AoC23/src/day02.rs

100 lines
2.7 KiB
Rust

use std::collections::HashMap;
use regex::Regex;
pub fn run() {
let input = include_str!("../input/day2.txt");
// let input = r#"
// 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
// "#;
let games = parse_games(input);
let valid_ids_sum: u32 = games
.iter()
.filter(|g| g.valid_counts(12, 13, 14))
.map(|g| g.id)
.sum();
dbg!(valid_ids_sum);
let min_counts_power_sum: u32 = games
.iter()
.map(|g| {
let (r, g, b) = g.min_counts();
r * g * b
})
.sum();
dbg!(min_counts_power_sum);
}
fn parse_games(s: &str) -> Vec<Game> {
let mut games = vec![];
for l in s.lines() {
let l = l.trim();
if l.is_empty() {
continue;
}
let (game_s, rest) = l.split_once(": ").unwrap();
let game_n: u32 = game_s
.strip_prefix("Game ")
.expect("game prefix")
.parse()
.expect("game number");
let mut draws = vec![];
for draw in rest.split(";") {
let drawn = draw
.split(", ")
.map(|s| {
let (count, color) = s.trim().split_once(" ").unwrap();
let count: u32 = count.parse().expect("count number");
(color, count)
})
.collect::<HashMap<_, _>>();
draws.push(Draw {
red: *drawn.get("red").unwrap_or(&0),
green: *drawn.get("green").unwrap_or(&0),
blue: *drawn.get("blue").unwrap_or(&0),
});
}
games.push(Game { id: game_n, draws });
}
games
}
#[derive(Debug, Clone)]
struct Game {
id: u32,
draws: Vec<Draw>,
}
#[derive(Debug, Copy, Clone)]
struct Draw {
red: u32,
green: u32,
blue: u32,
}
impl Game {
fn valid_counts(&self, red: u32, green: u32, blue: u32) -> bool {
self.draws
.iter()
.all(|draw| draw.red <= red && draw.green <= green && draw.blue <= blue)
}
fn min_counts(&self) -> (u32, u32, u32) {
let mut red = 0u32;
let mut green = 0u32;
let mut blue = 0u32;
for draw in self.draws.iter() {
red = red.max(draw.red);
green = green.max(draw.green);
blue = blue.max(draw.blue);
}
(red, green, blue)
}
}