const std = @import("std"); const Setup = @import("common.zig").Setup; const Colour = enum { red, green, blue , fn parse(str: []const u8) !Colour { const ei = @typeInfo(Colour).Enum; inline for (ei.fields) |field| { if (std.mem.eql(u8, field.name, str)) { return @enumFromInt(field.value); } } else { return error.InvalidColour; } } }; pub fn main() !void { var setup = try Setup.get(); defer setup.deinit(); var sum: u32 = 0; var lines = std.mem.splitScalar(u8, setup.input, '\n'); const maxred: u32 = 12; const maxgreen: u32 = 13; const maxblue: u32 = 14; while (lines.next()) |line| { var spl = std.mem.split(u8, line, ": "); const game_no_str = spl.first(); const game_no = try std.fmt.parseInt(u32, game_no_str[5..game_no_str.len], 10); // "Game " prefix skipped const game_str = spl.next() orelse return error.NoGame; var turns = std.mem.split(u8, game_str, "; "); var gamemaxred: u32 = 0; var gamemaxgreen: u32 = 0; var gamemaxblue: u32 = 0; while (turns.next()) |turn| { var cols = std.mem.split(u8, turn, ", "); while (cols.next()) |col| { var spl2 = std.mem.split(u8, col, " "); const num = try std.fmt.parseInt(u32, spl2.first(), 10); const col_str = spl2.next() orelse return error.NoColour; const c = try Colour.parse(col_str); switch(c) { .blue => { gamemaxblue = @max(num, gamemaxblue); }, .green => { gamemaxgreen = @max(num, gamemaxgreen); }, .red => { gamemaxred = @max(num, gamemaxred); }, } } } switch (setup.part) { .pt1 => { if (gamemaxblue <= maxblue and gamemaxgreen <= maxgreen and gamemaxred <= maxred) { sum += game_no; } else { //std.log.warn("game was impossible {s}", .{line}); } }, .pt2 => { const power = gamemaxblue * gamemaxgreen * gamemaxred; sum += power; }, } //turns.next() } try std.fmt.format(std.io.getStdOut().writer(), "answer: {}\n", .{sum}); }