day 7 part 2
This commit is contained in:
parent
ca8d1c7708
commit
3c4e784d97
1 changed files with 58 additions and 17 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(clippy::no_effect)]
|
||||||
#![forbid(elided_lifetimes_in_paths, unsafe_code)]
|
#![forbid(elided_lifetimes_in_paths, unsafe_code)]
|
||||||
|
|
||||||
use aoc23::read;
|
use aoc23::read;
|
||||||
|
@ -13,6 +14,10 @@ macro_rules! cards {
|
||||||
enum Card { $($ident),+ }
|
enum Card { $($ident),+ }
|
||||||
|
|
||||||
impl Card {
|
impl Card {
|
||||||
|
fn all_cards() -> [Self; 0 $(+ { $char; 1 })+] {
|
||||||
|
[$(Self::$ident),+]
|
||||||
|
}
|
||||||
|
|
||||||
fn parser() -> impl Parser<char, Self, Error = Simple<char>> {
|
fn parser() -> impl Parser<char, Self, Error = Simple<char>> {
|
||||||
choice((
|
choice((
|
||||||
$(just($char).map(|_| Self::$ident)),+
|
$(just($char).map(|_| Self::$ident)),+
|
||||||
|
@ -31,6 +36,7 @@ macro_rules! cards {
|
||||||
}
|
}
|
||||||
|
|
||||||
cards! {
|
cards! {
|
||||||
|
Joker = '*',
|
||||||
Two = '2',
|
Two = '2',
|
||||||
Three = '3',
|
Three = '3',
|
||||||
Four = '4',
|
Four = '4',
|
||||||
|
@ -74,27 +80,39 @@ struct Hand {
|
||||||
impl Hand {
|
impl Hand {
|
||||||
fn new(cards: [Card; 5], bid: usize) -> Self {
|
fn new(cards: [Card; 5], bid: usize) -> Self {
|
||||||
let mut counts: HashMap<Card, usize> = HashMap::new();
|
let mut counts: HashMap<Card, usize> = HashMap::new();
|
||||||
|
let mut jokers = 0;
|
||||||
for card in cards {
|
for card in cards {
|
||||||
|
if card == Card::Joker {
|
||||||
|
jokers += 1;
|
||||||
|
} else {
|
||||||
*counts.entry(card).or_default() += 1;
|
*counts.entry(card).or_default() += 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
match counts.values_mut().max() {
|
||||||
|
Some(max) => {
|
||||||
|
*max += jokers;
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
counts.insert(Card::Joker, jokers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let ty = if counts.values().any(|c| *c == 5) {
|
let ty = if counts.values().any(|c| *c >= 5) {
|
||||||
Type::FiveOfAKind
|
Type::FiveOfAKind
|
||||||
} else if counts.values().any(|c| *c == 4) {
|
} else if counts.values().any(|c| *c >= 4) {
|
||||||
Type::FourOfAKind
|
Type::FourOfAKind
|
||||||
} else if counts.values().any(|c| *c == 3) {
|
} else if counts.values().any(|c| *c >= 3) {
|
||||||
if counts.values().any(|c| *c == 2) {
|
if counts.values().filter(|c| **c >= 2).count() >= 2 {
|
||||||
Type::FullHouse
|
Type::FullHouse
|
||||||
} else {
|
} else {
|
||||||
Type::ThreeOfAKind
|
Type::ThreeOfAKind
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let pairs = counts.values().filter(|c| **c == 2).count();
|
let pairs = counts.values().filter(|c| **c >= 2).count();
|
||||||
match pairs {
|
match pairs {
|
||||||
2 => Type::TwoPair,
|
|
||||||
1 => Type::OnePair,
|
|
||||||
0 => Type::HighCard,
|
0 => Type::HighCard,
|
||||||
_ => unreachable!()
|
1 => Type::OnePair,
|
||||||
|
_ => Type::TwoPair
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -120,20 +138,43 @@ fn parser() -> impl Parser<char, Vec<Hand>, Error = Simple<char>> {
|
||||||
.then_ignore(end())
|
.then_ignore(end())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sum_hands<'a>(hands: impl IntoIterator<Item = &'a Hand>) -> usize {
|
||||||
|
hands
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, hand)| (i + 1) * hand.bid)
|
||||||
|
.sum::<usize>()
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
let hands = read("inputs/day7.txt", parser())?;
|
let hands = read("inputs/day7.txt", parser())?;
|
||||||
// eprintln!("{hands:?}");
|
// eprintln!("{hands:?}");
|
||||||
|
|
||||||
let sorted: BTreeSet<&Hand> = hands.iter().collect();
|
let sorted: BTreeSet<&Hand> = hands.iter().collect();
|
||||||
// eprintln!("{sorted:?}");
|
// eprintln!("{sorted:?}");
|
||||||
println!(
|
let sum = sum_hands(sorted);
|
||||||
"{}",
|
println!("{sum}");
|
||||||
sorted
|
// assert_eq!(sum, 251106089);
|
||||||
.into_iter()
|
|
||||||
.enumerate()
|
let sorted: BTreeSet<Hand> = hands
|
||||||
.map(|(i, hand)| (i + 1) * hand.bid)
|
.iter()
|
||||||
.sum::<usize>()
|
.map(|hand| {
|
||||||
);
|
let mut cards = hand.cards;
|
||||||
|
for card in &mut cards {
|
||||||
|
if *card == Card::Junior {
|
||||||
|
*card = Card::Joker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let hand = Hand::new(cards, hand.bid);
|
||||||
|
// eprintln!("{hand:?}");
|
||||||
|
hand
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
// eprintln!("{sorted:#?}");
|
||||||
|
let sum = sum_hands(&sorted);
|
||||||
|
println!("{sum}");
|
||||||
|
// assert!(sum > 249135400);
|
||||||
|
// assert!(sum < 249779500);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue