Day 3.1 - first, bad attempt
This commit is contained in:
213
03/src/main.zig
Normal file
213
03/src/main.zig
Normal file
@@ -0,0 +1,213 @@
|
||||
const std = @import("std");
|
||||
|
||||
const max = 512;
|
||||
const xOrigin = max / 2;
|
||||
const yOrigin = max / 2;
|
||||
|
||||
const Error = error{ParseError};
|
||||
|
||||
const State = enum(u8) {
|
||||
Empty,
|
||||
Origin,
|
||||
Line,
|
||||
Intersect,
|
||||
};
|
||||
|
||||
const Direction = enum(u8) {
|
||||
Up = 'U',
|
||||
Right = 'R',
|
||||
Down = 'D',
|
||||
Left = 'L',
|
||||
|
||||
pub fn parse(in: u8) anyerror!Direction {
|
||||
return switch (in) {
|
||||
'U' => .Up,
|
||||
'R' => .Right,
|
||||
'D' => .Down,
|
||||
'L' => .Left,
|
||||
else => Error.ParseError,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const Grid = [max][max]State;
|
||||
|
||||
const Step = struct {
|
||||
d: Direction,
|
||||
l: u32,
|
||||
|
||||
pub fn parse(in: []const u8) anyerror!Step {
|
||||
if (in.len < 2) {
|
||||
return error.ParseError;
|
||||
}
|
||||
|
||||
return Step{
|
||||
.d = try Direction.parse(in[0]),
|
||||
.l = try std.fmt.parseInt(u32, in[1..in.len], 10),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const World = struct {
|
||||
x: u32,
|
||||
y: u32,
|
||||
grid: *Grid,
|
||||
|
||||
pub fn init(self: *World) void {
|
||||
for (self.grid) |y, y_offset| {
|
||||
for (y) |x, x_offset| {
|
||||
self.grid[y_offset][x_offset] = State.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display(self: *World) void {
|
||||
for (self.grid) |y, y_offset| {
|
||||
for (y) |x, x_offset| {
|
||||
var chr = switch (x) {
|
||||
State.Empty => " ",
|
||||
State.Line => ".",
|
||||
State.Origin => "o",
|
||||
State.Intersect => "*",
|
||||
};
|
||||
|
||||
std.debug.warn("{}", chr);
|
||||
}
|
||||
std.debug.warn("\n");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn step(self: *World, in: Step, compare: *Grid) void {
|
||||
std.debug.warn("Step: {}\n", in);
|
||||
|
||||
switch (in.d) {
|
||||
.Up => {
|
||||
self.lineY(self.y - in.l, self.y - 1, compare);
|
||||
self.y -= in.l;
|
||||
},
|
||||
.Down => {
|
||||
self.lineY(self.y + 1, self.y + in.l, compare);
|
||||
self.y += in.l;
|
||||
},
|
||||
.Left => {
|
||||
self.lineX(self.x - in.l, self.x - 1, compare);
|
||||
self.x -= in.l;
|
||||
},
|
||||
.Right => {
|
||||
self.lineX(self.x + 1, self.x + in.l, compare);
|
||||
self.x += in.l;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn lineX(self: *World, start: u32, end: u32, compare: *Grid) void {
|
||||
var x: u32 = start;
|
||||
while (x <= end) : (x += 1) {
|
||||
self.fill(x, self.y, compare);
|
||||
}
|
||||
}
|
||||
|
||||
fn lineY(self: *World, start: u32, end: u32, compare: *Grid) void {
|
||||
var y: u32 = start;
|
||||
while (y <= end) : (y += 1) {
|
||||
self.fill(self.x, y, compare);
|
||||
}
|
||||
}
|
||||
|
||||
fn fill(self: *World, x: u32, y: u32, compare: *Grid) void {
|
||||
std.debug.warn("\tFilling {},{}\n", x, y);
|
||||
|
||||
var newVal: State = switch (compare[y][x]) {
|
||||
.Line => .Intersect,
|
||||
else => .Line,
|
||||
};
|
||||
|
||||
self.grid[y][x] = newVal;
|
||||
}
|
||||
};
|
||||
|
||||
fn getLine(stream: *std.fs.File.InStream.Stream) anyerror![]Step {
|
||||
var buf: [10240]u8 = undefined;
|
||||
var out: [1000]Step = undefined;
|
||||
var i: u32 = 0;
|
||||
|
||||
var line = (try stream.readUntilDelimiterOrEof(&buf, '\n')) orelse return Error.ParseError;
|
||||
var iter = std.mem.separate(line, ",");
|
||||
|
||||
while (iter.next()) |value| {
|
||||
std.debug.assert(i < out.len);
|
||||
|
||||
out[i] = try Step.parse(value);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
return out[0..i];
|
||||
}
|
||||
|
||||
fn manhattan(x: i32, y: i32) u32 {
|
||||
return std.math.absCast(x - xOrigin) + std.math.absCast(y - yOrigin);
|
||||
}
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const alloc = &arena.allocator;
|
||||
const file = std.io.getStdIn();
|
||||
const stream = &file.inStream().stream;
|
||||
|
||||
var grid = try alloc.create(Grid);
|
||||
|
||||
var world: World = World{
|
||||
.x = xOrigin,
|
||||
.y = yOrigin,
|
||||
.grid = grid,
|
||||
};
|
||||
|
||||
world.init();
|
||||
var compare = std.mem.dupe(alloc, Grid, grid);
|
||||
|
||||
// Line 1
|
||||
for (try getLine(stream)) |item| {
|
||||
world.step(item, compare);
|
||||
}
|
||||
|
||||
// reset to origin
|
||||
//std.mem.copy(compare, world.grid);
|
||||
world.x = xOrigin;
|
||||
world.y = yOrigin;
|
||||
|
||||
// Line 2
|
||||
for (try getLine(stream)) |item| {
|
||||
world.step(item, compare);
|
||||
}
|
||||
|
||||
// Ignore the origin
|
||||
world.grid[yOrigin][xOrigin] = State.Origin;
|
||||
|
||||
// detect collisions
|
||||
var minMH: u32 = undefined;
|
||||
var found: bool = false;
|
||||
for (world.grid) |y, yOff| {
|
||||
for (y) |x, xOff| {
|
||||
if (x == State.Intersect) {
|
||||
const mh = manhattan(@intCast(i32, xOff), @intCast(i32, yOff));
|
||||
std.debug.warn("Intersect! {},{} : {}\n", xOff, yOff, mh);
|
||||
if (found) {
|
||||
if (minMH > mh) {
|
||||
minMH = mh;
|
||||
}
|
||||
} else {
|
||||
found = true;
|
||||
minMH = mh;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
std.debug.warn("Smallest manhattan: {}\n", minMH);
|
||||
}
|
||||
|
||||
// world.display();
|
||||
}
|
Reference in New Issue
Block a user