import arrays import os const input := os.read_file('./input.txt')! //const input = 'Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green //Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue //Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red //Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red //Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green //' struct Draw { reds int blues int greens int } struct Game { id int draws []Draw } fn (g Game) min_reds() int { return arrays.max(g.draws.map(it.reds)) or { panic('cannot get the min number of reds needed for ${g}') } } fn (g Game) min_greens() int { return arrays.max(g.draws.map(it.greens)) or { panic('cannot get the min number of greens needed for ${g}') } } fn (g Game) min_blues() int { return arrays.max(g.draws.map(it.blues)) or { panic('cannot get the min number of blues needed for ${g}') } } fn (g Game) power_min() int { return g.min_reds() * g.min_greens() * g.min_blues() } fn parse_draw(input string) Draw { parts := input.split(',') mut r, mut g, mut b := 0, 0, 0 for part in parts { match true { part.contains('red') { r = part.trim_space().split(' ')[0].int() } part.contains('green') { g = part.trim_space().split(' ')[0].int() } part.contains('blue') { b = part.trim_space().split(' ')[0].int() } else { panic('unrecognized color ${part}') } } } return Draw{ reds: r greens: g blues: b } } fn parse_input(input string) []Game { lines := input.split('\n') mut games := []Game{} for i, line in lines { if line.is_blank() { continue } parts := line.split_any(':;') mut draws := []Draw{} for draw in parts[1..] { draws << parse_draw(draw) } games << Game{ id: i + 1 draws: draws } } return games } fn main() { games := parse_input(input) powers := games.map(it.power_min()) sum := arrays.sum(powers)! println('Result: ${sum}') }