day 7 part 1
This commit is contained in:
parent
146735881a
commit
ca8d1c7708
2 changed files with 1139 additions and 0 deletions
1000
inputs/day7.txt
Normal file
1000
inputs/day7.txt
Normal file
File diff suppressed because it is too large
Load diff
139
src/bin/day7.rs
Normal file
139
src/bin/day7.rs
Normal file
|
@ -0,0 +1,139 @@
|
|||
#![forbid(elided_lifetimes_in_paths, unsafe_code)]
|
||||
|
||||
use aoc23::read;
|
||||
use chumsky::{prelude::*, text::int};
|
||||
use std::{
|
||||
collections::{BTreeSet, HashMap},
|
||||
fmt::{self, Debug}
|
||||
};
|
||||
|
||||
macro_rules! cards {
|
||||
($($ident:ident = $char:literal),+) => {
|
||||
#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
||||
enum Card { $($ident),+ }
|
||||
|
||||
impl Card {
|
||||
fn parser() -> impl Parser<char, Self, Error = Simple<char>> {
|
||||
choice((
|
||||
$(just($char).map(|_| Self::$ident)),+
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Card {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
$(Self::$ident => write!(f, "{}", $char)),+
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cards! {
|
||||
Two = '2',
|
||||
Three = '3',
|
||||
Four = '4',
|
||||
Five = '5',
|
||||
Six = '6',
|
||||
Seven = '7',
|
||||
Eight = '8',
|
||||
Nine = '9',
|
||||
Ten = 'T',
|
||||
Junior = 'J',
|
||||
Queen = 'Q',
|
||||
King = 'K',
|
||||
Ass = 'A'
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||
enum Type {
|
||||
/// All distinct (e.g. `23456`).
|
||||
HighCard,
|
||||
/// One pair (e.g. `A23A4`).
|
||||
OnePair,
|
||||
/// Two pair (e.g. `23432`).
|
||||
TwoPair,
|
||||
/// Three of a kind (e.g. `TTT98`).
|
||||
ThreeOfAKind,
|
||||
/// Full house (e.g. `23332`).
|
||||
FullHouse,
|
||||
/// Four of a kind (e.g. `AA8AA`).
|
||||
FourOfAKind,
|
||||
/// Five of a kind (e.g. `AAAAA`).
|
||||
FiveOfAKind
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||
struct Hand {
|
||||
ty: Type,
|
||||
cards: [Card; 5],
|
||||
bid: usize
|
||||
}
|
||||
|
||||
impl Hand {
|
||||
fn new(cards: [Card; 5], bid: usize) -> Self {
|
||||
let mut counts: HashMap<Card, usize> = HashMap::new();
|
||||
for card in cards {
|
||||
*counts.entry(card).or_default() += 1;
|
||||
}
|
||||
|
||||
let ty = if counts.values().any(|c| *c == 5) {
|
||||
Type::FiveOfAKind
|
||||
} else if counts.values().any(|c| *c == 4) {
|
||||
Type::FourOfAKind
|
||||
} else if counts.values().any(|c| *c == 3) {
|
||||
if counts.values().any(|c| *c == 2) {
|
||||
Type::FullHouse
|
||||
} else {
|
||||
Type::ThreeOfAKind
|
||||
}
|
||||
} else {
|
||||
let pairs = counts.values().filter(|c| **c == 2).count();
|
||||
match pairs {
|
||||
2 => Type::TwoPair,
|
||||
1 => Type::OnePair,
|
||||
0 => Type::HighCard,
|
||||
_ => unreachable!()
|
||||
}
|
||||
};
|
||||
|
||||
Self { ty, cards, bid }
|
||||
}
|
||||
|
||||
fn parser() -> impl Parser<char, Self, Error = Simple<char>> {
|
||||
Card::parser()
|
||||
.repeated()
|
||||
.exactly(5)
|
||||
.then_ignore(just(" "))
|
||||
.then(int(10))
|
||||
.map(|(cards, bid)| {
|
||||
Self::new(cards.try_into().unwrap(), bid.parse().unwrap())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn parser() -> impl Parser<char, Vec<Hand>, Error = Simple<char>> {
|
||||
Hand::parser()
|
||||
.then_ignore(just("\n"))
|
||||
.repeated()
|
||||
.then_ignore(end())
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let hands = read("inputs/day7.txt", parser())?;
|
||||
// eprintln!("{hands:?}");
|
||||
|
||||
let sorted: BTreeSet<&Hand> = hands.iter().collect();
|
||||
// eprintln!("{sorted:?}");
|
||||
println!(
|
||||
"{}",
|
||||
sorted
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, hand)| (i + 1) * hand.bid)
|
||||
.sum::<usize>()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in a new issue