Day7 Rust

This commit is contained in:
dobiadi
2023-12-09 14:57:28 +01:00
parent 14d18f6814
commit 71727f812d
4 changed files with 275 additions and 0 deletions

1
day7/rust/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
target

7
day7/rust/Cargo.lock generated Normal file
View File

@@ -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"

8
day7/rust/Cargo.toml Normal file
View File

@@ -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]

259
day7/rust/src/main.rs Normal file
View File

@@ -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<char>,
bid: usize,
r#type: Option<HandType>,
}
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);
}