optimize day 7

This commit is contained in:
nora 2023-12-07 21:14:07 +01:00
parent 3120797873
commit f933f33ceb
2 changed files with 33 additions and 20 deletions

View file

@ -1,4 +1,4 @@
mod sort_key; mod sort_cache;
mod unstable_sort; mod unstable_sort;
use std::cmp::{self, Ordering}; use std::cmp::{self, Ordering};
@ -16,12 +16,12 @@ helper::define_variants! {
part1 { part1 {
basic => crate::part1, sample_count=10000; basic => crate::part1, sample_count=10000;
unstable_sort => crate::unstable_sort::part1, sample_count=10000; unstable_sort => crate::unstable_sort::part1, sample_count=10000;
card_soa => crate::sort_key::part1, sample_count=10000; sort_cache => crate::sort_cache::part1, sample_count=10000;
} }
part2 { part2 {
basic => crate::part2, sample_count=10000; basic => crate::part2, sample_count=10000;
unstable_sort => crate::unstable_sort::part2, sample_count=10000; unstable_sort => crate::unstable_sort::part2, sample_count=10000;
card_soa => crate::sort_key::part2, sample_count=10000; sort_cache => crate::sort_cache::part2, sample_count=10000;
} }
} }

View file

@ -1,8 +1,15 @@
use std::cmp::{self}; use std::cmp::{self, Ordering};
use helper::IteratorExt; use helper::IteratorExt;
use crate::{Hand, HandType}; use crate::HandType;
#[derive(Debug)]
struct Hand {
values_cmp: [u8; 5],
hand_type: HandType,
bid: u64,
}
fn hand_type_of(hand: [u8; 5], has_jokers: bool) -> HandType { fn hand_type_of(hand: [u8; 5], has_jokers: bool) -> HandType {
let mut card_type = [0; 5]; let mut card_type = [0; 5];
@ -69,9 +76,15 @@ fn parse(input: &str, has_jokers: bool) -> Vec<Hand> {
let values = cards.bytes().collect_array::<5>().unwrap(); let values = cards.bytes().collect_array::<5>().unwrap();
let hand_type = hand_type_of(values, has_jokers); let hand_type = hand_type_of(values, has_jokers);
let mk_compare = |v| match v {
b'A' => b'Z',
b'K' => b'Y',
b'T' => b'I',
b'J' if has_jokers => b'0',
other => other,
};
Hand { Hand {
values, values_cmp: values.map(mk_compare),
hand_type, hand_type,
bid, bid,
} }
@ -79,18 +92,18 @@ fn parse(input: &str, has_jokers: bool) -> Vec<Hand> {
.collect() .collect()
} }
fn evaluate_hands(hands: &mut [Hand], has_jokers: bool) -> u64 { fn evaluate_hands(hands: &mut [Hand]) -> u64 {
// Worst hand first, best hand last. // Worst hand first, best hand last.
hands.sort_unstable_by_key(|hand| { hands.sort_unstable_by(|a, b| {
let mk_compare = |v| match v { let cmp = b.hand_type.cmp(&a.hand_type);
b'A' => b'Z', if cmp != Ordering::Equal {
b'K' => b'Y', return cmp;
b'T' => b'I', }
b'J' if has_jokers => b'0', let cmp = a.values_cmp.cmp(&b.values_cmp);
other => other, if cmp != Ordering::Equal {
}; return cmp;
}
cmp::Reverse((hand.hand_type, cmp::Reverse(hand.values.map(mk_compare)))) Ordering::Equal
}); });
hands hands
@ -102,10 +115,10 @@ fn evaluate_hands(hands: &mut [Hand], has_jokers: bool) -> u64 {
pub fn part1(input: &str) -> u64 { pub fn part1(input: &str) -> u64 {
let mut hands = parse(input, false); let mut hands = parse(input, false);
evaluate_hands(&mut hands, false) evaluate_hands(&mut hands)
} }
pub fn part2(input: &str) -> u64 { pub fn part2(input: &str) -> u64 {
let mut hands = parse(input, true); let mut hands = parse(input, true);
evaluate_hands(&mut hands, true) evaluate_hands(&mut hands)
} }