2024 Day 11 Part 2
This commit is contained in:
parent
2bdf2c89c7
commit
2dcccc935c
1 changed files with 47 additions and 3 deletions
|
|
@ -24,6 +24,9 @@ pub fn main() !void {
|
||||||
|
|
||||||
try stdout.print("{d}\n", .{try part1(allocator, stones)});
|
try stdout.print("{d}\n", .{try part1(allocator, stones)});
|
||||||
try bw.flush();
|
try bw.flush();
|
||||||
|
|
||||||
|
try stdout.print("{d}\n", .{try part2(allocator, stones)});
|
||||||
|
try bw.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part1(allocator: Allocator, start: Stones) !usize {
|
fn part1(allocator: Allocator, start: Stones) !usize {
|
||||||
|
|
@ -37,6 +40,17 @@ fn part1(allocator: Allocator, start: Stones) !usize {
|
||||||
return stones.list.items.len;
|
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 {
|
const Stones = struct {
|
||||||
list: ArrayList(u64),
|
list: ArrayList(u64),
|
||||||
|
|
||||||
|
|
@ -89,8 +103,8 @@ const Stones = struct {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
try next.append(1);
|
try next.append(1);
|
||||||
} else if (split(i)) |parts| {
|
} else if (split(i)) |parts| {
|
||||||
try next.append(parts.@"0");
|
try next.append(parts[0]);
|
||||||
try next.append(parts.@"1");
|
try next.append(parts[1]);
|
||||||
} else {
|
} else {
|
||||||
try next.append(i * 2024);
|
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);
|
const digits = 1 + std.math.log10(n);
|
||||||
if (digits % 2 == 0) {
|
if (digits % 2 == 0) {
|
||||||
const x = std.math.pow(u64, 10, digits / 2);
|
const x = std.math.pow(u64, 10, digits / 2);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue