day 11 done

This commit is contained in:
Moritz Gmeiner 2024-12-11 22:22:04 +01:00
commit d06f8527ff
13 changed files with 211 additions and 34 deletions

View file

@ -2,7 +2,9 @@ const std = @import("std");
const utils = @import("lib/utils.zig");
const filename = "inputs/day1.txt";
const day = "1";
const filename = "inputs/day" ++ day ++ ".txt";
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -14,7 +16,7 @@ pub fn main() !void {
const result = try part1(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 1, part 1: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 1: {}\n", .{result});
}
{
@ -23,7 +25,7 @@ pub fn main() !void {
const result = try part2(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 1, part 1: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 2: {}\n", .{result});
}
}

View file

@ -4,7 +4,9 @@ const utils = @import("lib/utils.zig");
const spice = @import("lib/spice.zig");
const filename = "inputs/day10.txt";
const day = "10";
const filename = "inputs/day" ++ day ++ ".txt";
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -16,7 +18,7 @@ pub fn main() !void {
const result = try part1(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 10, part 1: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 1: {}\n", .{result});
}
{
@ -25,7 +27,7 @@ pub fn main() !void {
const result = try part2(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 10, part 2: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 2: {}\n", .{result});
}
}

154
day11.zig Normal file
View file

@ -0,0 +1,154 @@
const std = @import("std");
const utils = @import("lib/utils.zig");
const spice = @import("lib/spice.zig");
const day = "11";
const filename = "inputs/day" ++ day ++ ".txt";
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const alloc = gpa.allocator();
{
const file_reader = try utils.FileReader.init(alloc, filename);
defer file_reader.deinit();
const result = try part1(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 1: {}\n", .{result});
}
{
const file_reader = try utils.FileReader.init(alloc, filename);
defer file_reader.deinit();
const result = try part2(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 2: {}\n", .{result});
}
}
const CacheKey = struct { n: u64, depth: u8 };
fn countStones(n: u64, remaining_depth: u8, cache: *std.AutoHashMap(CacheKey, u64)) u64 {
if (remaining_depth == 0) {
return 1;
}
if (cache.get(.{ .n = n, .depth = remaining_depth })) |result| {
return result;
}
if (n == 0) {
const result = countStones(1, remaining_depth - 1, cache);
cache.put(.{ .n = n, .depth = remaining_depth }, result) catch @panic("cache put failed");
return result;
// try countStones(count, 1, remaining_depth);
// return;
}
if (utils.num_digits(n) % 2 == 0) {
const num_digits = utils.num_digits(n);
const pow10 = std.math.powi(u32, 10, num_digits / 2) catch @panic("powi failed");
const left = n / pow10;
const right = n % pow10;
// return countStones(left, remaining_depth - 1, cache) + countStones(right, remaining_depth - 1, cache);
const left_result = countStones(left, remaining_depth - 1, cache);
const right_result = countStones(right, remaining_depth - 1, cache);
const result = left_result + right_result;
cache.put(.{ .n = n, .depth = remaining_depth }, result) catch @panic("cache put failed");
return left_result + right_result;
// try countStones(count, left, remaining_depth - 1);
// try countStones(count, right, remaining_depth - 1);
// return;
}
const result = countStones(n * 2024, remaining_depth - 1, cache);
cache.put(.{ .n = n, .depth = remaining_depth }, result) catch @panic("cache put failed");
return result;
// try countStones(count, 2024 * n, remaining_depth - 1);
}
fn part1(alloc: std.mem.Allocator, reader: anytype) !u64 {
const input = try reader.readAllAlloc(alloc, std.math.maxInt(usize));
defer alloc.free(input);
var count: u64 = 0;
var cache = std.AutoHashMap(CacheKey, u64).init(alloc);
defer cache.deinit();
var number_parser = utils.numberParser(u64, input);
while (try number_parser.next()) |n| {
count += countStones(n, 25, &cache);
}
return count;
}
fn part2(alloc: std.mem.Allocator, reader: anytype) !u64 {
const input = try reader.readAllAlloc(alloc, std.math.maxInt(usize));
defer alloc.free(input);
var count: u64 = 0;
var cache = std.AutoHashMap(CacheKey, u64).init(alloc);
defer cache.deinit();
var number_parser = utils.numberParser(u64, input);
while (try number_parser.next()) |n| {
count += countStones(n, 75, &cache);
}
return count;
}
test "part1 example" {
const alloc = std.testing.allocator;
const example = "125 17";
var stream = std.io.fixedBufferStream(example);
const result = try part1(alloc, stream.reader());
try std.testing.expectEqual(55312, result);
}
test "part1 input" {
const alloc = std.testing.allocator;
const file_reader = try utils.FileReader.init(alloc, filename);
defer file_reader.deinit();
const result = try part1(alloc, file_reader.reader());
try std.testing.expectEqual(193899, result);
}
test "part2 input" {
const alloc = std.testing.allocator;
const file_reader = try utils.FileReader.init(alloc, filename);
defer file_reader.deinit();
const result = try part2(alloc, file_reader.reader());
try std.testing.expectEqual(229682160383225, result);
}

View file

@ -2,7 +2,9 @@ const std = @import("std");
const utils = @import("lib/utils.zig");
const filename = "inputs/day2.txt";
const day = "2";
const filename = "inputs/day" ++ day ++ ".txt";
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -14,7 +16,7 @@ pub fn main() !void {
const result = try part1(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 2, part 1: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 1: {}\n", .{result});
}
{
@ -23,7 +25,7 @@ pub fn main() !void {
const result = try part2(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 2, part 2: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 2: {}\n", .{result});
}
}

View file

@ -4,7 +4,9 @@ const utils = @import("lib/utils.zig");
const isDigit = std.ascii.isDigit;
const filename = "inputs/day3.txt";
const day = "3";
const filename = "inputs/day" ++ day ++ ".txt";
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -16,7 +18,7 @@ pub fn main() !void {
const result = try part1(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 3, part 1: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 1: {}\n", .{result});
}
{
@ -25,7 +27,7 @@ pub fn main() !void {
const result = try part2(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 3, part 2: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 2: {}\n", .{result});
}
}

View file

@ -2,7 +2,9 @@ const std = @import("std");
const utils = @import("lib/utils.zig");
const filename = "inputs/day4.txt";
const day = "4";
const filename = "inputs/day" ++ day ++ ".txt";
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -14,7 +16,7 @@ pub fn main() !void {
const result = try part1(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 4, part 1: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 1: {}\n", .{result});
}
{
@ -23,7 +25,7 @@ pub fn main() !void {
const result = try part2(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 4, part 2: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 2: {}\n", .{result});
}
}

View file

@ -4,7 +4,9 @@ const utils = @import("lib/utils.zig");
const List = std.DoublyLinkedList(u8);
const filename = "inputs/day5.txt";
const day = "5";
const filename = "inputs/day" ++ day ++ ".txt";
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -16,7 +18,7 @@ pub fn main() !void {
const result = try part1(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 5, part 1: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 1: {}\n", .{result});
}
{
@ -25,7 +27,7 @@ pub fn main() !void {
const result = try part2(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 5, part 2: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 2: {}\n", .{result});
}
}

View file

@ -2,7 +2,9 @@ const std = @import("std");
const utils = @import("lib/utils.zig");
const filename = "inputs/day6.txt";
const day = "6";
const filename = "inputs/day" ++ day ++ ".txt";
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -14,7 +16,7 @@ pub fn main() !void {
const result = try part1(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 6, part 1: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 1: {}\n", .{result});
}
{
@ -23,7 +25,7 @@ pub fn main() !void {
const result = try part2(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 6, part 2: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 2: {}\n", .{result});
}
}

View file

@ -4,7 +4,9 @@ const utils = @import("lib/utils.zig");
const spice = @import("lib/spice.zig");
const filename = "inputs/day7.txt";
const day = "7";
const filename = "inputs/day" ++ day ++ ".txt";
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -16,7 +18,7 @@ pub fn main() !void {
const result = try part1(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 7, part 1: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 1: {}\n", .{result});
}
{
@ -25,7 +27,7 @@ pub fn main() !void {
const result = try part2(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 7, part 2: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 2: {}\n", .{result});
}
}

View file

@ -4,7 +4,9 @@ const utils = @import("lib/utils.zig");
const spice = @import("lib/spice.zig");
const filename = "inputs/day8.txt";
const day = "8";
const filename = "inputs/day" ++ day ++ ".txt";
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -16,7 +18,7 @@ pub fn main() !void {
const result = try part1(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 8, part 1: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 1: {}\n", .{result});
}
{
@ -25,7 +27,7 @@ pub fn main() !void {
const result = try part2(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 8, part 2: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 2: {}\n", .{result});
}
}

View file

@ -4,7 +4,9 @@ const utils = @import("lib/utils.zig");
const spice = @import("lib/spice.zig");
const filename = "inputs/day9.txt";
const day = "9";
const filename = "inputs/day" ++ day ++ ".txt";
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -16,7 +18,7 @@ pub fn main() !void {
const result = try part1(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 9, part 1: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 1: {}\n", .{result});
}
{
@ -25,7 +27,7 @@ pub fn main() !void {
const result = try part2(alloc, file_reader.reader());
try std.io.getStdOut().writer().print("Day 9, part 2: {}\n", .{result});
try std.io.getStdOut().writer().print("Day " ++ day ++ ", part 2: {}\n", .{result});
}
}

1
inputs/day11.txt Normal file
View file

@ -0,0 +1 @@
0 89741 316108 7641 756 9 7832357 91

View file

@ -92,12 +92,14 @@ pub fn NumberParser(comptime T: type) type {
};
}
pub fn numberParser(comptime T: type, input: []const u8) NumberParser(T) {
return NumberParser(T){ .token_it = std.mem.tokenizeScalar(u8, input, ' ') };
pub fn numberParserWithDelimiter(comptime T: type, input: []const u8, delimiter: u8) NumberParser(T) {
const input_trimmed = std.mem.trim(u8, input, "\n");
return NumberParser(T){ .token_it = std.mem.tokenizeScalar(u8, input_trimmed, delimiter) };
}
pub fn numberParserWithDelimiter(comptime T: type, input: []const u8, delimiter: u8) NumberParser(T) {
return NumberParser(T){ .token_it = std.mem.tokenizeScalar(u8, input, delimiter) };
pub fn numberParser(comptime T: type, input: []const u8) NumberParser(T) {
return numberParserWithDelimiter(T, input, ' ');
}
pub fn allocGrid(comptime T: type, alloc: std.mem.Allocator, n: usize, m: usize) ![][]T {