diff options
Diffstat (limited to 'aoc24/src')
-rw-r--r-- | aoc24/src/day1.zig | 70 | ||||
-rw-r--r-- | aoc24/src/day1p1.zig | 49 | ||||
-rw-r--r-- | aoc24/src/day1p2.zig | 51 | ||||
-rw-r--r-- | aoc24/src/day2.zig (renamed from aoc24/src/day2p2.zig) | 68 | ||||
-rw-r--r-- | aoc24/src/day2p1.zig | 54 |
5 files changed, 125 insertions, 167 deletions
diff --git a/aoc24/src/day1.zig b/aoc24/src/day1.zig new file mode 100644 index 0000000..1f26943 --- /dev/null +++ b/aoc24/src/day1.zig @@ -0,0 +1,70 @@ +const std = @import("std"); + +test { + std.debug.assert(try part1( + \\3 4 + \\4 3 + \\2 5 + \\1 3 + \\3 9 + \\3 3 + ) == 11); +} + +const Input = struct { + lefts: std.ArrayList(u32), + rights: std.ArrayList(u32), +}; + +pub fn parse(allocator: std.mem.Allocator, input: []const u8) !Input { + var lines = std.mem.split(u8, input, "\n"); + + var lefts = std.ArrayList(u32).init(allocator); + // defer lefts.deinit(); + var rights = std.ArrayList(u32).init(allocator); + // defer rights.deinit(); + + while (lines.next()) |line| { + if (line.len == 0) continue; + var words = std.mem.split(u8, line, " "); + const left = try std.fmt.parseInt(u32, words.next() orelse return error.InvalidInput, 10); + const right = try std.fmt.parseInt(u32, words.next() orelse return error.InvalidInput, 10); + try lefts.append(left); + try rights.append(right); + } + + return .{ .lefts = lefts, .rights = rights }; +} + +pub fn part1(_: std.mem.Allocator, input: Input) !u32 { + std.mem.sort(u32, input.lefts.items, {}, std.sort.asc(u32)); + std.mem.sort(u32, input.rights.items, {}, std.sort.asc(u32)); + + var sum: u32 = 0; + for (input.lefts.items, input.rights.items) |l, r| { + sum += @max(l, r) - @min(l, r); + } + + return sum; +} + +pub fn part2(allocator: std.mem.Allocator, input: Input) !u32 { + var right_counts = std.AutoHashMap(u32, u16).init(allocator); + defer right_counts.deinit(); + + for (input.rights.items) |right| { + const entry = try right_counts.getOrPut(right); + if (entry.found_existing) + entry.value_ptr.* += 1 + else + entry.value_ptr.* = 1; + } + + var sum: u32 = 0; + for (input.lefts.items) |x| { + const count: u32 = @intCast(right_counts.get(x) orelse 0); + sum += x * count; + } + + return sum; +} diff --git a/aoc24/src/day1p1.zig b/aoc24/src/day1p1.zig deleted file mode 100644 index fba4b8c..0000000 --- a/aoc24/src/day1p1.zig +++ /dev/null @@ -1,49 +0,0 @@ -const std = @import("std"); - -pub fn main() !void { - const input = @embedFile("1.txt"); - try std.fmt.format(std.io.getStdOut().writer(), "{}\n", .{try run(input)}); -} - -test { - std.debug.assert(try run( - \\3 4 - \\4 3 - \\2 5 - \\1 3 - \\3 9 - \\3 3 - ) == 11); -} - -pub fn run(input: []const u8) !u32 { - var lines = std.mem.split(u8, input, "\n"); - - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); - - var lefts = std.ArrayList(u32).init(allocator); - defer lefts.deinit(); - var rights = std.ArrayList(u32).init(allocator); - defer rights.deinit(); - - while (lines.next()) |line| { - if (line.len == 0) continue; - var words = std.mem.split(u8, line, " "); - const left = try std.fmt.parseInt(u32, words.next() orelse return error.InvalidInput, 10); - const right = try std.fmt.parseInt(u32, words.next() orelse return error.InvalidInput, 10); - try lefts.append(left); - try rights.append(right); - } - - std.mem.sort(u32, lefts.items, {}, std.sort.asc(u32)); - std.mem.sort(u32, rights.items, {}, std.sort.asc(u32)); - - var sum: u32 = 0; - for (lefts.items, rights.items) |l, r| { - sum += @max(l, r) - @min(l, r); - } - - return sum; -} diff --git a/aoc24/src/day1p2.zig b/aoc24/src/day1p2.zig deleted file mode 100644 index 91b99fa..0000000 --- a/aoc24/src/day1p2.zig +++ /dev/null @@ -1,51 +0,0 @@ -const std = @import("std"); - -pub fn main() !void { - const input = @embedFile("1.txt"); - try std.fmt.format(std.io.getStdOut().writer(), "{}\n", .{try run(input)}); -} - -test { - std.debug.assert(try run( - \\3 4 - \\4 3 - \\2 5 - \\1 3 - \\3 9 - \\3 3 - ) == 31); -} - -pub fn run(input: []const u8) !u32 { - var lines = std.mem.split(u8, input, "\n"); - - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); - - var lefts = std.ArrayList(u32).init(allocator); - defer lefts.deinit(); - var rights = std.AutoHashMap(u32, u16).init(allocator); - defer rights.deinit(); - - while (lines.next()) |line| { - if (line.len == 0) continue; - var words = std.mem.split(u8, line, " "); - const left = try std.fmt.parseInt(u32, words.next() orelse return error.InvalidInput, 10); - const right = try std.fmt.parseInt(u32, words.next() orelse return error.InvalidInput, 10); - try lefts.append(left); - const entry = try rights.getOrPut(right); - if (entry.found_existing) - entry.value_ptr.* += 1 - else - entry.value_ptr.* = 1; - } - - var sum: u32 = 0; - for (lefts.items) |x| { - const count: u32 = @intCast(rights.get(x) orelse 0); - sum += x * count; - } - - return sum; -} diff --git a/aoc24/src/day2p2.zig b/aoc24/src/day2.zig index fd2f7a3..656fd41 100644 --- a/aoc24/src/day2p2.zig +++ b/aoc24/src/day2.zig @@ -1,12 +1,28 @@ const std = @import("std"); -pub fn main() !void { - const input = @embedFile("2.txt"); - try std.fmt.format(std.io.getStdOut().writer(), "{}\n", .{try run(input)}); +test "part 1" { + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const allocator = arena.allocator(); + const input = try parse(allocator, + \\7 6 4 2 1 + \\1 2 7 8 9 + \\9 7 6 2 1 + \\1 3 2 4 5 + \\8 6 4 4 1 + \\1 3 6 7 9 + ); + const value = try part1(allocator, input); + const ok = value == 2; + if (!ok) std.debug.print("got {}\n", .{value}); + std.debug.assert(ok); } -test { - const value = try run( +test "part 2" { + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const allocator = arena.allocator(); + const input = try parse(allocator, \\7 6 4 2 1 \\1 2 7 8 9 \\9 7 6 2 1 @@ -14,19 +30,19 @@ test { \\8 6 4 4 1 \\1 3 6 7 9 ); - std.debug.print("got {}\n", .{value}); - std.debug.assert(value == 4); + const value = try part2(allocator, input); + const ok = value == 4; + if (!ok) std.debug.print("got {}\n", .{value}); + std.debug.assert(ok); } -pub fn run(input: []const u8) !u32 { +pub fn parse( + allocator: std.mem.Allocator, + input: []const u8, +) !std.ArrayList(std.ArrayList(u32)) { var lines = std.mem.split(u8, input, "\n"); - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); - var reports = std.ArrayList(std.ArrayList(u32)).init(allocator); - defer reports.deinit(); while (lines.next()) |line| { if (line.len == 0) continue; @@ -38,6 +54,32 @@ pub fn run(input: []const u8) !u32 { try reports.append(report); } + return reports; +} + +pub fn part1( + _: std.mem.Allocator, + reports: std.ArrayList(std.ArrayList(u32)), +) !u32 { + var safe: u32 = 0; + for (reports.items) |report| { + const increasing = report.items[0] < report.items[1]; + for (report.items[0 .. report.items.len - 1], report.items[1..]) |prev, curr| { + if ((prev < curr) != increasing) break; + if (prev == curr) break; + if (@max(prev, curr) - @min(prev, curr) > 3) break; + } else { + safe += 1; + } + } + + return safe; +} + +pub fn part2( + _: std.mem.Allocator, + reports: std.ArrayList(std.ArrayList(u32)), +) !u32 { var safe: u32 = 0; for (reports.items) |report| { var is_safe = false; diff --git a/aoc24/src/day2p1.zig b/aoc24/src/day2p1.zig deleted file mode 100644 index f5263be..0000000 --- a/aoc24/src/day2p1.zig +++ /dev/null @@ -1,54 +0,0 @@ -const std = @import("std"); - -pub fn main() !void { - const input = @embedFile("2.txt"); - try std.fmt.format(std.io.getStdOut().writer(), "{}\n", .{try run(input)}); -} - -test { - const value = try run( - \\7 6 4 2 1 - \\1 2 7 8 9 - \\9 7 6 2 1 - \\1 3 2 4 5 - \\8 6 4 4 1 - \\1 3 6 7 9 - ); - std.debug.print("got {}\n", .{value}); - std.debug.assert(value == 2); -} - -pub fn run(input: []const u8) !u32 { - var lines = std.mem.split(u8, input, "\n"); - - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); - - var reports = std.ArrayList(std.ArrayList(u32)).init(allocator); - defer reports.deinit(); - - while (lines.next()) |line| { - if (line.len == 0) continue; - var report = std.ArrayList(u32).init(allocator); - var words = std.mem.split(u8, line, " "); - while (words.next()) |word| { - try report.append(try std.fmt.parseInt(u32, word, 10)); - } - try reports.append(report); - } - - var safe: u32 = 0; - for (reports.items) |report| { - const increasing = report.items[0] < report.items[1]; - for (report.items[0 .. report.items.len - 1], report.items[1..]) |prev, curr| { - if ((prev < curr) != increasing) break; - if (prev == curr) break; - if (@max(prev, curr) - @min(prev, curr) > 3) break; - } else { - safe += 1; - } - } - - return safe; -} |