Advent of Code 2025 - Zig
at main 3.9 kB view raw
1const std = @import("std"); 2const Allocator = std.mem.Allocator; 3const StringTokenIterator = std.mem.TokenIterator(u8, .scalar); 4 5const MAX_WIDTH = 137; 6 7const Grid = struct { 8 data: [MAX_WIDTH][]u8, 9 maxX: usize, 10 maxY: usize, 11 12 pub fn isRoll(self: *const Grid, x: isize, y: isize) bool { 13 if (x < 0 or x >= self.maxX) { 14 return false; 15 } 16 if (y < 0 or y >= self.maxY) { 17 return false; 18 } 19 20 return self.data[@intCast(x)][@intCast(y)] == '@'; 21 } 22}; 23 24fn newGrid(lines: *StringTokenIterator) !Grid { 25 const line_len = lines.peek().?.len; 26 var grid: [MAX_WIDTH][]u8 = undefined; 27 28 var i: usize = 0; 29 while (lines.next()) |line| : (i += 1) { 30 grid[i] = @constCast(line); 31 } 32 33 return .{ .data = grid, .maxX = line_len, .maxY = i }; 34} 35 36pub fn run(_: Allocator, input: []u8) !struct { u64, u64 } { 37 var lines = std.mem.tokenizeScalar(u8, input, '\n'); 38 39 const grid = try newGrid(&lines); 40 41 var answer1: u64 = 0; 42 var answer2: u64 = 0; 43 44 // Need to figure out how to not make this ugly, but too tired 45 for (0..grid.maxX) |i| { 46 for (0..grid.maxY) |j| { 47 if (grid.isRoll(@as(isize, @intCast(i)), @as(isize, @intCast(j)))) { 48 var adjacent_count: usize = 0; 49 50 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) - 1, @as(isize, @intCast(j)) - 1)); 51 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) - 1, @as(isize, @intCast(j)))); 52 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)), @as(isize, @intCast(j)) - 1)); 53 54 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) + 1, @as(isize, @intCast(j)) - 1)); 55 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) - 1, @as(isize, @intCast(j)) + 1)); 56 57 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) + 1, @as(isize, @intCast(j)) + 1)); 58 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) + 1, @as(isize, @intCast(j)))); 59 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)), @as(isize, @intCast(j)) + 1)); 60 61 if (adjacent_count < 4) { 62 answer1 += 1; 63 } 64 } 65 } 66 } 67 68 var removed = true; 69 70 while (removed) { 71 removed = false; 72 73 for (0..grid.maxX) |i| { 74 for (0..grid.maxY) |j| { 75 if (grid.isRoll(@as(isize, @intCast(i)), @as(isize, @intCast(j)))) { 76 var adjacent_count: usize = 0; 77 78 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) - 1, @as(isize, @intCast(j)) - 1)); 79 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) - 1, @as(isize, @intCast(j)))); 80 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)), @as(isize, @intCast(j)) - 1)); 81 82 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) + 1, @as(isize, @intCast(j)) - 1)); 83 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) - 1, @as(isize, @intCast(j)) + 1)); 84 85 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) + 1, @as(isize, @intCast(j)) + 1)); 86 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)) + 1, @as(isize, @intCast(j)))); 87 adjacent_count += @intFromBool(grid.isRoll(@as(isize, @intCast(i)), @as(isize, @intCast(j)) + 1)); 88 89 if (adjacent_count < 4) { 90 answer2 += 1; 91 grid.data[i][j] = '.'; 92 removed = true; 93 } 94 } 95 } 96 } 97 } 98 99 return .{ answer1, answer2 }; 100}