// zig is growing on me tbh const std = @import("std"); var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); const alloc = arena.allocator(); const test_data = @embedFile("test"); const input_data = @embedFile("input"); pub fn main() !void { const stdout = std.io.getStdOut().writer(); const value1 = try run1(input_data); try stdout.print("{d}\n", .{value1}); const value2 = try run2(input_data); try stdout.print("{d}\n", .{value2}); } test "test input part 1" { std.debug.print("\n", .{}); const value = try run1(test_data); std.debug.print("{d}\n", .{value}); try std.testing.expectEqual(36, value); } test "test input part 2" { std.debug.print("\n",.{}); const value = try run2(test_data); std.debug.print("{d}\n", .{value}); try std.testing.expectEqual(81, value); } fn parseIntFromReader(reader: anytype) anyerror!u64 { const f = try reader.readByte(); if (f < '0' or f > '9') return error.BadCharacter; var v: u64 = f - '0'; while (true) { const c = try reader.readByte(); if (c < '0' or c > '9') { break; } else { v = (v * 10) + (c - '0'); } } return v; } fn run2(input: []const u8) !u64 { var map: [64][64]u8 = [_][64]u8{[_]u8{0}**64}**64; var lines = std.mem.splitScalar(u8, input, '\n'); var y: usize = 0; var x: usize = 0; var dim: usize = undefined; while (lines.next()) |line| { if (std.mem.eql(u8, line, "")) continue; std.mem.copyForwards(u8, &map[y], line); std.debug.print("{s}\n",.{line}); dim = line.len; y += 1; } std.debug.print("map max {}\n", .{dim}); var total: u64 = 0; var outmap: [64][64]u8 = [_][64]u8{[_]u8{0}**64}**64; y = 0; while (y < dim) : (y += 1) { x = 0; while (x < dim) : (x += 1) { if (map[y][x] == '9') { checkpath2(y, x, dim, &map, &outmap); } } } y = 0; while (y < dim) : (y += 1) { x = 0; while (x < dim) : (x += 1) { total += outmap[y][x]; } } return total; } fn checkpath2(y: usize, x: usize, dim: usize, map: *[64][64]u8, outmap: *[64][64]u8) void { const c = map[y][x]; if (c == '0') { outmap[y][x] += 1; return; } if (y > 0) if (map[y-1][x] == c-1) { checkpath2(y-1, x, dim, map, outmap); }; if (x > 0) if (map[y][x-1] == c-1) { checkpath2(y, x-1, dim, map, outmap); }; if (y < dim-1) if (map[y+1][x] == c-1) { checkpath2(y+1, x, dim, map, outmap); }; if (x < dim-1) if (map[y][x+1] == c-1) { checkpath2(y, x+1, dim, map, outmap); }; } fn checkpath(y: usize, x: usize, dim: usize, map: *[64][64]u8, outmap: *[64][64]u8) void { const c = map[y][x]; if (c == '0') { outmap[y][x] = 1; return; } if (y > 0) if (map[y-1][x] == c-1) { checkpath(y-1, x, dim, map, outmap); }; if (x > 0) if (map[y][x-1] == c-1) { checkpath(y, x-1, dim, map, outmap); }; if (y < dim-1) if (map[y+1][x] == c-1) { checkpath(y+1, x, dim, map, outmap); }; if (x < dim-1) if (map[y][x+1] == c-1) { checkpath(y, x+1, dim, map, outmap); }; } fn run1(input: []const u8) !u64 { var map: [64][64]u8 = [_][64]u8{[_]u8{0}**64}**64; var lines = std.mem.splitScalar(u8, input, '\n'); var y: usize = 0; var x: usize = 0; var dim: usize = undefined; while (lines.next()) |line| { if (std.mem.eql(u8, line, "")) continue; std.mem.copyForwards(u8, &map[y], line); std.debug.print("{s}\n",.{line}); dim = line.len; y += 1; } std.debug.print("map max {}\n", .{dim}); var total: u64 = 0; var outmap: [64][64]u8 = undefined; y = 0; while (y < dim) : (y += 1) { x = 0; while (x < dim) : (x += 1) { if (map[y][x] == '9') { outmap = [_][64]u8{[_]u8{0}**64}**64; checkpath(y, x, dim, &map, &outmap); var iy: usize = 0; while (iy < dim) : (iy += 1) { var ix: usize = 0; while (ix < dim) : (ix += 1) { total += outmap[iy][ix]; } } } } } return total; }