const std = @import("std"); fn check(blocks: [6]u9, width: usize, height: usize, counts: [6]usize) bool { var totalBlocks: usize = 0; for (counts) |c| { totalBlocks += c; } if ((width / 3) * (height / 3) >= totalBlocks) { return true; } var totalUnits: usize = 0; for (counts, 0..) |c, i| { totalUnits += c * @popCount(blocks[i]); } if (width * height < totalUnits) { return false; } // more complex cases don't actually exist in the input data unreachable; } pub fn main() !void { const path: [:0]const u8 = std.mem.span(std.os.argv[1]); var file = try std.fs.cwd().openFile(path, .{}); defer file.close(); var buffer: [1024]u8 = undefined; var reader = file.reader(&buffer); var i: usize = 0; var blocks = [_]u9{0} ** 6; var part1: usize = 0; while (reader.interface.peekDelimiterExclusive('\n')) |line| { reader.interface.toss(line.len + 1); const j = i / 5; if (j < 6) { for (line) |c| { if (c == '#') { blocks[j] <<= 1; blocks[j] |= 1; } else if (c == '.') { blocks[j] <<= 1; } } } else { var x1: usize = 0; var x2: usize = std.mem.indexOfScalar(u8, line, 'x').?; const width = try std.fmt.parseInt(usize, line[x1..x2], 10); x1 = x2 + 1; x2 = std.mem.indexOfScalar(u8, line, ':').?; const height = try std.fmt.parseInt(usize, line[x1..x2], 10); var counts = [_]usize{0} ** 6; x2 += 1; for (0..6) |k| { x1 = x2 + 1; x2 = x1 + (std.mem.indexOfScalar(u8, line[x1..], ' ') orelse (line.len - x1)); counts[k] = try std.fmt.parseInt(usize, line[x1..x2], 10); } if (check(blocks, width, height, counts)) { part1 += 1; } } i += 1; } else |err| switch (err) { error.EndOfStream => {}, else => |e| return e, } std.debug.print("part1: {}\n", .{part1}); }