From 91a90afb677196c2119d92a02c9be18f1baeba5c Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Thu, 14 Dec 2023 16:28:31 -0500 Subject: [PATCH] More work on 2023 day7 part 1 --- 2023/day7/src/main.rs | 144 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 140 insertions(+), 4 deletions(-) diff --git a/2023/day7/src/main.rs b/2023/day7/src/main.rs index 37d81ec..1c0b7c8 100644 --- a/2023/day7/src/main.rs +++ b/2023/day7/src/main.rs @@ -1,12 +1,148 @@ +use crate::CardType::Four; +use crate::HandType::{ + FiveOfAKind, FourOfAKind, FullHouse, HighCard, OnePair, ThreeOfAKind, TwoPair, +}; +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 { + #[default] + Two = 0, + Three, + Four, + Five, + Six, + Seven, + Eight, + Nine, + Joker, + Jack, + Queen, + King, + Ace, +} + +impl From for CardType { + fn from(value: char) -> Self { + use CardType::*; + + match value { + '2' => Two, + '3' => Three, + '4' => Four, + '5' => Five, + '6' => Six, + '7' => Seven, + '8' => Eight, + '9' => Nine, + 'T' => Joker, + 'J' => Jack, + 'Q' => Queen, + 'K' => King, + 'A' => Ace, + _ => panic!("Invalid card character"), + } + } +} + +#[derive(Debug, Default)] +struct Hand { + cards: [CardType; 5], + bet: usize, +} + +impl Hand { + fn parse(line: &str) -> Self { + let mut parts = line.split_whitespace(); + let raw_hand = parts.next().unwrap(); + let raw_bet = parts.next().unwrap(); + let cards: [CardType; 5] = raw_hand + .trim() + .chars() + .map(CardType::from) + .collect::>() + .try_into() + .unwrap(); + let bet = raw_bet.trim().parse::().unwrap(); + + Hand { cards, bet } + } +} + +#[derive(Debug, Default, PartialOrd, Ord, PartialEq, Eq)] +#[repr(u8)] +enum HandType { + #[default] + HighCard = 0, + OnePair, + TwoPair, + ThreeOfAKind, + FullHouse, + FourOfAKind, + FiveOfAKind, +} + +impl From<[CardType; 5]> for HandType { + fn from(value: [CardType; 5]) -> Self { + let mut cards = Vec::from(value); + cards.sort_unstable(); + + let mut count_map: HashMap = HashMap::new(); + cards.into_iter().for_each(|ct| { + match count_map.get(&ct) { + Some(count) => count_map.insert(ct, *count + 1), + None => count_map.insert(ct, 1), + }; + }); + let mut card_type_counts: Vec = count_map.into_values().collect(); + card_type_counts.sort_unstable(); + + match card_type_counts[..] { + [5] => FiveOfAKind, + [1, 4] => FourOfAKind, + [2, 3] => FullHouse, + [1, 1, 3] => ThreeOfAKind, + [1, 2, 2] => TwoPair, + [1, 1, 1, 2] => OnePair, + _ => HighCard, + } + } +} + +type Rank = u16; +type HandInd = usize; + +#[derive(Debug, Default)] +struct Game { + hands: Vec, + rank: HashMap, +} + +impl Game { + fn parse(input: &str) -> Self { + let hands = input + .split('\n') + .filter(|s| !s.is_empty()) + .map(Hand::parse) + .collect::>(); + + Game { + hands, + ..Default::default() + } + } +} fn main() { - println!("Hello, world!"); + let game = Game::parse(EXAMPLE_FILE_STR); + println!("{:#?}", game); } #[cfg(test)] mod test { - const EXAMPLE_FILE_STR: &str = include_str!("example-input.txt"); - use super::*; -} \ No newline at end of file +}