const std = @import("std"); pub fn main() !void { const file = try std.fs.cwd().openFile("./data.txt", .{}); defer file.close(); var buffer: [30000]u8 = undefined; _ = try file.readAll(&buffer); var it = std.mem.split(u8, &buffer, "\n"); var total1: u64 = 0; var total2: u64 = 0; while (it.next()) |line| { if (!std.ascii.isAlphanumeric(line[0])) { continue; } var game: u64 = 0; var busted: bool = false; var min_red: u64 = 1; var min_green: u64 = 1; var min_blue: u64 = 1; // Split the row on colons var parts = std.mem.split(u8, line, ": "); while (parts.next()) |part| { // if it contais "Game", parse out the game ID if (std.mem.eql(u8, part[0..4], "Game")) { game = try std.fmt.parseInt(u8, part[5..], 10); } else { // Split the turns up by semicolons var turns = std.mem.split(u8, part, "; "); var red: u64 = 0; var green: u64 = 0; var blue: u64 = 0; while (turns.next()) |turn| { // Split the colors up by commas var colors = std.mem.split(u8, turn, ", "); while (colors.next()) |color| { const idx = findIdx(color, ' ').?; const num = try std.fmt.parseInt(u8, color[0..idx], 10); if (endsWith(color, "red")) { if (num > min_red) { min_red = num; } if (num > 12) { busted = true; } red += num; } else if (endsWith(color, "green")) { if (num > min_green) { min_green = num; } if (num > 13) { busted = true; } green += num; } else if (endsWith(color, "blue")) { if (num > min_blue) { min_blue = num; } if (num > 14) { busted = true; } blue += num; } } } } } if (!busted) { total1 += game; } const power: u64 = min_red * min_green * min_blue; total2 += power; } std.debug.print("part 1 total: {any}\n", .{total1}); std.debug.print("part 2 total: {any}\n", .{total2}); } // does the outer string end with the inner string fn endsWith(outer: []const u8, inner: []const u8) bool { if (outer.len < inner.len) { return false; } const offset = outer.len - inner.len; for (inner, 0..) |c, idx| { if (c != outer[idx + offset]) { return false; } } return true; } // find the index of char in string fn findIdx(string: []const u8, char: u8) ?usize { for (string, 0..) |c, idx| { if (c == char) { return idx; } } return null; }