feat: implement day 7 part 2

This commit is contained in:
Lennard Brinkhaus 2023-12-07 19:36:44 +01:00
parent e09005bb83
commit faad5beb77

View File

@ -1,3 +1,4 @@
use std::cmp::Ordering;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::panic::panic_any; use std::panic::panic_any;
@ -19,9 +20,12 @@ pub enum Card {
N5 = 11, N5 = 11,
N4 = 12, N4 = 12,
N3 = 13, N3 = 13,
N2 = 14 N2 = 14,
JOKER_2 = 15,
} }
impl From<char> for Card { impl From<char> for Card {
fn from(value: char) -> Self { fn from(value: char) -> Self {
match value { match value {
@ -67,17 +71,32 @@ impl From<Vec<Card>> for Hand {
*cards.entry(c.to_string()).or_insert(0) += 1; *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() { match cards.values().len() {
1 => Hand::FiveOfAKind(value), // can only be five of a kind 1 => Hand::FiveOfAKind(value), // can only be five of a kind
2 => { // Can be four of a kind or Full house 2 => { // Can be four of a kind or Full house
if *cards.values().sorted().rev().collect::<Vec<&usize>>()[0] == 4 { if *cards.values().max().unwrap() == 4 {
Hand::FourOfAKind(value) Hand::FourOfAKind(value)
} else { } else {
Hand::FullHouse(value) Hand::FullHouse(value)
} }
}, },
3 => { // Can be two pairs or three of a kind 3 => { // Can be two pairs or three of a kind
if *cards.values().sorted().rev().collect::<Vec<&usize>>()[0] == 3 { if *cards.values().max().unwrap() == 3 {
Hand::ThreeOfAKind(value) Hand::ThreeOfAKind(value)
} else { } else {
Hand::TwoPair(value) Hand::TwoPair(value)
@ -104,7 +123,7 @@ pub fn execute_task02(content: &str) {
let product_correct_races = solve_02(content).unwrap(); let product_correct_races = solve_02(content).unwrap();
let duration = start.elapsed(); 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) println!("Day07 - Task02 - Duration: {duration:?} - Correct Race (with Joker): {}", product_correct_races)
} }
@ -121,11 +140,18 @@ fn solve_01(content: &str) -> anyhow::Result<usize> {
.sum()) .sum())
} }
fn solve_02(content: &str) -> anyhow::Result<i64> { fn solve_02(content: &str) -> anyhow::Result<usize> {
Ok(content Ok(content
.lines() .lines()
.map(|line| line.split_once(" ").unwrap()) .map(|line| line.split_once(" ").unwrap())
.map(|(hand, bid)| (hand.chars().map(|c| Card::from(c)).collect::<Vec<Card>>(), bid.parse::<usize>().unwrap())) .map(|(hand, bid)| (hand.chars().map(|c| {
let mut c = Card::from(c);
if c == Card::J {
c = Card::JOKER_2;
}
c
}).collect::<Vec<Card>>(), bid.parse::<usize>().unwrap()))
.map(|(hand, bid)| (Hand::from(hand), bid)) .map(|(hand, bid)| (Hand::from(hand), bid))
.sorted_by(|(hand, _), (second_hand, _)| Ord::cmp(hand, second_hand)) .sorted_by(|(hand, _), (second_hand, _)| Ord::cmp(hand, second_hand))
.rev() .rev()
@ -134,6 +160,83 @@ fn solve_02(content: &str) -> anyhow::Result<i64> {
.sum()) .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] #[test]
fn test_solve_01() { fn test_solve_01() {
let example = r#"32T3K 765 let example = r#"32T3K 765
@ -157,5 +260,5 @@ QQQJA 483"#;
let result = solve_02(example).unwrap(); let result = solve_02(example).unwrap();
assert_eq!(5905g, result); assert_eq!(5905, result);
} }