Complete 2023 day 2

This commit is contained in:
Timothy Warren 2023-12-06 09:38:40 -05:00
parent 0d46c79e14
commit a6995cbc51
1 changed files with 123 additions and 16 deletions

View File

@ -1,12 +1,22 @@
use std::collections::HashMap; use std::collections::HashMap;
const FILE_STR: &'static str = include_str!("input.txt");
#[derive(Debug, PartialOrd, PartialEq)] #[derive(Debug, PartialOrd, PartialEq)]
struct CubeSet { struct CubeSet {
red: usize, red: usize,
blue: usize,
green: usize, green: usize,
blue: usize,
}
impl CubeSet {
fn new(red: usize, green: usize, blue: usize) -> Self {
CubeSet { red, green, blue }
}
} }
type CubeMap = HashMap<usize, Vec<CubeSet>>; type CubeMap = HashMap<usize, Vec<CubeSet>>;
type MinCubeMap = HashMap<usize, CubeSet>;
fn parse_colors(raw_colors: Vec<&str>) -> CubeSet { fn parse_colors(raw_colors: Vec<&str>) -> CubeSet {
let mut red = 0usize; let mut red = 0usize;
@ -38,7 +48,7 @@ fn parse_colors(raw_colors: Vec<&str>) -> CubeSet {
} }
} }
CubeSet { red, blue, green } CubeSet::new(red, green, blue)
} }
fn parse_game(line: &str, map: &mut CubeMap) { fn parse_game(line: &str, map: &mut CubeMap) {
@ -67,27 +77,45 @@ fn is_valid(reference: &CubeSet, comparison: &CubeSet) -> bool {
&& reference.red >= comparison.red && reference.red >= comparison.red
} }
fn filter_valid_games(reference: &CubeSet, games: CubeMap) -> CubeMap { fn validate_games(reference: &CubeSet, games: CubeMap) -> Vec<usize> {
games games
.into_iter() .into_iter()
.filter(|(_, cubes)| cubes.iter().all(|c| is_valid(reference, c))) .filter(|(_, cubes)| cubes.iter().all(|c| is_valid(reference, c)))
.collect()
}
fn validate_games(reference: &CubeSet, games: CubeMap) -> Vec<usize> {
filter_valid_games(reference, games)
.into_iter()
.map(|(id, _)| id) .map(|(id, _)| id)
.collect() .collect()
} }
fn find_min_cubes(valid_games: &CubeMap) -> CubeMap { fn find_min_cubes(valid_games: &CubeMap) -> MinCubeMap {
let games = valid_games.clone().to_owned(); let mut min_cubes = HashMap::new();
todo!();
valid_games.iter().for_each(|(id, set_map)| {
let mut r = 0usize;
let mut g = 0usize;
let mut b = 0usize;
set_map.iter().for_each(|set| {
if set.red > r {
r = set.red;
}
if set.green > g {
g = set.green;
}
if set.blue > b {
b = set.blue;
}
});
min_cubes.insert(*id, CubeSet::new(r, g, b));
});
min_cubes
} }
fn main() { fn cube_power(cube: &CubeSet) -> usize {
let file_str = include_str!("input.txt"); cube.red * cube.green * cube.blue
}
fn part_one() {
let mut map: CubeMap = HashMap::new(); let mut map: CubeMap = HashMap::new();
let reference = CubeSet { let reference = CubeSet {
red: 12, red: 12,
@ -95,7 +123,7 @@ fn main() {
blue: 14, blue: 14,
}; };
file_str FILE_STR
.split('\n') .split('\n')
.for_each(|line| parse_game(line, &mut map)); .for_each(|line| parse_game(line, &mut map));
@ -105,5 +133,84 @@ fn main() {
println!("Part 1 Sum of valid games: {}", sum); println!("Part 1 Sum of valid games: {}", sum);
} }
fn part_two() {
let mut map: CubeMap = HashMap::new();
FILE_STR
.split('\n')
.for_each(|line| parse_game(line, &mut map));
let min_cube_sum: usize = find_min_cubes(&map)
.iter()
.map(|(_, set)| cube_power(set))
.sum();
println!("Part 2 Sum of min cubes: {}", min_cube_sum);
}
fn main() {
part_one();
part_two();
}
#[cfg(test)] #[cfg(test)]
mod tests {} mod tests {
use super::*;
#[test]
fn test_min_cubes() {
let games: CubeMap = HashMap::from([
(
1,
Vec::from([
CubeSet::new(4, 0, 3),
CubeSet::new(1, 2, 0),
CubeSet::new(0, 2, 6),
]),
),
(
2,
Vec::from([
CubeSet::new(0, 2, 1),
CubeSet::new(1, 3, 4),
CubeSet::new(0, 1, 1),
]),
),
(
3,
Vec::from([
CubeSet::new(20, 8, 6),
CubeSet::new(4, 13, 5),
CubeSet::new(1, 5, 0),
]),
),
(
4,
Vec::from([
CubeSet::new(3, 1, 6),
CubeSet::new(6, 3, 0),
CubeSet::new(14, 3, 15),
]),
),
(5, Vec::from([CubeSet::new(6, 3, 1), CubeSet::new(1, 2, 2)])),
]);
let expected: MinCubeMap = HashMap::from([
(1, CubeSet::new(4, 2, 6)),
(2, CubeSet::new(1, 3, 4)),
(3, CubeSet::new(20, 13, 6)),
(4, CubeSet::new(14, 3, 15)),
(5, CubeSet::new(6, 3, 2)),
]);
let actual = find_min_cubes(&games);
actual.iter().for_each(|(id, min_cubes)| {
assert_eq!(
min_cubes,
expected.get(id).unwrap(),
"Game {} min cubes",
id
);
});
}
}