diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 7f3dc66..59e1219 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -4,4 +4,4 @@ version = 3 [[package]] name = "advent-of-code" -version = "23.2.1" +version = "23.2.2" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index bbd8903..9d21233 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "advent-of-code" -version = "23.2.1" +version = "23.2.2" edition = "2021" default-run = "day02" diff --git a/rust/src/day02/part_2.rs b/rust/src/day02/part_2.rs index 928ee24..3953677 100644 --- a/rust/src/day02/part_2.rs +++ b/rust/src/day02/part_2.rs @@ -1,5 +1,86 @@ -pub(crate) fn part_2(_input: &'static str) -> u64 { - todo!("Part 2") +#[derive(Default)] +struct CubeCounts { + red: u16, + green: u16, + blue: u16, +} +impl CubeCounts { + const fn power(&self) -> u16 { + self.red * self.green * self.blue + } +} + +impl std::ops::Add for CubeCounts { + type Output = Self; + + fn add(self, rhs: CubeCounts) -> Self::Output { + Self { + red: self.red + rhs.red, + green: self.green + rhs.green, + blue: self.blue + rhs.blue, + } + } +} + +impl std::iter::Sum for CubeCounts { + fn sum>(iter: I) -> Self { + iter.fold(CubeCounts::default(), |acc, x| acc + x) + } +} + +pub(crate) fn part_2(input: &'static str) -> u16 { + let id_sum = input + .lines() + .map(|line| { + let game_start_index = line.find(":").expect("Every line should have a ': '") + 2; + + let game = &line[game_start_index..]; + + let groups = game.split("; "); + + let game_counts = groups + .map(|group| { + let color_counts = group.split(", "); + + let group_counts = + color_counts.map(|color_count| { + let (count, color) = color_count + .split_once(' ') + .expect("Every color count should have one space"); + + let count = count.parse().expect( + format!("Every color count should be a valid number - `{count}` `{color}`") + .as_str(), + ); + + match color { + "red" => CubeCounts { + red: count, + ..Default::default() + }, + "green" => CubeCounts { + green: count, + ..Default::default() + }, + "blue" => CubeCounts { + blue: count, + ..Default::default() + }, + _ => unreachable!(), + } + }); + group_counts.sum::() + }) + .reduce(|acc, cube_count| CubeCounts { + red: u16::max(acc.red, cube_count.red), + green: u16::max(acc.green, cube_count.green), + blue: u16::max(acc.blue, cube_count.blue), + }) + .expect("At least one group should exist in each game"); + game_counts.power() + }) + .sum(); + id_sum } #[cfg(test)] @@ -8,17 +89,11 @@ mod tests { #[test] fn test_with_sample_solution() { - assert_eq!( - super::part_2(SAMPLE_INPUT), - todo!("Add result from example part 2") - ); + assert_eq!(super::part_2(SAMPLE_INPUT), 2286); } #[test] fn test_with_solution() { - assert_eq!( - super::part_2(crate::INPUT), - todo!("Add result for solved part 2") - ); + assert_eq!(super::part_2(crate::INPUT), 63981); } }