diff --git a/src/days/day7.rs b/src/days/day7.rs index 5fa1f10..d9b9cf4 100644 --- a/src/days/day7.rs +++ b/src/days/day7.rs @@ -2,7 +2,8 @@ use std::{path::Path, str::FromStr}; use itertools::Itertools; -use::std::hash::Hash; +use std::hash::Hash; +use std::fmt::Debug; use crate::{error::AdventError, input::read_into_vec}; @@ -17,6 +18,7 @@ enum CardTwo { trait Card { fn strength(self: &Self) -> u32; + fn get_card(self: &Self) -> char; } impl Hash for dyn Card { @@ -66,6 +68,10 @@ impl Card for CardOne { _ => panic!("Invalid card found") } } + + fn get_card(self: &Self) -> char { + self.0 + } } impl Card for CardTwo { @@ -89,9 +95,16 @@ impl Card for CardTwo { 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 { None, HighCard, @@ -116,6 +129,12 @@ struct HandTwo { cards: [Box;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 { fn new() -> Self { Self { @@ -133,18 +152,77 @@ impl HandTwo { impl Hand for HandTwo { 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 { - todo!() + &self.hand_type } fn get_cards(&self) -> &[Box;5] { - todo!() + &self.cards } } + trait Hand { fn determine_type(&mut self) -> (); @@ -264,12 +342,19 @@ struct LineOne { bid: u32, } -#[derive(Eq)] +#[derive(Eq, Debug)] struct LineTwo { hand: Box, 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 { fn eq(&self, other: &Self) -> bool { self.hand.as_ref() == other.hand.as_ref() @@ -347,5 +432,7 @@ pub fn one() -> Result { pub fn two() -> Result { let mut lines = read_into_vec::(Path::new("resources/input7.txt".into()))?; lines.sort(); - Ok(0) + Ok(lines.iter().enumerate().fold(0, |acc, (rank, hand)| { + acc + (rank as u32 + 1) * hand.bid + })) } \ No newline at end of file