Day 2.1, horrible but working
This commit is contained in:
146
03/src/main.zig
146
03/src/main.zig
@@ -1,18 +1,14 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const max = 512;
|
|
||||||
const xOrigin = max / 2;
|
|
||||||
const yOrigin = max / 2;
|
|
||||||
|
|
||||||
const Error = error{ParseError};
|
const Error = error{ParseError};
|
||||||
|
|
||||||
const State = enum(u8) {
|
const Point = struct {
|
||||||
Empty,
|
X: i32,
|
||||||
Origin,
|
Y: i32,
|
||||||
Line,
|
|
||||||
Intersect,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Points = std.ArrayList(Point);
|
||||||
|
|
||||||
const Direction = enum(u8) {
|
const Direction = enum(u8) {
|
||||||
Up = 'U',
|
Up = 'U',
|
||||||
Right = 'R',
|
Right = 'R',
|
||||||
@@ -30,11 +26,9 @@ const Direction = enum(u8) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Grid = [max][max]State;
|
|
||||||
|
|
||||||
const Step = struct {
|
const Step = struct {
|
||||||
d: Direction,
|
d: Direction,
|
||||||
l: u32,
|
l: i32,
|
||||||
|
|
||||||
pub fn parse(in: []const u8) anyerror!Step {
|
pub fn parse(in: []const u8) anyerror!Step {
|
||||||
if (in.len < 2) {
|
if (in.len < 2) {
|
||||||
@@ -43,86 +37,55 @@ const Step = struct {
|
|||||||
|
|
||||||
return Step{
|
return Step{
|
||||||
.d = try Direction.parse(in[0]),
|
.d = try Direction.parse(in[0]),
|
||||||
.l = try std.fmt.parseInt(u32, in[1..in.len], 10),
|
.l = try std.fmt.parseInt(i32, in[1..in.len], 10),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const World = struct {
|
const World = struct {
|
||||||
x: u32,
|
entries: Points,
|
||||||
y: u32,
|
pos: Point,
|
||||||
grid: *Grid,
|
|
||||||
|
|
||||||
pub fn init(self: *World) void {
|
pub fn step(self: *World, in: Step) anyerror!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);
|
std.debug.warn("Step: {}\n", in);
|
||||||
|
|
||||||
switch (in.d) {
|
switch (in.d) {
|
||||||
.Up => {
|
.Up => {
|
||||||
self.lineY(self.y - in.l, self.y - 1, compare);
|
try self.lineY(self.pos.Y - in.l, self.pos.Y - 1);
|
||||||
self.y -= in.l;
|
self.pos.Y -= in.l;
|
||||||
},
|
},
|
||||||
.Down => {
|
.Down => {
|
||||||
self.lineY(self.y + 1, self.y + in.l, compare);
|
try self.lineY(self.pos.Y + 1, self.pos.Y + in.l);
|
||||||
self.y += in.l;
|
self.pos.Y += in.l;
|
||||||
},
|
},
|
||||||
.Left => {
|
.Left => {
|
||||||
self.lineX(self.x - in.l, self.x - 1, compare);
|
try self.lineX(self.pos.X - in.l, self.pos.X - 1);
|
||||||
self.x -= in.l;
|
self.pos.X -= in.l;
|
||||||
},
|
},
|
||||||
.Right => {
|
.Right => {
|
||||||
self.lineX(self.x + 1, self.x + in.l, compare);
|
try self.lineX(self.pos.X + 1, self.pos.X + in.l);
|
||||||
self.x += in.l;
|
self.pos.X += in.l;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lineX(self: *World, start: u32, end: u32, compare: *Grid) void {
|
fn lineX(self: *World, start: i32, end: i32) anyerror!void {
|
||||||
var x: u32 = start;
|
var x: i32 = start;
|
||||||
while (x <= end) : (x += 1) {
|
while (x <= end) : (x += 1) {
|
||||||
self.fill(x, self.y, compare);
|
try self.fill(x, self.pos.Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lineY(self: *World, start: u32, end: u32, compare: *Grid) void {
|
fn lineY(self: *World, start: i32, end: i32) anyerror!void {
|
||||||
var y: u32 = start;
|
var y: i32 = start;
|
||||||
while (y <= end) : (y += 1) {
|
while (y <= end) : (y += 1) {
|
||||||
self.fill(self.x, y, compare);
|
try self.fill(self.pos.X, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill(self: *World, x: u32, y: u32, compare: *Grid) void {
|
fn fill(self: *World, x: i32, y: i32) anyerror!void {
|
||||||
std.debug.warn("\tFilling {},{}\n", x, y);
|
//self.entries = try self.alloc.realloc(self.entries, self.entries.len+1);
|
||||||
|
self.entries.appendAssumeCapacity(Point{ .X = x, .Y = y });
|
||||||
var newVal: State = switch (compare[y][x]) {
|
|
||||||
.Line => .Intersect,
|
|
||||||
else => .Line,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.grid[y][x] = newVal;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -145,9 +108,11 @@ fn getLine(stream: *std.fs.File.InStream.Stream) anyerror![]Step {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn manhattan(x: i32, y: i32) u32 {
|
fn manhattan(x: i32, y: i32) u32 {
|
||||||
return std.math.absCast(x - xOrigin) + std.math.absCast(y - yOrigin);
|
return std.math.absCast(x) + std.math.absCast(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const maxEntries = 1024 * 1024;
|
||||||
|
|
||||||
pub fn main() anyerror!void {
|
pub fn main() anyerror!void {
|
||||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
@@ -156,58 +121,35 @@ pub fn main() anyerror!void {
|
|||||||
const file = std.io.getStdIn();
|
const file = std.io.getStdIn();
|
||||||
const stream = &file.inStream().stream;
|
const stream = &file.inStream().stream;
|
||||||
|
|
||||||
var grid = try alloc.create(Grid);
|
|
||||||
|
|
||||||
var world: World = World{
|
var world: World = World{
|
||||||
.x = xOrigin,
|
.entries = try Points.initCapacity(alloc, maxEntries),
|
||||||
.y = yOrigin,
|
.pos = Point{ .X = 0, .Y = 0 },
|
||||||
.grid = grid,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
world.init();
|
|
||||||
var compare = std.mem.dupe(alloc, Grid, grid);
|
|
||||||
|
|
||||||
// Line 1
|
// Line 1
|
||||||
for (try getLine(stream)) |item| {
|
for (try getLine(stream)) |item| {
|
||||||
world.step(item, compare);
|
try world.step(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset to origin
|
// reset to origin
|
||||||
//std.mem.copy(compare, world.grid);
|
const entriesA = world.entries;
|
||||||
world.x = xOrigin;
|
world.entries = try Points.initCapacity(alloc, maxEntries);
|
||||||
world.y = yOrigin;
|
world.pos = Point{ .X = 0, .Y = 0 };
|
||||||
|
|
||||||
// Line 2
|
// Line 2
|
||||||
for (try getLine(stream)) |item| {
|
for (try getLine(stream)) |item| {
|
||||||
world.step(item, compare);
|
try world.step(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore the origin
|
const entriesB = world.entries;
|
||||||
world.grid[yOrigin][xOrigin] = State.Origin;
|
|
||||||
|
|
||||||
// detect collisions
|
std.debug.warn("A: {} entries\nB: {} entries\n", entriesA.len, entriesB.len);
|
||||||
var minMH: u32 = undefined;
|
|
||||||
var found: bool = false;
|
for (entriesA.toSlice()) |a| {
|
||||||
for (world.grid) |y, yOff| {
|
for (entriesB.toSlice()) |b| {
|
||||||
for (y) |x, xOff| {
|
if (a.X == b.X and a.Y == b.Y) {
|
||||||
if (x == State.Intersect) {
|
std.debug.warn("Match! {} => {}\n", a, manhattan(a.X, a.Y));
|
||||||
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