summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Magnusson <mathias@magnusson.space>2024-12-06 22:27:16 +0100
committerMathias Magnusson <mathias@magnusson.space>2024-12-06 22:27:16 +0100
commit1c085ae9e52cdd3309967492c9a8316218cf7b4d (patch)
treed665eb643b8e421fa39bb0db20d21795a70c570b
parentbda1c5c94a5002fb16c5b2d739adba32147cf920 (diff)
downloadprogramming-problem-solving-1c085ae9e52cdd3309967492c9a8316218cf7b4d.tar.gz
aoc2024: day 6 part 1
-rw-r--r--aoc24/src/day6.zig136
1 files changed, 136 insertions, 0 deletions
diff --git a/aoc24/src/day6.zig b/aoc24/src/day6.zig
new file mode 100644
index 0000000..c52b0ff
--- /dev/null
+++ b/aoc24/src/day6.zig
@@ -0,0 +1,136 @@
+const std = @import("std");
+
+const Pos = @Vector(2, usize);
+
+const Dir = enum {
+ right,
+ up,
+ left,
+ down,
+
+ fn rotate(self: @This()) @This() {
+ return switch (self) {
+ .right => .down,
+ .up => .right,
+ .left => .up,
+ .down => .left,
+ };
+ }
+};
+
+const Input = struct {
+ map: std.AutoHashMap(Pos, void),
+ size: Pos,
+ start_pos: Pos,
+ start_dir: Dir,
+
+ const Self = @This();
+
+ fn step_forwards(pos: Pos, dir: Dir) ?Pos {
+ return switch (dir) {
+ .right => .{ std.math.add(usize, pos[0], 1) catch return null, pos[1] },
+ .up => .{ pos[0], std.math.sub(usize, pos[1], 1) catch return null },
+ .left => .{ std.math.sub(usize, pos[0], 1) catch return null, pos[1] },
+ .down => .{ pos[0], std.math.add(usize, pos[1], 1) catch return null },
+ };
+ }
+
+ fn step(self: Self, pos: Pos, dir: Dir) ?struct { Pos, Dir } {
+ var new_pos = Self.step_forwards(pos, dir) orelse return null;
+ var new_dir = dir;
+ while (self.map.contains(new_pos)) {
+ new_dir = new_dir.rotate();
+ new_pos = Self.step_forwards(pos, new_dir) orelse return null;
+ }
+ return .{ new_pos, new_dir };
+ }
+};
+
+pub fn parse(allocator: std.mem.Allocator, data: []const u8) !Input {
+ var lines = std.mem.split(u8, data, "\n");
+ var input = Input{ .map = std.AutoHashMap(Pos, void).init(allocator), .size = undefined, .start_pos = undefined, .start_dir = undefined };
+ var y: usize = 0;
+ while (lines.next()) |line| : (y += 1) {
+ if (line.len == 0) input.size[1] = y else input.size[0] = line.len;
+ for (0.., line) |x, c| {
+ if (c == '#') {
+ try input.map.put(.{ x, y }, {});
+ } else if (c == '>') {
+ input.start_pos = .{ x, y };
+ input.start_dir = .right;
+ } else if (c == '^') {
+ input.start_pos = .{ x, y };
+ input.start_dir = .up;
+ } else if (c == '<') {
+ input.start_pos = .{ x, y };
+ input.start_dir = .left;
+ } else if (c == 'v') {
+ input.start_pos = .{ x, y };
+ input.start_dir = .down;
+ }
+ }
+ }
+ return input;
+}
+
+fn printAndWait(input: Input, traversed: std.AutoHashMap(Pos, void)) !void {
+ var underlying_buffer: [100000]u8 = undefined;
+ var buffer = std.io.fixedBufferStream(&underlying_buffer);
+ var writer = buffer.writer();
+ for (0..input.size[1]) |y| {
+ for (0..input.size[0]) |x| {
+ try writer.print("{c}", .{
+ if (traversed.contains(.{ x, y })) 'X' else if (input.map.contains(.{ x, y })) @as(u8, '#') else '.',
+ });
+ }
+ try writer.print("\n", .{});
+ }
+ std.debug.print("{s}\n", .{underlying_buffer[0..try buffer.getPos()]});
+ try std.io.getStdIn().reader().skipUntilDelimiterOrEof('\n');
+}
+
+const test_input =
+ \\....#.....
+ \\.........#
+ \\..........
+ \\..#.......
+ \\.......#..
+ \\..........
+ \\.#..^.....
+ \\........#.
+ \\#.........
+ \\......#...
+ \\
+;
+
+test "part1" {
+ var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
+ defer arena.deinit();
+
+ const output = try part1(arena.allocator(), try parse(arena.allocator(), test_input));
+ std.debug.print("got {}\n", .{output});
+ std.debug.assert(output == 41);
+}
+
+pub fn part1(allocator: std.mem.Allocator, input: Input) !u32 {
+ var pos = input.start_pos;
+ var dir = input.start_dir;
+ var traversed = std.AutoHashMap(Pos, void).init(allocator);
+ return while (true) {
+ try traversed.put(pos, {});
+ const new = input.step(pos, dir);
+ if (new) |n| {
+ pos = n[0];
+ dir = n[1];
+ // const try printAndWait(input, traversed);
+ } else {
+ break traversed.count();
+ }
+ };
+}
+
+pub fn part2(allocator: std.mem.Allocator, input: Input) !u32 {
+ _ = allocator;
+ _ = input;
+ return 0;
+}