diff options
author | Mathias Magnusson <mathias@magnusson.space> | 2024-12-06 22:27:16 +0100 |
---|---|---|
committer | Mathias Magnusson <mathias@magnusson.space> | 2024-12-06 22:27:16 +0100 |
commit | 1c085ae9e52cdd3309967492c9a8316218cf7b4d (patch) | |
tree | d665eb643b8e421fa39bb0db20d21795a70c570b /aoc24/src/day6.zig | |
parent | bda1c5c94a5002fb16c5b2d739adba32147cf920 (diff) | |
download | programming-problem-solving-1c085ae9e52cdd3309967492c9a8316218cf7b4d.tar.gz |
aoc2024: day 6 part 1
Diffstat (limited to 'aoc24/src/day6.zig')
-rw-r--r-- | aoc24/src/day6.zig | 136 |
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; +} |