From 2dcccc935c7d2fd4bbdd25993b939bbaf9a5e7de Mon Sep 17 00:00:00 2001 From: Jeremy Kaplan Date: Tue, 10 Dec 2024 22:07:17 -0800 Subject: [PATCH] 2024 Day 11 Part 2 --- 2024/src/day11.zig | 50 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/2024/src/day11.zig b/2024/src/day11.zig index 3f63131..8b38131 100644 --- a/2024/src/day11.zig +++ b/2024/src/day11.zig @@ -24,6 +24,9 @@ pub fn main() !void { try stdout.print("{d}\n", .{try part1(allocator, stones)}); try bw.flush(); + + try stdout.print("{d}\n", .{try part2(allocator, stones)}); + try bw.flush(); } fn part1(allocator: Allocator, start: Stones) !usize { @@ -37,6 +40,17 @@ fn part1(allocator: Allocator, start: Stones) !usize { return stones.list.items.len; } +fn part2(allocator: Allocator, stones: Stones) !u64 { + var memo = std.AutoHashMap(State, u64).init(allocator); + defer memo.deinit(); + + var total: u64 = 0; + for (stones.list.items) |start| { + total += try blinkMemo(&memo, start, 75); + } + return total; +} + const Stones = struct { list: ArrayList(u64), @@ -89,8 +103,8 @@ const Stones = struct { if (i == 0) { try next.append(1); } else if (split(i)) |parts| { - try next.append(parts.@"0"); - try next.append(parts.@"1"); + try next.append(parts[0]); + try next.append(parts[1]); } else { try next.append(i * 2024); } @@ -100,7 +114,37 @@ const Stones = struct { } }; -fn split(n: u64) ?struct { u64, u64 } { +const State = struct { + start: u64, + ticks: usize, +}; + +fn blinkMemo(memo: *std.AutoHashMap(State, u64), start: u64, ticks: usize) !u64 { + if (ticks == 0) { + return 1; + } + + const state = State{ .start = start, .ticks = ticks }; + if (memo.get(state)) |n| { + return n; + } + + var total: u64 = undefined; + if (start == 0) { + total = try blinkMemo(memo, 1, ticks - 1); + } else if (split(start)) |parts| { + const a = try blinkMemo(memo, parts[0], ticks - 1); + const b = try blinkMemo(memo, parts[1], ticks - 1); + total = a + b; + } else { + total = try blinkMemo(memo, start * 2024, ticks - 1); + } + + try memo.put(state, total); + return total; +} + +fn split(n: u64) ?[2]u64 { const digits = 1 + std.math.log10(n); if (digits % 2 == 0) { const x = std.math.pow(u64, 10, digits / 2);