advent-of-code-2023/02/part2.v

100 lines
2 KiB
Coq
Raw Normal View History

2023-12-02 13:48:19 +01:00
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}')
}