#![feature(iter_array_chunks)] use std::collections::BTreeMap; static INPUT: &str = include_str!("input.txt"); static MAPPING1: &[u8] = &[ 0, b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'T', b'J', b'Q', b'K', b'A' ]; static MAPPING2: &[u8] = &[ 0, b'J', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'T', b'Q', b'K', b'A' ]; #[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Copy, Clone)] enum Hand { HighCard = 0, OnePair, TwoPair, ThreeOfAKind, FullHouse, FourOfAKind, FiveOfAKind } fn from_analyzer(analyzer: &BTreeMap) -> Hand { match analyzer.len() { 1 => Hand::FiveOfAKind, 2 if analyzer.values().any(|a| *a == 4) => Hand::FourOfAKind, 2 => Hand::FullHouse, 3 if analyzer.values().any(|a| *a == 3) => Hand::ThreeOfAKind, 3 => Hand::TwoPair, 4 => Hand::OnePair, 5 => Hand::HighCard, _ => unreachable!() } } fn main() { let valueified_1 = INPUT.split_ascii_whitespace().array_chunks::<2>().map(|[hand, bid]| { let bid = bid.parse::().unwrap(); let mut analyzer = BTreeMap::new(); for c in hand.bytes() { *analyzer.entry(c).or_insert(0) += 1; } let handtype = from_analyzer(&analyzer); ((handtype, hand.bytes().map(|b| MAPPING1.iter().position(|i| *i == b).unwrap()).collect::>()), bid) }); let total_winnings = valueified_1.collect::>().into_iter().enumerate().map(|(n, (_, b))| (n + 1) as u32 * b).sum::(); println!("Total Winnings: {total_winnings}"); let mut valueified_2 = INPUT.split_ascii_whitespace().array_chunks::<2>().map(|[hand, bid]| { let bid = bid.parse::().unwrap(); let mut analyzer = BTreeMap::new(); for c in hand.bytes() { *analyzer.entry(c).or_insert(0) += 1; } let mut hand = hand.bytes().collect::>(); if analyzer.contains_key(&b'J') { let (hichar, _) = analyzer.iter().fold((0, 0), |(a, b), (c, n)| if *n > b && *c != b'J' { (*c, *n) } else { (a, b) }); if hichar != 0 { *analyzer.get_mut(&hichar).unwrap() += analyzer[&b'J']; analyzer.remove(&b'J'); } } let handtype = from_analyzer(&analyzer); for c in &mut hand { *c = MAPPING2.iter().position(|i| *i == *c).unwrap() as u8 } ((handtype, hand), bid) }).collect::>(); valueified_2.sort_by(|a, b| a.0.cmp(&b.0)); let total_winnings = valueified_2.into_iter().enumerate().map(|(n, (_, b))| (n + 1) as u32 * b).sum::(); println!("Total Winnings 2: {total_winnings}"); }