diff --git a/2023/day7/src/main.rs b/2023/day7/src/main.rs index 1c0b7c8..0b68661 100644 --- a/2023/day7/src/main.rs +++ b/2023/day7/src/main.rs @@ -1,4 +1,3 @@ -use crate::CardType::Four; use crate::HandType::{ FiveOfAKind, FourOfAKind, FullHouse, HighCard, OnePair, ThreeOfAKind, TwoPair, }; @@ -6,7 +5,7 @@ use std::cmp::Ordering; use std::collections::HashMap; const FILE_STR: &str = include_str!("input.txt"); -const EXAMPLE_FILE_STR: &str = include_str!("example-input.txt"); + #[derive(Clone, Debug, Default, PartialOrd, Ord, PartialEq, Eq, Hash)] #[repr(u8)] enum CardType { @@ -49,9 +48,10 @@ impl From for CardType { } } -#[derive(Debug, Default)] +#[derive(Debug, Default, PartialEq, Eq)] struct Hand { cards: [CardType; 5], + kind: HandType, bet: usize, } @@ -68,12 +68,37 @@ impl Hand { .try_into() .unwrap(); let bet = raw_bet.trim().parse::().unwrap(); + let kind = HandType::from(cards.clone()); - Hand { cards, bet } + Hand { cards, kind, bet } } } -#[derive(Debug, Default, PartialOrd, Ord, PartialEq, Eq)] +impl PartialOrd for Hand { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Hand { + /// Implement the sorting for each hand, first comparing the type of + /// hand, and then comparing the individual cards, if necessary + fn cmp(&self, other: &Self) -> Ordering { + if self.kind != other.kind { + return self.kind.cmp(&other.kind); + } + + for (i, card) in self.cards.iter().enumerate() { + if card != &other.cards[i] { + return card.cmp(&other.cards[i]); + } + } + + Ordering::Equal + } +} + +#[derive(Debug, Default, PartialOrd, Ord, PartialEq, Eq, Copy, Clone)] #[repr(u8)] enum HandType { #[default] @@ -113,13 +138,9 @@ impl From<[CardType; 5]> for HandType { } } -type Rank = u16; -type HandInd = usize; - #[derive(Debug, Default)] struct Game { hands: Vec, - rank: HashMap, } impl Game { @@ -130,19 +151,41 @@ impl Game { .map(Hand::parse) .collect::>(); - Game { - hands, - ..Default::default() - } + Game { hands } + } + + fn get_score_sum(&mut self) -> usize { + // Rank the hands + self.hands.sort_unstable(); + + self.hands.iter().enumerate().fold(0, |prev, curr| { + let (i, hand) = curr; + let rank = i + 1; + + prev + (rank * hand.bet) + }) } } +fn part_one() { + let mut game = Game::parse(FILE_STR); + let score = game.get_score_sum(); + + println!("Part 1: Sum of scores: {}", score); +} + fn main() { - let game = Game::parse(EXAMPLE_FILE_STR); - println!("{:#?}", game); + part_one(); } #[cfg(test)] mod test { + const EXAMPLE_FILE_STR: &str = include_str!("example-input.txt"); use super::*; + + #[test] + fn get_score_sum() { + let mut game = Game::parse(EXAMPLE_FILE_STR); + assert_eq!(6440, game.get_score_sum()); + } }