Complete 2023 day7 part 1

This commit is contained in:
Timothy Warren 2023-12-15 13:49:10 -05:00
parent 91a90afb67
commit e1b0ca6d2e

View File

@ -1,4 +1,3 @@
use crate::CardType::Four;
use crate::HandType::{
FiveOfAKind, FourOfAKind, FullHouse, HighCard, OnePair, ThreeOfAKind, TwoPair,
};
@ -6,7 +5,7 @@ use std::cmp::Ordering;
use std::collections::HashMap;
const FILE_STR: &str = include_str!("input.txt");
const EXAMPLE_FILE_STR: &str = include_str!("example-input.txt");
#[derive(Clone, Debug, Default, PartialOrd, Ord, PartialEq, Eq, Hash)]
#[repr(u8)]
enum CardType {
@ -49,9 +48,10 @@ impl From<char> for CardType {
}
}
#[derive(Debug, Default)]
#[derive(Debug, Default, PartialEq, Eq)]
struct Hand {
cards: [CardType; 5],
kind: HandType,
bet: usize,
}
@ -68,12 +68,37 @@ impl Hand {
.try_into()
.unwrap();
let bet = raw_bet.trim().parse::<usize>().unwrap();
let kind = HandType::from(cards.clone());
Hand { cards, bet }
Hand { cards, kind, bet }
}
}
#[derive(Debug, Default, PartialOrd, Ord, PartialEq, Eq)]
impl PartialOrd for Hand {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Hand {
/// Implement the sorting for each hand, first comparing the type of
/// hand, and then comparing the individual cards, if necessary
fn cmp(&self, other: &Self) -> Ordering {
if self.kind != other.kind {
return self.kind.cmp(&other.kind);
}
for (i, card) in self.cards.iter().enumerate() {
if card != &other.cards[i] {
return card.cmp(&other.cards[i]);
}
}
Ordering::Equal
}
}
#[derive(Debug, Default, PartialOrd, Ord, PartialEq, Eq, Copy, Clone)]
#[repr(u8)]
enum HandType {
#[default]
@ -113,13 +138,9 @@ impl From<[CardType; 5]> for HandType {
}
}
type Rank = u16;
type HandInd = usize;
#[derive(Debug, Default)]
struct Game {
hands: Vec<Hand>,
rank: HashMap<Rank, HandInd>,
}
impl Game {
@ -130,19 +151,41 @@ impl Game {
.map(Hand::parse)
.collect::<Vec<Hand>>();
Game {
hands,
..Default::default()
Game { hands }
}
fn get_score_sum(&mut self) -> usize {
// Rank the hands
self.hands.sort_unstable();
self.hands.iter().enumerate().fold(0, |prev, curr| {
let (i, hand) = curr;
let rank = i + 1;
prev + (rank * hand.bet)
})
}
}
fn part_one() {
let mut game = Game::parse(FILE_STR);
let score = game.get_score_sum();
println!("Part 1: Sum of scores: {}", score);
}
fn main() {
let game = Game::parse(EXAMPLE_FILE_STR);
println!("{:#?}", game);
part_one();
}
#[cfg(test)]
mod test {
const EXAMPLE_FILE_STR: &str = include_str!("example-input.txt");
use super::*;
#[test]
fn get_score_sum() {
let mut game = Game::parse(EXAMPLE_FILE_STR);
assert_eq!(6440, game.get_score_sum());
}
}