diff options
author | Mathias Magnusson <mathias@magnusson.space> | 2024-12-08 16:36:58 +0100 |
---|---|---|
committer | Mathias Magnusson <mathias@magnusson.space> | 2024-12-08 16:36:58 +0100 |
commit | f8cc65a1ae6e6587e316757c7eb0d7d56624cdb0 (patch) | |
tree | c3b52ae6812a0923e6cff490db702122f92a309f /aoc24/src | |
parent | f3d2506b162f5d4c432e393ee9c24cca566cbc80 (diff) | |
download | programming-problem-solving-f8cc65a1ae6e6587e316757c7eb0d7d56624cdb0.tar.gz |
aoc2024: day 8
Diffstat (limited to 'aoc24/src')
-rw-r--r-- | aoc24/src/day8.zig | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/aoc24/src/day8.zig b/aoc24/src/day8.zig new file mode 100644 index 0000000..2d90fd6 --- /dev/null +++ b/aoc24/src/day8.zig @@ -0,0 +1,103 @@ +const std = @import("std"); + +const Pos = @Vector(2, isize); + +const Input = struct { + width: usize, + height: usize, + antenna_locations: std.AutoHashMap(u8, std.ArrayList(Pos)), +}; + +pub fn parse(allocator: std.mem.Allocator, data: []const u8) !Input { + var lines = std.mem.split(u8, data, "\n"); + var width: usize = undefined; + var y: usize = 0; + var antenna_locations = std.AutoHashMap(u8, std.ArrayList(Pos)).init(allocator); + while (lines.next()) |line| : (y += 1) { + if (line.len == 0) break; + for (0.., line) |x, c| { + switch (c) { + '0'...'9', 'a'...'z', 'A'...'Z' => { + const res = try antenna_locations.getOrPut(c); + if (!res.found_existing) + res.value_ptr.* = std.ArrayList(Pos).init(allocator); + try res.value_ptr.*.append(.{ @intCast(x), @intCast(y) }); + }, + else => {}, + } + } + width = line.len; + } + return .{ + .width = width, + .height = y, + .antenna_locations = antenna_locations, + }; +} + +const test_input = + \\............ + \\........0... + \\.....0...... + \\.......0.... + \\....0....... + \\......A..... + \\............ + \\............ + \\........A... + \\.........A.. + \\............ + \\............ + \\ +; + +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 == 14); +} + +pub fn part1(allocator: std.mem.Allocator, input: Input) !u32 { + var it = input.antenna_locations.valueIterator(); + var antinodes = std.AutoHashMap(Pos, void).init(allocator); + while (it.next()) |locations| { + for (locations.items) |a| for (locations.items) |b| { + if (@reduce(.And, a == b)) continue; + const pos = b + b - a; + if (pos[0] < 0 or input.width <= pos[0] or + pos[1] < 0 or input.height <= pos[1]) continue; + try antinodes.put(pos, {}); + }; + } + return antinodes.count(); +} + +test "part2" { + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + + const output = try part2(arena.allocator(), try parse(arena.allocator(), test_input)); + std.debug.print("got {}\n", .{output}); + std.debug.assert(output == 34); +} + +pub fn part2(allocator: std.mem.Allocator, input: Input) !u32 { + var it = input.antenna_locations.valueIterator(); + var antinodes = std.AutoHashMap(Pos, void).init(allocator); + while (it.next()) |locations| { + for (locations.items) |a| for (locations.items) |b| { + if (@reduce(.And, a == b)) continue; + const delta = b - a; + var pos = b; + while (0 <= pos[0] and pos[0] < input.width and + 0 <= pos[1] and pos[1] < input.height) : (pos += delta) + { + try antinodes.put(pos, {}); + } + }; + } + return antinodes.count(); +} |