const std = @import("std"); const mecha = @import("mecha"); const print = std.debug.print; pub fn solve(part: []u8, buffer: []u8, allocator: std.mem.Allocator) !void { var lines = std.mem.splitScalar(u8, buffer, '\n'); var split = std.mem.splitScalar(u8, lines.next().?, ' '); var numbers = std.ArrayList(usize).init(allocator); defer numbers.deinit(); while (split.next()) |n_string| { try numbers.append(try std.fmt.parseInt(usize, n_string, 10)); } if (std.mem.eql(u8, part, "1")) { try part1(numbers, allocator); } else { try part2(numbers, allocator); } } fn digits(int: usize) usize { var count: usize = 0; var temp = int; while (temp > 0) { temp /= 10; count += 1; } return count; } fn recursive(number: usize, history: *std.AutoHashMap(std.meta.Tuple(&.{ usize, usize }), usize), depth: usize) !usize { if (history.get(.{ number, depth })) |value| { return value; } if (depth == 0) { return 1; } var sum: usize = 0; if (number == 0) { sum = try recursive(1, history, depth - 1); } else { const n_digits = digits(number); if (n_digits % 2 == 0) { const p = std.math.pow(usize, 10, n_digits / 2); const first = number / p; const second = number % p; sum += try recursive(first, history, depth - 1); sum += try recursive(second, history, depth - 1); } else { sum += try recursive(number * 2024, history, depth - 1); } } try history.put(.{ number, depth }, sum); return sum; } fn part1(numbers: std.ArrayList(usize), allocator: std.mem.Allocator) !void { var history = std.AutoHashMap(std.meta.Tuple(&.{ usize, usize }), usize).init(allocator); defer history.deinit(); var total: usize = 0; for (numbers.items) |number| { total += try recursive(number, &history, 25); } print("{d}\n", .{total}); } fn part2(numbers: std.ArrayList(usize), allocator: std.mem.Allocator) !void { var history = std.AutoHashMap(std.meta.Tuple(&.{ usize, usize }), usize).init(allocator); defer history.deinit(); var total: usize = 0; for (numbers.items) |number| { total += try recursive(number, &history, 75); } print("{d}\n", .{total}); }