From 71727f812d438b2ab43e0b250639cf505e258bde Mon Sep 17 00:00:00 2001 From: dobiadi Date: Sat, 9 Dec 2023 14:57:28 +0100 Subject: [PATCH] Day7 Rust --- day7/rust/.gitignore | 1 + day7/rust/Cargo.lock | 7 ++ day7/rust/Cargo.toml | 8 ++ day7/rust/src/main.rs | 259 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 275 insertions(+) create mode 100644 day7/rust/.gitignore create mode 100644 day7/rust/Cargo.lock create mode 100644 day7/rust/Cargo.toml create mode 100644 day7/rust/src/main.rs diff --git a/day7/rust/.gitignore b/day7/rust/.gitignore new file mode 100644 index 0000000..eb5a316 --- /dev/null +++ b/day7/rust/.gitignore @@ -0,0 +1 @@ +target diff --git a/day7/rust/Cargo.lock b/day7/rust/Cargo.lock new file mode 100644 index 0000000..b21cc6a --- /dev/null +++ b/day7/rust/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "rust" +version = "0.1.0" diff --git a/day7/rust/Cargo.toml b/day7/rust/Cargo.toml new file mode 100644 index 0000000..1ec6963 --- /dev/null +++ b/day7/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day7/rust/src/main.rs b/day7/rust/src/main.rs new file mode 100644 index 0000000..e4870e2 --- /dev/null +++ b/day7/rust/src/main.rs @@ -0,0 +1,259 @@ +use std::cmp::Ordering; + +#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord)] +enum HandType { + FiveOfAKind, + FourOfAKind, + FullHouse, + ThreeOfAKind, + TwoPair, + OnePair, + HighCard, +} + +#[derive(Debug)] +struct Hand { + cards: Vec, + bid: usize, + r#type: Option, +} + +static CARD_ORDER: &[char] = &[ + 'A', 'K', 'Q', 'J', 'T', '9', '8', '7', '6', '5', '4', '3', '2', +]; + +static CARD_ORDER2: &[char] = &[ + 'A', 'K', 'Q', 'T', '9', '8', '7', '6', '5', '4', '3', '2', 'J', +]; + +impl Hand { + fn get_type(&self, allow_joker: bool) -> HandType { + // Five of a kind + for card in &self.cards { + let mut good = 0; + + for card2 in &self.cards { + if *card == *card2 || (allow_joker && *card2 == 'J') { + good += 1; + } + } + + if good == 5 { + return HandType::FiveOfAKind; + } + } + + // Four of a kind + for card in &self.cards { + let mut good = 0; + + for card2 in &self.cards { + if *card == *card2 || (allow_joker && *card2 == 'J') { + good += 1; + } + } + + if good == 4 { + return HandType::FourOfAKind; + } + } + + // Full house + for card in &self.cards { + for card2 in &self.cards { + let mut good = 0; + let mut good2 = 0; + + let mut used_jokers = vec![false; 5]; + + for (i, card3) in self.cards.iter().enumerate() { + if *card == *card3 || (allow_joker && *card3 == 'J') { + good += 1; + if allow_joker && *card3 == 'J' { + used_jokers[i] = true; + } + } + } + for (i, card4) in self.cards.iter().enumerate() { + if *card2 == *card4 || (allow_joker && !used_jokers[i] && *card4 == 'J') { + good2 += 1; + } + } + + if ((good == 3 && good2 == 2) || (good == 2 && good2 == 3)) + && *card != *card2 + && (!allow_joker || (allow_joker && *card != 'J' && *card2 != 'J')) + { + return HandType::FullHouse; + } + } + } + + // Three of a kind + for card in &self.cards { + let mut good = 0; + + for card2 in &self.cards { + if *card == *card2 || (allow_joker && *card2 == 'J') { + good += 1; + } + } + + if good == 3 { + return HandType::ThreeOfAKind; + } + } + + // Two pair + for card in &self.cards { + for card2 in &self.cards { + let mut good = 0; + let mut good2 = 0; + + let mut used_jokers = vec![false; 5]; + + for (i, card3) in self.cards.iter().enumerate() { + if *card == *card3 || (allow_joker && *card3 == 'J') { + good += 1; + if allow_joker && *card3 == 'J' { + used_jokers[i] = true; + } + } + } + for (i, card4) in self.cards.iter().enumerate() { + if *card2 == *card4 || (allow_joker && !used_jokers[i] && *card4 == 'J') { + good2 += 1; + } + } + + if ((good == 2 && good2 == 2) || (good == 2 && good2 == 2)) && card != card2 { + return HandType::TwoPair; + } + } + } + + // One pair + for card in &self.cards { + let mut good = 0; + + for card2 in &self.cards { + if *card == *card2 || (allow_joker && *card2 == 'J') { + good += 1; + } + } + + if good == 2 { + return HandType::OnePair; + } + } + + HandType::HighCard + } +} + +fn main() { + let stdin = std::io::stdin(); + + let mut hands = Vec::new(); + + for line in stdin.lines() { + let line = line.unwrap(); + + let (cards, bid) = line.split_once(" ").unwrap(); + + let cards = cards.chars().collect(); + let bid = bid.parse().unwrap(); + + hands.push(Hand { + cards, + bid, + r#type: None, + }) + } + + // Part1 + let mut part1 = 0; + + for hand in &mut hands { + hand.r#type = Some(hand.get_type(false)); + } + + hands.sort_by(cmp); + + for (i, hand) in hands.iter().enumerate() { + part1 += (i + 1) * hand.bid; + } + + println!("{}", part1); + + // Part2 + let mut part2 = 0; + + for hand in &mut hands { + hand.r#type = Some(hand.get_type(true)); + } + + hands.sort_by(cmp2); + + for (i, hand) in hands.iter().enumerate() { + part2 += (i + 1) * hand.bid; + } + + println!("{}", part2); +} + +fn cmp(hand1: &Hand, hand2: &Hand) -> Ordering { + if hand1.r#type.unwrap() == hand2.r#type.unwrap() { + for (card1, card2) in hand1.cards.iter().zip(hand2.cards.iter()) { + let mut card1_idx = 0; + let mut card2_idx = 0; + + for i in 0..CARD_ORDER.len() { + if CARD_ORDER[i] == *card1 { + card1_idx = i; + } + } + for i in 0..CARD_ORDER.len() { + if CARD_ORDER[i] == *card2 { + card2_idx = i; + } + } + + if card1_idx == card2_idx { + continue; + } + + return card2_idx.cmp(&card1_idx); + } + } + + return hand2.r#type.cmp(&hand1.r#type); +} + +fn cmp2(hand1: &Hand, hand2: &Hand) -> Ordering { + if hand1.r#type.unwrap() == hand2.r#type.unwrap() { + for (card1, card2) in hand1.cards.iter().zip(hand2.cards.iter()) { + let mut card1_idx = 0; + let mut card2_idx = 0; + + for i in 0..CARD_ORDER2.len() { + if CARD_ORDER2[i] == *card1 { + card1_idx = i; + } + } + for i in 0..CARD_ORDER2.len() { + if CARD_ORDER2[i] == *card2 { + card2_idx = i; + } + } + + if card1_idx == card2_idx { + continue; + } + + return card2_idx.cmp(&card1_idx); + } + } + + return hand2.r#type.cmp(&hand1.r#type); +}