144 lines
3.7 KiB
Rust
144 lines
3.7 KiB
Rust
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<char> 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<Card>,
|
|
bid: u32,
|
|
hand_type: HandType
|
|
}
|
|
|
|
fn parse_input(input: &str) -> Vec<Hand> {
|
|
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
|
|
}
|