From 7f35208133d37b08259a7e205de36522ff837775 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Sat, 07 Dec 2024 21:26:25 +0000 Subject: [PATCH] Add 2024 day 6 --- README | 4 ++-- 2024/06.zig | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/README b/README index 05114d6..10906c9 100644 --- a/README +++ a/README @@ -19,8 +19,8 @@ | 3 | Perl | | 3 | Haskell | | 3 | Clojure | | 4 | Rust | | 4 | Haskell | | 4 | Jsonnet | | 5 | PHP | | 5 | Rust | | 5 | HCL/TF | -+---------------------+ | 6 | Haskell | | 6 | Apache2 | - | 7 | Haskell | +---------------------+ +| 6 | Zig | | 6 | Haskell | | 6 | Apache2 | ++---------------------+ | 7 | Haskell | +---------------------+ | 8 | Haskell | | 9 | Haskell | | 10 | Haskell | diff --git a/2024/06.zig b/2024/06.zig new file mode 100644 index 0000000..fe35b3d 100644 --- /dev/null +++ a/2024/06.zig @@ -1,0 +1,122 @@ +const std = @import("std"); + +const Vec = struct { + x: usize, + y: usize, +}; + +const Direction = enum { + Up, + Down, + Left, + Right, + + fn turn(self: Direction) Direction { + return switch (self) { + .Up => .Right, + .Right => .Down, + .Down => .Left, + .Left => .Up, + }; + } + + fn step(self: Direction, player: *Vec) void { + switch (self) { + .Up => player.y -= 1, + .Right => player.x += 1, + .Down => player.y += 1, + .Left => player.x -= 1, + } + } + + fn stepBack(self: Direction, player: *Vec) void { + switch (self) { + .Up => player.y += 1, + .Right => player.x -= 1, + .Down => player.y -= 1, + .Left => player.x += 1, + } + } +}; + +pub fn main() !void { + const in = std.io.getStdIn().reader(); + + var msg_buf: [200]u8 = undefined; + + var blocks = std.ArrayList(Vec).init(std.heap.page_allocator); + var player = Vec{ .x = 0, .y = 0 }; + var gridBounds = Vec{ .x = 0, .y = 0 }; + + var y: usize = 0; + while (try in.readUntilDelimiterOrEof(&msg_buf, '\n')) |line| : (y += 1) { + for (line, 0..) |char, x| { + gridBounds = Vec{ .x = x, .y = y }; + + switch (char) { + '#' => try blocks.append(.{ .x = x, .y = y }), + '^' => player = .{ .x = x, .y = y }, + else => continue, + } + } + } + + var part1 = try findExitPath(player, gridBounds, blocks); + std.debug.print("{d}\n", .{part1.?.count()}); + + var part2: usize = 0; + var iter = part1.?.iterator(); + while (iter.next()) |data| { + if (data.key_ptr.y == player.y and data.key_ptr.x == player.x) { + continue; + } + + try blocks.append(.{ .x = data.key_ptr.x, .y = data.key_ptr.y }); + + if (try findExitPath(player, gridBounds, blocks) == null) { + part2 += 1; + } + + _ = blocks.pop(); + } + + std.debug.print("{d}", .{part2}); +} + +fn findExitPath(initialPlayer: Vec, gridBounds: Vec, blocks: std.ArrayList(Vec)) !?std.AutoHashMap(Vec, u32) { + var seenPositions = std.AutoHashMap(Vec, u32).init(std.heap.page_allocator); + var direction = Direction.Up; + var player = initialPlayer; + + while (player.x <= gridBounds.x and player.y <= gridBounds.y and player.x > 0 and player.y > 0) { + direction.step(&player); + + if (containsVec(blocks.items, player)) { + direction.stepBack(&player); + direction = direction.turn(); + } else { + const res = seenPositions.get(player); + if (res) |value| { + if (value == 100) { + // assume we're stuck in a loop + return null; + } + try seenPositions.put(player, value + 1); + } else { + try seenPositions.put(player, 1); + } + } + } + + return seenPositions; +} + +fn containsVec(items: []Vec, vec: Vec) bool { + for (items) |elem| { + if (elem.x == vec.x and elem.y == vec.y) { + return true; + } + } + + return false; +} -- rgit 0.1.5