2023-advent-of-code/src/07part1.rs

197 lines
7.0 KiB
Rust
Raw Normal View History

2023-12-07 21:42:34 +01:00
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};
}