Fixes Day 7 part 2.

This commit is contained in:
Dennis Brentjes 2023-12-11 10:10:50 +01:00
parent cacc884cf1
commit 3b529af1d6

View File

@ -2,7 +2,8 @@ use std::{path::Path, str::FromStr};
use itertools::Itertools; use itertools::Itertools;
use::std::hash::Hash; use std::hash::Hash;
use std::fmt::Debug;
use crate::{error::AdventError, input::read_into_vec}; use crate::{error::AdventError, input::read_into_vec};
@ -17,6 +18,7 @@ enum CardTwo {
trait Card { trait Card {
fn strength(self: &Self) -> u32; fn strength(self: &Self) -> u32;
fn get_card(self: &Self) -> char;
} }
impl Hash for dyn Card { impl Hash for dyn Card {
@ -66,6 +68,10 @@ impl Card for CardOne {
_ => panic!("Invalid card found") _ => panic!("Invalid card found")
} }
} }
fn get_card(self: &Self) -> char {
self.0
}
} }
impl Card for CardTwo { impl Card for CardTwo {
@ -89,9 +95,16 @@ impl Card for CardTwo {
Self::Joker => 1 Self::Joker => 1
} }
} }
fn get_card(self: &Self) -> char {
match self {
CardTwo::Card(c) => *c,
CardTwo::Joker => 'J'
}
}
} }
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
enum HandType { enum HandType {
None, None,
HighCard, HighCard,
@ -116,6 +129,12 @@ struct HandTwo {
cards: [Box<dyn Card>;5] cards: [Box<dyn Card>;5]
} }
impl Debug for dyn Card {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Ok(f.write_str(&self.get_card().to_string())?)
}
}
impl HandTwo { impl HandTwo {
fn new() -> Self { fn new() -> Self {
Self { Self {
@ -133,18 +152,77 @@ impl HandTwo {
impl Hand for HandTwo { impl Hand for HandTwo {
fn determine_type(&mut self) -> () { fn determine_type(&mut self) -> () {
todo!() let counts = self.cards.iter().map(|c| {c.get_card()}).counts();
let joker_counts = match counts.get_key_value(&'J') {
Some((_, c)) => *c,
None => 0
};
let value_counts = counts.iter().map(|c| { c.1 }).collect_vec();
self.hand_type = match (counts.len(), value_counts) {
(5, _) => match joker_counts {
0 => HandType::HighCard,
1 => HandType::OnePair,
2 => HandType::ThreeOfAKind,
3 => HandType::FourOfAKind,
4 => HandType::FiveOfAKind,
_ => panic!("Should not happen")
},
(4, _) => match joker_counts {
0 => HandType::OnePair,
1 => HandType::ThreeOfAKind,
2 => HandType::ThreeOfAKind,
_ => panic!("Should not happen")
},
(3, c) => {
if c.contains(&&3) {
match joker_counts {
0 => HandType::ThreeOfAKind,
1 => HandType::FourOfAKind,
3 => HandType::FourOfAKind,
_ => panic!("Should not happen")
}
} else {
match joker_counts {
0 => HandType::TwoPair,
1 => HandType::FullHouse,
2 => HandType::FourOfAKind,
_ => panic!("Should not happen")
}
}
}
(2, c) => {
if c.contains(&&4) {
match joker_counts {
0 => HandType::FourOfAKind,
1 => HandType::FiveOfAKind,
4 => HandType::FiveOfAKind,
_ => panic!("Should not happen")
}
} else {
match joker_counts {
0 => HandType::FullHouse,
2 => HandType::FiveOfAKind,
3 => HandType::FiveOfAKind,
_ => panic!("Should not happen")
}
}
}
(1, _) => HandType::FiveOfAKind,
(_, _) => panic!("Hand type match should never fail")
};
} }
fn get_hand_type(&self) -> &HandType { fn get_hand_type(&self) -> &HandType {
todo!() &self.hand_type
} }
fn get_cards(&self) -> &[Box<dyn Card>;5] { fn get_cards(&self) -> &[Box<dyn Card>;5] {
todo!() &self.cards
} }
} }
trait Hand { trait Hand {
fn determine_type(&mut self) -> (); fn determine_type(&mut self) -> ();
@ -264,12 +342,19 @@ struct LineOne {
bid: u32, bid: u32,
} }
#[derive(Eq)] #[derive(Eq, Debug)]
struct LineTwo { struct LineTwo {
hand: Box<dyn Hand>, hand: Box<dyn Hand>,
bid: u32, bid: u32,
} }
impl Debug for dyn Hand {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.get_hand_type().fmt(f)?;
Ok(self.get_cards().fmt(f)?)
}
}
impl PartialEq for LineOne { impl PartialEq for LineOne {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.hand.as_ref() == other.hand.as_ref() self.hand.as_ref() == other.hand.as_ref()
@ -347,5 +432,7 @@ pub fn one() -> Result<u32, AdventError> {
pub fn two() -> Result<u32, AdventError> { pub fn two() -> Result<u32, AdventError> {
let mut lines = read_into_vec::<LineTwo>(Path::new("resources/input7.txt".into()))?; let mut lines = read_into_vec::<LineTwo>(Path::new("resources/input7.txt".into()))?;
lines.sort(); lines.sort();
Ok(0) Ok(lines.iter().enumerate().fold(0, |acc, (rank, hand)| {
acc + (rank as u32 + 1) * hand.bid
}))
} }