Day7 Rust
This commit is contained in:
1
day7/rust/.gitignore
vendored
Normal file
1
day7/rust/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
target
|
||||
7
day7/rust/Cargo.lock
generated
Normal file
7
day7/rust/Cargo.lock
generated
Normal 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
8
day7/rust/Cargo.toml
Normal 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
259
day7/rust/src/main.rs
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user