197 lines
7.0 KiB
Rust
197 lines
7.0 KiB
Rust
|
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<Card>,
|
||
|
}
|
||
|
|
||
|
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<Ordering> {
|
||
|
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<Hand> = Vec::new();
|
||
|
loop {
|
||
|
let line = lines.next();
|
||
|
if line.is_none() {
|
||
|
break;
|
||
|
}
|
||
|
let mut line_parts = line.unwrap().split_whitespace();
|
||
|
let hand_cards: Vec<Card> = 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::<u128>().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::<u128>().ok().unwrap();
|
||
|
}
|
||
|
println!("{}", total_winnings);
|
||
|
}
|
||
|
|
||
|
fn hand_from_cards(bet: u128, cards: Vec<Card>) -> 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};
|
||
|
}
|