use std::{fs, cmp::Ordering}; #[derive(PartialEq, Eq, PartialOrd, Ord, Debug)] enum Card { None = 0, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9, Ten = 10, Jack = 11, Queen = 12, King = 13, Ace = 14 } impl Copy for Card {} impl Clone for Card { fn clone(&self) -> Self { *self } } #[derive(PartialEq, Eq, PartialOrd, Ord, Debug)] enum HandType { FiveOfAKind = 6, FourOfAKind = 5, FullHouse = 4, ThreeOfAKind = 3, TwoPair = 2, OnePair = 1, HighCard = 0, } #[derive(Eq, Debug)] struct Hand { bet: u128, hand_type: HandType, cards: Vec, } impl Ord for Hand { fn cmp(&self, other: &Self) -> Ordering { if self.hand_type.ne(&other.hand_type) { return self.hand_type.cmp(&other.hand_type); } if self.cards[0].ne(&other.cards[0]) { return self.cards[0].cmp(&other.cards[0]); } if self.cards[1].ne(&other.cards[1]) { return self.cards[1].cmp(&other.cards[1]); } if self.cards[2].ne(&other.cards[2]) { return self.cards[2].cmp(&other.cards[2]); } if self.cards[3].ne(&other.cards[3]) { return self.cards[3].cmp(&other.cards[3]); } return self.cards[4].cmp(&other.cards[4]); } } impl PartialOrd for Hand { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl PartialEq for Hand { fn eq(&self, other: &Self) -> bool { self.cards == other.cards } } fn main() { let file_path = "input/07input.txt"; let contents = fs::read_to_string(file_path).expect("should read file"); let mut lines = contents.lines(); let mut hands: Vec = Vec::new(); loop { let line = lines.next(); if line.is_none() { break; } let mut line_parts = line.unwrap().split_whitespace(); let hand_cards: Vec = line_parts.next().unwrap().chars().map(|x| match x{ '2' => Card::Two, '3' => Card::Three, '4' => Card::Four, '5' => Card::Five, '6' => Card::Six, '7' => Card::Seven, '8' => Card::Eight, '9' => Card::Nine, 'T' => Card::Ten, 'J' => Card::Jack, 'Q' => Card::Queen, 'K' => Card::King, 'A' => Card::Ace, _ => Card::None, }).collect(); let bet = line_parts.next().unwrap().parse::().ok().unwrap(); let hand = hand_from_cards(bet, hand_cards); let loc_val: usize; match hands.binary_search_by(|probe| probe.cmp(&hand)) { Ok(v) => loc_val = v, Err(v) => loc_val = v, } hands.insert(loc_val, hand); } let mut total_winnings: u128 = 0; for i in 0..hands.len() { total_winnings += hands[i].bet * (i + 1).to_string().parse::().ok().unwrap(); } println!("{}", total_winnings); } fn hand_from_cards(bet: u128, cards: Vec) -> Hand { let hand_type: HandType; if cards[0] == cards[1] && cards[1] == cards[2] && cards[2] == cards[3] && cards[3] == cards[4] { // AAAAA hand_type = HandType::FiveOfAKind; } else if (cards[0] == cards[1] && cards[1] == cards[2] && cards[2] == cards[3]) || // AAAAB (cards[0] == cards[2] && cards[2] == cards[3] && cards[3] == cards[4]) || // ABAAA (cards[0] == cards[1] && cards[1] == cards[3] && cards[3] == cards[4]) || // AABAA (cards[0] == cards[1] && cards[1] == cards[2] && cards[2] == cards[4]) || // AAABA (cards[1] == cards[2] && cards[2] == cards[3] && cards[3] == cards[4]) // BAAAA { hand_type = HandType::FourOfAKind; } else if (cards[0] == cards[1] && cards[1] == cards[2] && cards[3] == cards[4]) || // AAABB (cards[0] == cards[1] && cards[1] == cards[3] && cards[2] == cards[4]) || // AABAB (cards[0] == cards[1] && cards[1] == cards[4] && cards[2] == cards[3]) || // AABBA (cards[0] == cards[2] && cards[2] == cards[3] && cards[1] == cards[4]) || // ABAAB (cards[0] == cards[2] && cards[2] == cards[4] && cards[1] == cards[3]) || // ABABA (cards[0] == cards[3] && cards[3] == cards[4] && cards[1] == cards[2]) || // ABBAA (cards[1] == cards[2] && cards[2] == cards[3] && cards[0] == cards[4]) || // BAAAB (cards[1] == cards[2] && cards[2] == cards[4] && cards[0] == cards[3]) || // BAABA (cards[1] == cards[3] && cards[3] == cards[4] && cards[0] == cards[2]) || // BABAA (cards[2] == cards[3] && cards[3] == cards[4] && cards[0] == cards[1]) // BBAAA { hand_type = HandType::FullHouse; } else if (cards[0] == cards[1] && cards[1] == cards[2]) || // AAABC (cards[0] == cards[1] && cards[1] == cards[3]) || // AABAC (cards[0] == cards[1] && cards[1] == cards[4]) || // AABCA (cards[0] == cards[2] && cards[2] == cards[3]) || // ABAAC (cards[0] == cards[2] && cards[2] == cards[4]) || // ABACA (cards[0] == cards[3] && cards[3] == cards[4]) || // ABCAA (cards[1] == cards[2] && cards[2] == cards[3]) || // BAAAC (cards[1] == cards[2] && cards[2] == cards[4]) || // BAACA (cards[1] == cards[3] && cards[3] == cards[4]) || // BACAA (cards[2] == cards[3] && cards[3] == cards[4]) // BCAAA { hand_type = HandType::ThreeOfAKind; } else if (cards[0] == cards[1] && cards[2] == cards[3]) || // AABBC (cards[0] == cards[1] && cards[2] == cards[4]) || // AABCB (cards[0] == cards[1] && cards[3] == cards[4]) || // AACBB (cards[0] == cards[2] && cards[1] == cards[3]) || // ABABC (cards[0] == cards[2] && cards[1] == cards[4]) || // ABACB (cards[0] == cards[2] && cards[3] == cards[4]) || // ACABB (cards[0] == cards[3] && cards[1] == cards[2]) || // ABBAC (cards[0] == cards[3] && cards[1] == cards[4]) || // ABCAB (cards[0] == cards[3] && cards[2] == cards[4]) || // ACBAB (cards[0] == cards[4] && cards[1] == cards[2]) || // ABBCA (cards[0] == cards[4] && cards[1] == cards[3]) || // ABCBA (cards[0] == cards[4] && cards[2] == cards[3]) || // ACBBA (cards[1] == cards[2] && cards[3] == cards[4]) || // CAABB (cards[1] == cards[3] && cards[2] == cards[4]) || // CABAB (cards[1] == cards[4] && cards[2] == cards[3]) // CABBA { hand_type = HandType::TwoPair; } else if cards[0] == cards[1] || // AABCD cards[0] == cards[2] || // ABACD cards[0] == cards[3] || // ABCAD cards[0] == cards[4] || // ABCDA cards[1] == cards[2] || // BAACD cards[1] == cards[3] || // BACAD cards[1] == cards[4] || // BACDA cards[2] == cards[3] || // BCAAD cards[2] == cards[4] || // BCADA cards[3] == cards[4] // BCDAA { hand_type = HandType::OnePair; } else { // ABCDE hand_type = HandType::HighCard; } return Hand {bet, hand_type, cards}; }