pub fn task_one(input: &str) -> String { let mut hands = parse_input(&input); hands.sort_by_key(|hand| hand.hand_type); loop { let mut swap_occured = false; for i in 0..(hands.len() - 1) { let current_element = hands[i].clone(); let next_element = &hands[i + 1].clone(); if current_element.hand_type != next_element.hand_type { continue; } for j in 0..5 { match current_element.cards[j].cmp(&next_element.cards[j]) { std::cmp::Ordering::Greater => { hands.swap(i, i + 1); swap_occured = true; break; }, std::cmp::Ordering::Equal => continue, std::cmp::Ordering::Less => break } } } if !swap_occured { break; } } hands.iter() .enumerate() .fold(0, |sum, (rank, hand)| sum + ((rank + 1) * hand.bid as usize)) .to_string() } pub fn task_two(input: &str) -> String { let mut product = 1_u64; product.to_string() } #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] enum HandType { FiveOfAKind = 6, FourOfAKind = 5, FullHouse = 4, ThreeOfAKind = 3, TwoPair = 2, OnePair = 1, HighCard = 0 } #[derive(PartialEq, Eq, PartialOrd, Ord, Clone)] enum Card { Ass = 14, King = 13, Queen = 12, Junior = 11, Ten = 10, Nine = 9, Eight = 8, Seven = 7, Six = 6, Five = 5, Four = 4, Three = 3, Two = 2 } impl From for Card { fn from(value: char) -> Self { match value { 'A' => Card::Ass, 'K' => Card::King, 'Q' => Card::Queen, 'J' => Card::Junior, 'T' => Card::Ten, '9' => Card::Nine, '8' => Card::Eight, '7' => Card::Seven, '6' => Card::Six, '5' => Card::Five, '4' => Card::Four, '3' => Card::Three, '2' => Card::Two, _ => panic!("Found {}", value) } } } #[derive(Clone)] struct Hand { cards: Vec, bid: u32, hand_type: HandType } fn parse_input(input: &str) -> Vec { let mut hands = Vec::new(); for line in input.lines() { let (cards, bid_string) = line.split_once(" ").unwrap(); let mut hand_type = HandType::HighCard; let pairs = count_cards(cards); if pairs.iter().find(|pair| pair.1 == 5).is_some() { hand_type = HandType::FiveOfAKind; } else if pairs.iter().find(|pair| pair.1 == 4).is_some() { hand_type = HandType::FourOfAKind; } else if pairs.iter().find(|pair| pair.1 == 3).is_some() && pairs.iter().find(|pair| pair.1 == 2).is_some() { hand_type = HandType::FullHouse; } else if pairs.iter().find(|pair| pair.1 == 3).is_some() { hand_type = HandType::ThreeOfAKind; } else if pairs.iter().filter(|pair| pair.1 == 2).count() == 2 { hand_type = HandType::TwoPair; } else if pairs.iter().filter(|pair| pair.1 == 2).count() == 1 { hand_type = HandType::OnePair; } hands.push(Hand { cards: cards.chars().into_iter().map(|c| c.into()).collect(), bid: bid_string.parse().unwrap(), hand_type }) } hands } fn count_cards(input: &str) -> Vec<(char, u8)> { let mut result: Vec<(char, u8)> = Vec::new(); for char in input.chars() { if let Some(entry) = result.iter_mut().find(|pair| pair.0 == char) { entry.1 += 1; } else { result.push((char, 1)); } } result }