This commit is contained in:
Niklas Kapelle 2023-12-18 18:07:22 +01:00
parent 6334f8f0a8
commit 8b4524912f
Signed by: niklas
GPG Key ID: 4EB651B36D841D16
3 changed files with 1196 additions and 0 deletions

1000
input/7.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@ mod three;
mod four;
mod five;
mod six;
mod seven;
fn main() {
let args: Vec<String> = env::args().collect();
@ -25,6 +26,7 @@ fn main() {
"5p2" => five::run_part2(),
"6" => six::run(),
"6p2" => six::run_part2(),
"7" => seven::run(),
_ => Ok(-1),
};

194
src/seven.rs Normal file
View File

@ -0,0 +1,194 @@
use std::{cmp::Ordering, collections::HashMap};
use crate::common::load_input;
//
// Card
//
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Copy, Clone, Debug)]
enum Card {
A = 14,
K = 13,
Q = 12,
J = 11,
T = 10,
N9 = 9,
N8 = 8,
N7 = 7,
N6 = 6,
N5 = 5,
N4 = 4,
N3 = 3,
N2 = 2,
}
impl TryFrom<char> for Card {
type Error = &'static str;
fn try_from(value: char) -> Result<Self, Self::Error> {
match value {
'A' => Ok(Card::A),
'K' => Ok(Card::K),
'Q' => Ok(Card::Q),
'J' => Ok(Card::J),
'T' => Ok(Card::T),
'9' => Ok(Card::N9),
'8' => Ok(Card::N8),
'7' => Ok(Card::N7),
'6' => Ok(Card::N6),
'5' => Ok(Card::N5),
'4' => Ok(Card::N4),
'3' => Ok(Card::N3),
'2' => Ok(Card::N2),
_ => Err("Not a card"),
}
}
}
//
// Hand Value
//
#[derive(PartialEq, PartialOrd, Ord,Eq, Hash, Copy, Clone, Debug)]
enum HandValue {
FiveOfKind = 6,
FourOfKind = 5,
FullHouse = 4,
ThreeOfKind = 3,
TwoPair = 2,
OnePair = 1,
HighCard = 0,
}
//
// Hand
//
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
struct Hand {
cards: [Card; 5],
}
impl TryFrom<&str> for Hand {
type Error = &'static str;
fn try_from(value: &str) -> Result<Self, Self::Error> {
let cards: Vec<_> = value.chars().map(|e| Card::try_from(e)).collect();
if !cards.iter().all(|e| e.is_ok()) {
return Err("Invalid char");
}
if cards.iter().count() != 5 {
return Err("To many cards");
}
let arr: [Card; 5] = [
cards.get(0).unwrap().unwrap(),
cards.get(1).unwrap().unwrap(),
cards.get(2).unwrap().unwrap(),
cards.get(3).unwrap().unwrap(),
cards.get(4).unwrap().unwrap(),
];
return Ok(Hand { cards: arr });
}
}
impl Hand {
fn get_hand_value(&self) -> HandValue {
let groups = self.get_card_cout();
// Check Five of a kind
if groups.iter().any(|e| *e.1 == 5) {
return HandValue::FiveOfKind;
}
// Check for Four of a kind
if groups.iter().any(|e| *e.1 == 4) {
return HandValue::FourOfKind;
}
//Check full house
if groups.iter().any(|e| *e.1 == 3) && groups.iter().any(|e| *e.1 == 2) {
return HandValue::FullHouse;
}
// Check for Three of a kind
if groups.iter().any(|e| *e.1 == 3) {
return HandValue::ThreeOfKind;
}
// Check for 1 and 2 Pairs
let pairs = groups.iter().filter(|e| *e.1 == 2).count();
if pairs == 2 {
return HandValue::TwoPair;
}
if pairs == 1 {
return HandValue::OnePair;
}
return HandValue::HighCard;
}
fn get_card_cout(&self) -> HashMap<Card, u8> {
let mut rtn = HashMap::new();
self.cards.iter().for_each(|e| {
match rtn.get(e) {
None => rtn.insert(*e, 1u8),
Some(v) => rtn.insert(*e, v + 1u8),
};
});
return rtn;
}
}
impl PartialOrd for Hand {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(&other))
}
}
impl Ord for Hand {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
let self_hand_value = self.get_hand_value();
let other_hand_value = other.get_hand_value();
if self_hand_value != other_hand_value {
return self_hand_value.cmp(&other_hand_value);
}
// Compare the cards
for (self_card, other_card) in self.cards.iter().zip(other.cards.iter()) {
if self_card != other_card {
return self_card.cmp(other_card);
}
}
return Ordering::Equal;
}
}
//
// Everything else
//
fn parse_input(lines: &[String]) -> Vec<(Hand, u64)> {
lines
.iter()
.map(|e| e.split_once(" ").unwrap())
.map(|e| (Hand::try_from(e.0).unwrap(), e.1.parse::<u64>().unwrap()))
.collect()
}
pub fn run() -> Result<i32, Box<dyn std::error::Error>> {
let lines = load_input("./input/7.txt")?;
let hands = parse_input(&lines);
let mut orderd_hands = hands.clone();
orderd_hands.sort_by_key(|e| e.0);
let score: u64 = orderd_hands.iter().enumerate().map(|e| (e.0 + 1) as u64 * (e.1.1)).sum();
Ok(score as i32)
}