1
0
Fork 0
advent-of-code/2023/src/day02.rs

98 lines
2.6 KiB
Rust

use aoc_runner_derive::{aoc, aoc_generator};
const MAX_RED: u32 = 12;
const MAX_GREEN: u32 = 13;
const MAX_BLUE: u32 = 14;
struct Turn {
red: u32,
green: u32,
blue: u32,
}
struct Game {
id: u32,
turns: Vec<Turn>,
}
impl Game {
fn part1_possible(&self) -> Option<u32> {
for turn in self.turns.iter() {
if turn.red > MAX_RED || turn.green > MAX_GREEN || turn.blue > MAX_BLUE {
return None;
}
}
return Some(self.id);
}
fn part2_power(&self) -> u32 {
let mut max_red = 0;
let mut max_green = 0;
let mut max_blue = 0;
for turn in self.turns.iter() {
if turn.red > max_red {
max_red = turn.red;
}
if turn.green > max_green {
max_green = turn.green;
}
if turn.blue > max_blue {
max_blue = turn.blue;
}
}
max_red * max_green * max_blue
}
}
#[aoc_generator(day2)]
fn parse(input: &str) -> Vec<Game> {
input
.lines()
.filter_map(|line| {
if !line.is_empty() {
let gparts: Vec<&str> = line.split(": ").collect();
let game_id = gparts[0].split(" ").collect::<Vec<&str>>()[1]
.parse::<u32>()
.unwrap();
let mut turns: Vec<Turn> = vec![];
for whole_turn in gparts[1].split("; ") {
let mut red = 0;
let mut green = 0;
let mut blue = 0;
for dice_group in whole_turn.split(", ") {
let dice_parts: Vec<&str> = dice_group.split(" ").collect();
let count = dice_parts[0].parse::<u32>().unwrap();
match dice_parts[1] {
"red" => red = count,
"green" => green = count,
"blue" => blue = count,
_ => panic!("invalid color! {}", dice_parts[0]),
}
}
turns.push(Turn { red, green, blue });
}
Some(Game { id: game_id, turns })
} else {
None
}
})
.collect()
}
#[aoc(day2, part1)]
fn part1_valid_game_sum(input: &[Game]) -> u32 {
input.iter().filter_map(|game| game.part1_possible()).sum()
}
#[aoc(day2, part2)]
fn part2_power_sum(input: &[Game]) -> u32 {
input.iter().map(|game| game.part2_power()).sum()
}
#[cfg(test)]
mod tests {
// use super::*;
}