diff --git a/src/day07.rs b/src/day07.rs index 93dce1a..69a1551 100644 --- a/src/day07.rs +++ b/src/day07.rs @@ -1,3 +1,4 @@ +use std::cmp::Ordering; use std::collections::HashMap; use std::fmt::{Display, Formatter}; use std::panic::panic_any; @@ -19,9 +20,12 @@ pub enum Card { N5 = 11, N4 = 12, N3 = 13, - N2 = 14 + N2 = 14, + JOKER_2 = 15, } + + impl From for Card { fn from(value: char) -> Self { match value { @@ -67,17 +71,32 @@ impl From> for Hand { *cards.entry(c.to_string()).or_insert(0) += 1; } + let key = cards.keys() + .filter(|k| k.to_string() != "JOKER_2") + .map(|k| (k, cards[k])) + .max_by(|(_, v1), (_, v2)| Ord::cmp(v1, v2)); + + if let None = key { // All are jokers + return Hand::FiveOfAKind(value) + } + let key = key.unwrap().0.to_owned(); + + let joker = cards.get("JOKER_2").unwrap_or(&0).clone(); + *cards.entry(key).or_default() += joker; + cards.remove("JOKER_2"); + + match cards.values().len() { 1 => Hand::FiveOfAKind(value), // can only be five of a kind 2 => { // Can be four of a kind or Full house - if *cards.values().sorted().rev().collect::>()[0] == 4 { + if *cards.values().max().unwrap() == 4 { Hand::FourOfAKind(value) } else { Hand::FullHouse(value) } }, 3 => { // Can be two pairs or three of a kind - if *cards.values().sorted().rev().collect::>()[0] == 3 { + if *cards.values().max().unwrap() == 3 { Hand::ThreeOfAKind(value) } else { Hand::TwoPair(value) @@ -104,7 +123,7 @@ pub fn execute_task02(content: &str) { let product_correct_races = solve_02(content).unwrap(); let duration = start.elapsed(); - assert_eq!(32583852, product_correct_races); + assert_eq!(248747492, product_correct_races); println!("Day07 - Task02 - Duration: {duration:?} - Correct Race (with Joker): {}", product_correct_races) } @@ -121,11 +140,18 @@ fn solve_01(content: &str) -> anyhow::Result { .sum()) } -fn solve_02(content: &str) -> anyhow::Result { +fn solve_02(content: &str) -> anyhow::Result { Ok(content .lines() .map(|line| line.split_once(" ").unwrap()) - .map(|(hand, bid)| (hand.chars().map(|c| Card::from(c)).collect::>(), bid.parse::().unwrap())) + .map(|(hand, bid)| (hand.chars().map(|c| { + let mut c = Card::from(c); + if c == Card::J { + c = Card::JOKER_2; + } + + c + }).collect::>(), bid.parse::().unwrap())) .map(|(hand, bid)| (Hand::from(hand), bid)) .sorted_by(|(hand, _), (second_hand, _)| Ord::cmp(hand, second_hand)) .rev() @@ -134,6 +160,83 @@ fn solve_02(content: &str) -> anyhow::Result { .sum()) } +/* +fn order_joker_hands(a: &Hand, b: &Hand) -> Ordering { + match (a, b) { + (Hand::FiveOfAKind(a_data), Hand::FiveOfAKind(b_data)) => { + + }, + (Hand::FourOfAKind(a_data), Hand::FourOfAKind(b_data)) => { + todo!() + }, + (Hand::FullHouse(a_data), Hand::FullHouse(b_data)) => { + todo!() + }, + (Hand::ThreeOfAKind(a_data), Hand::ThreeOfAKind(b_data)) => { + todo!() + }, + (Hand::TwoPair(a_data), Hand::TwoPair(b_data)) => { + todo!() + }, + (Hand::OnePair(a_data), Hand::OnePair(b_data)) => { + todo!() + }, + (Hand::HighCard(a_data), Hand::HighCard(b_data)) => { + todo!() + }, + (Hand::FiveOfAKind(a_data), Hand::FourOfAKind(b_data)) => Ordering::Less, + (Hand::FiveOfAKind(a_data), Hand::FullHouse(b_data)) => Ordering::Less, + (Hand::FiveOfAKind(a_data), Hand::ThreeOfAKind(b_data)) => Ordering::Less, + (Hand::FiveOfAKind(a_data), Hand::TwoPair(b_data)) => Ordering::Less, + (Hand::FiveOfAKind(a_data), Hand::OnePair(b_data)) => Ordering::Less, + (Hand::FiveOfAKind(a_data), Hand::HighCard(b_data)) => Ordering::Less, + + (Hand::FourOfAKind(a_data), Hand::FiveOfAKind(b_data)) => Ordering::Greater, + (Hand::FourOfAKind(a_data), Hand::FullHouse(b_data)) => Ordering::Less, + (Hand::FourOfAKind(a_data), Hand::ThreeOfAKind(b_data)) => Ordering::Less, + (Hand::FourOfAKind(a_data), Hand::TwoPair(b_data)) => Ordering::Less, + (Hand::FourOfAKind(a_data), Hand::OnePair(b_data)) => Ordering::Less, + (Hand::FourOfAKind(a_data), Hand::HighCard(b_data)) => Ordering::Less, + + (Hand::FullHouse(a_data), Hand::FiveOfAKind(b_data)) => Ordering::Greater, + (Hand::FullHouse(a_data), Hand::FourOfAKind(b_data)) => Ordering::Greater, + (Hand::FullHouse(a_data), Hand::ThreeOfAKind(b_data)) => Ordering::Less, + (Hand::FullHouse(a_data), Hand::TwoPair(b_data)) => Ordering::Less, + (Hand::FullHouse(a_data), Hand::OnePair(b_data)) => Ordering::Less, + (Hand::FullHouse(a_data), Hand::HighCard(b_data)) => Ordering::Less, + + (Hand::ThreeOfAKind(a_data), Hand::FiveOfAKind(b_data)) => Ordering::Greater, + (Hand::ThreeOfAKind(a_data), Hand::FourOfAKind(b_data)) => Ordering::Greater, + (Hand::ThreeOfAKind(a_data), Hand::FullHouse(b_data)) => Ordering::Greater, + (Hand::ThreeOfAKind(a_data), Hand::TwoPair(b_data)) => Ordering::Less, + (Hand::ThreeOfAKind(a_data), Hand::OnePair(b_data)) => Ordering::Less, + (Hand::ThreeOfAKind(a_data), Hand::HighCard(b_data)) => Ordering::Less, + + (Hand::TwoPair(a_data), Hand::FiveOfAKind(b_data)) => Ordering::Greater, + (Hand::TwoPair(a_data), Hand::FourOfAKind(b_data)) => Ordering::Greater, + (Hand::TwoPair(a_data), Hand::FullHouse(b_data)) => Ordering::Greater, + (Hand::TwoPair(a_data), Hand::ThreeOfAKind(b_data)) => Ordering::Greater, + (Hand::TwoPair(a_data), Hand::OnePair(b_data)) => Ordering::Less, + (Hand::TwoPair(a_data), Hand::HighCard(b_data)) => Ordering::Less, + + (Hand::OnePair(a_data), Hand::FiveOfAKind(b_data)) => Ordering::Greater, + (Hand::OnePair(a_data), Hand::FourOfAKind(b_data)) => Ordering::Greater, + (Hand::OnePair(a_data), Hand::FullHouse(b_data)) => Ordering::Greater, + (Hand::OnePair(a_data), Hand::ThreeOfAKind(b_data)) => Ordering::Greater, + (Hand::OnePair(a_data), Hand::TwoPair(b_data)) => Ordering::Greater, + (Hand::OnePair(a_data), Hand::HighCard(b_data)) => Ordering::Less, + + (Hand::HighCard(a_data), Hand::FourOfAKind(b_data)) => Ordering::Greater, + (Hand::HighCard(a_data), Hand::FullHouse(b_data)) => Ordering::Greater, + (Hand::HighCard(a_data), Hand::ThreeOfAKind(b_data)) => Ordering::Greater, + (Hand::HighCard(a_data), Hand::TwoPair(b_data)) => Ordering::Greater, + (Hand::HighCard(a_data), Hand::OnePair(b_data)) => Ordering::Greater, + (Hand::HighCard(a_data), Hand::FiveOfAKind(b_data)) => Ordering::Greater, + (_, _) => panic!(), + } +} +*/ + #[test] fn test_solve_01() { let example = r#"32T3K 765 @@ -157,5 +260,5 @@ QQQJA 483"#; let result = solve_02(example).unwrap(); - assert_eq!(5905g, result); + assert_eq!(5905, result); }