100 lines
2.7 KiB
Rust
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)
|
||
|
}
|
||
|
}
|