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

112 lines
2.9 KiB
Rust

advent_of_code::solution!(2);
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
}
}
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()
}
pub fn part_one(input: &str) -> Option<u32> {
Some(
parse(input)
.iter()
.filter_map(|game| game.part1_possible())
.sum(),
)
}
pub fn part_two(input: &str) -> Option<u32> {
Some(parse(input).iter().map(|game| game.part2_power()).sum())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(8));
}
#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(2286));
}
}