diff --git a/2023/day07/src/lib.rs b/2023/day07/src/lib.rs index 66ce6ac..fcc0a55 100644 --- a/2023/day07/src/lib.rs +++ b/2023/day07/src/lib.rs @@ -1,4 +1,4 @@ -mod sort_key; +mod sort_cache; mod unstable_sort; use std::cmp::{self, Ordering}; @@ -16,12 +16,12 @@ helper::define_variants! { part1 { basic => crate::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 { basic => crate::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; } } diff --git a/2023/day07/src/sort_key.rs b/2023/day07/src/sort_cache.rs similarity index 76% rename from 2023/day07/src/sort_key.rs rename to 2023/day07/src/sort_cache.rs index f7d0a86..7cb000c 100644 --- a/2023/day07/src/sort_key.rs +++ b/2023/day07/src/sort_cache.rs @@ -1,8 +1,15 @@ -use std::cmp::{self}; +use std::cmp::{self, Ordering}; 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 { let mut card_type = [0; 5]; @@ -69,9 +76,15 @@ fn parse(input: &str, has_jokers: bool) -> Vec { let values = cards.bytes().collect_array::<5>().unwrap(); 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 { - values, + values_cmp: values.map(mk_compare), hand_type, bid, } @@ -79,18 +92,18 @@ fn parse(input: &str, has_jokers: bool) -> Vec { .collect() } -fn evaluate_hands(hands: &mut [Hand], has_jokers: bool) -> u64 { +fn evaluate_hands(hands: &mut [Hand]) -> u64 { // Worst hand first, best hand last. - hands.sort_unstable_by_key(|hand| { - 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, - }; - - cmp::Reverse((hand.hand_type, cmp::Reverse(hand.values.map(mk_compare)))) + hands.sort_unstable_by(|a, b| { + let cmp = b.hand_type.cmp(&a.hand_type); + if cmp != Ordering::Equal { + return cmp; + } + let cmp = a.values_cmp.cmp(&b.values_cmp); + if cmp != Ordering::Equal { + return cmp; + } + Ordering::Equal }); hands @@ -102,10 +115,10 @@ fn evaluate_hands(hands: &mut [Hand], has_jokers: bool) -> u64 { pub fn part1(input: &str) -> u64 { let mut hands = parse(input, false); - evaluate_hands(&mut hands, false) + evaluate_hands(&mut hands) } pub fn part2(input: &str) -> u64 { let mut hands = parse(input, true); - evaluate_hands(&mut hands, true) + evaluate_hands(&mut hands) }