diff --git a/2023/day7/src/main.rs b/2023/day7/src/main.rs index b9ac03b..a59a99a 100644 --- a/2023/day7/src/main.rs +++ b/2023/day7/src/main.rs @@ -8,7 +8,7 @@ const FILE_STR: &str = include_str!("input.txt"); #[derive(Copy, Clone, Debug, Default, PartialOrd, Ord, PartialEq, Eq, Hash)] #[repr(u8)] -enum NormalCardType { +enum PartOne { #[default] Two = 0, Three, @@ -25,9 +25,9 @@ enum NormalCardType { Ace, } -impl From for NormalCardType { +impl From for PartOne { fn from(value: char) -> Self { - use NormalCardType::*; + use PartOne::*; match value { '2' => Two, @@ -50,7 +50,7 @@ impl From for NormalCardType { #[derive(Copy, Clone, Debug, Default, PartialOrd, Ord, PartialEq, Eq, Hash)] #[repr(u8)] -enum WildJokerCardType { +enum PartTwo { #[default] Joker = 0, Two, @@ -67,9 +67,9 @@ enum WildJokerCardType { Ace, } -impl From for WildJokerCardType { +impl From for PartTwo { fn from(value: char) -> Self { - use WildJokerCardType::*; + use PartTwo::*; match value { 'J' => Joker, '2' => Two, @@ -88,13 +88,9 @@ impl From for WildJokerCardType { } } } - -type PartOne = NormalCardType; -type PartTwo = WildJokerCardType; - trait CardType: Eq + Copy + PartialOrd + Ord + Debug + Hash + From {} -impl CardType for NormalCardType {} -impl CardType for WildJokerCardType {} +impl CardType for PartOne {} +impl CardType for PartTwo {} #[derive(Debug, Default, PartialEq, Eq)] struct Hand { @@ -103,10 +99,7 @@ struct Hand { bet: usize, } -impl Hand -where - HandType: From<[T; 5]>, -{ +impl Hand { fn parse(line: &str) -> Self { let mut parts = line.split_whitespace(); let raw_hand = parts.next().unwrap(); @@ -163,8 +156,51 @@ enum HandType { } impl HandType { - fn from_cards(value: [WildJokerCardType; 5]) -> Self { - todo!(); + fn from_cards(value: [PartTwo; 5]) -> Self { + let mut cards = Vec::from(value); + cards.sort_unstable(); + + let mut count_map: HashMap = HashMap::new(); + cards.into_iter().for_each(|ct| { + match count_map.get(&ct) { + Some(count) => count_map.insert(ct, *count + 1), + None => count_map.insert(ct, 1), + }; + }); + let mut card_type_counts: Vec = count_map.clone().into_values().collect(); + card_type_counts.sort_unstable(); + + let joker_count = if let Some(count) = count_map.get(&PartTwo::Joker) { + *count + } else { + 0usize + }; + + let base_type = match card_type_counts[..] { + [5] => FiveOfAKind, + [1, 4] => FourOfAKind, + [2, 3] => FullHouse, + [1, 1, 3] => ThreeOfAKind, + [1, 2, 2] => TwoPair, + [1, 1, 1, 2] => OnePair, + _ => HighCard, + }; + + match (joker_count, base_type) { + (0, _) => base_type, + + (_, FourOfAKind) => FiveOfAKind, + (_, FullHouse) => FiveOfAKind, + (_, ThreeOfAKind) => FourOfAKind, + + (1, TwoPair) => FullHouse, + (_, TwoPair) => FourOfAKind, + (_, OnePair) => ThreeOfAKind, + + (_, HighCard) => OnePair, + + (_, _) => base_type, + } } } @@ -224,6 +260,16 @@ impl Game { } } +impl Game { + fn get_wild_score_sum(&mut self) -> usize { + self.hands + .iter_mut() + .for_each(|hand| hand.kind = HandType::from_cards(hand.cards)); + + self.get_score_sum() + } +} + fn part_one() { let mut game: Game = Game::parse(FILE_STR); let score = game.get_score_sum(); @@ -232,7 +278,10 @@ fn part_one() { } fn part_two() { - let _game: Game = Game::parse(FILE_STR); + let mut game: Game = Game::parse(FILE_STR); + let score = game.get_wild_score_sum(); + + println!("Part 2: Sum of wildcard scores: {}", score); } fn main() { @@ -252,5 +301,8 @@ mod test { } #[test] - fn get_wild_score_sum() {} + fn get_wild_score_sum() { + let mut game: Game = Game::parse(EXAMPLE_FILE_STR); + assert_eq!(5905, game.get_wild_score_sum()); + } }