From 37818823a8de213e3f2d5eb7b29887c1e4b9910b Mon Sep 17 00:00:00 2001 From: Ishan Jain Date: Thu, 7 Dec 2023 15:06:13 +0530 Subject: [PATCH] day7: optimized --- src/day7/1.rs | 102 ++++++++++++------------------------------------ src/day7/2.rs | 106 +++++++++++--------------------------------------- 2 files changed, 48 insertions(+), 160 deletions(-) diff --git a/src/day7/1.rs b/src/day7/1.rs index a7f88d4..61ebc6a 100644 --- a/src/day7/1.rs +++ b/src/day7/1.rs @@ -11,8 +11,8 @@ const INPUTS: [&[u8]; 2] = [ ]; #[derive(Debug)] -struct Card<'a> { - val: &'a [u8], +struct Card { + val: usize, set_type: SetType, } @@ -29,7 +29,7 @@ enum SetType { const ARRAY_SIZE: usize = 15; -fn process(data: &[u8]) -> u64 { +fn process(data: &[u8]) -> usize { let mut answer = 0; let mut cards = vec![]; @@ -37,14 +37,14 @@ fn process(data: &[u8]) -> u64 { if data.is_empty() { continue; } - let (card, value) = data.split_at(6); - let card = card.trim_ascii(); + let (card, value) = data.split_at(5); + let value = &value[1..]; let mut arr = [0; ARRAY_SIZE]; for &c in card { let c = card_weight(c); - arr[c as usize] += 1; + arr[c] += 1; } let transposed = transpose(&arr); @@ -70,10 +70,16 @@ fn process(data: &[u8]) -> u64 { let mut pow = 1; for &val in value.iter().rev() { - num += (val - b'0') as u64 * pow; + num += (val - b'0') as usize * pow; pow *= 10; } + let card = (card_weight(card[0]) << 32) + + (card_weight(card[1]) << 24) + + (card_weight(card[2]) << 16) + + (card_weight(card[3]) << 8) + + card_weight(card[4]); + cards.push(( Card { val: card, @@ -83,85 +89,27 @@ fn process(data: &[u8]) -> u64 { )); } - cards.sort_unstable_by(|(a, _), (b, _)| match (a.set_type, b.set_type) { - (x, y) if x == y => { - for (a, b) in a.val.iter().zip(b.val.iter()) { - let ordering = cmp(*a, *b); + cards.sort_unstable_by(|(a, _), (b, _)| -> Ordering { + match (a.set_type, b.set_type) { + (x, y) if x == y => a.val.cmp(&b.val), + (x, y) => { + let x = x as u8; + let y = y as u8; - if ordering != Ordering::Equal { - return ordering; - } + x.cmp(&y) } - - Ordering::Equal - } - (x, y) => { - let x = x as u8; - let y = y as u8; - - x.cmp(&y) } }); for (i, (_, v)) in cards.into_iter().enumerate() { let i = i + 1; - answer += v * i as u64; + answer += v * i; } answer } -#[inline] -const fn cmp(a: u8, b: u8) -> Ordering { - if a == b { - return Ordering::Equal; - } - - match (a, b) { - (b'A', _) => Ordering::Greater, - (_, b'A') => Ordering::Less, - - (b'K', _) => Ordering::Greater, - (_, b'K') => Ordering::Less, - - (b'Q', _) => Ordering::Greater, - (_, b'Q') => Ordering::Less, - - (b'J', _) => Ordering::Greater, - (_, b'J') => Ordering::Less, - - (b'T', _) => Ordering::Greater, - (_, b'T') => Ordering::Less, - - (b'9', _) => Ordering::Greater, - (_, b'9') => Ordering::Less, - - (b'8', _) => Ordering::Greater, - (_, b'8') => Ordering::Less, - - (b'7', _) => Ordering::Greater, - (_, b'7') => Ordering::Less, - - (b'6', _) => Ordering::Greater, - (_, b'6') => Ordering::Less, - - (b'5', _) => Ordering::Greater, - (_, b'5') => Ordering::Less, - - (b'4', _) => Ordering::Greater, - (_, b'4') => Ordering::Less, - - (b'3', _) => Ordering::Greater, - (_, b'3') => Ordering::Less, - - (b'2', _) => Ordering::Greater, - (_, b'2') => Ordering::Less, - - (_, _) => unreachable!(), - } -} - #[inline] fn transpose(ip: &[u8; ARRAY_SIZE]) -> [u8; 6] { let mut out = [0; 6]; @@ -174,12 +122,12 @@ fn transpose(ip: &[u8; ARRAY_SIZE]) -> [u8; 6] { } #[inline] -const fn card_weight(a: u8) -> u8 { +const fn card_weight(a: u8) -> usize { match a { - b'2'..=b'9' => a - b'0', + b'2'..=b'9' => (a - b'0') as usize, - b'J' => 10, - b'T' => 11, + b'T' => 10, + b'J' => 11, b'Q' => 12, b'K' => 13, b'A' => 14, diff --git a/src/day7/2.rs b/src/day7/2.rs index 09917a5..f221ddb 100644 --- a/src/day7/2.rs +++ b/src/day7/2.rs @@ -1,8 +1,6 @@ #![feature(byte_slice_trim_ascii)] #![feature(test)] -use std::cmp::Ordering; - extern crate test; const INPUTS: [&[u8]; 2] = [ @@ -11,8 +9,8 @@ const INPUTS: [&[u8]; 2] = [ ]; #[derive(Debug)] -struct Card<'a> { - val: &'a [u8], +struct Card { + val: usize, ctype: SetType, } @@ -29,7 +27,7 @@ enum SetType { const ARRAY_SIZE: usize = 14; -fn process(data: &[u8]) -> u64 { +fn process(data: &[u8]) -> usize { let mut answer = 0; let mut cards = vec![]; @@ -38,71 +36,63 @@ fn process(data: &[u8]) -> u64 { if data.is_empty() { continue; } - let (card, value) = data.split_at(6); - let card = card.trim_ascii(); + let (card, value) = data.split_at(5); + let value = &value[1..]; let mut arr = [0; ARRAY_SIZE]; for &c in card.iter() { let c = card_weight(c); - arr[c as usize] += 1; + arr[c] += 1; } - let count = arr[card_weight(b'J') as usize]; + let count = arr[card_weight(b'J')]; let transposed = transpose(&arr); let ctype = match (count, transposed) { (_, [_, _, _, _, _, 1]) => SetType::Five, - (4, [_, 1, _, _, 1, _]) => SetType::Five, - (1, [_, 1, _, _, 1, _]) => SetType::Five, + (4 | 1, [_, 1, _, _, 1, _]) => SetType::Five, (_, [_, 1, _, _, 1, _]) => SetType::Four, - (3, [_, _, 1, 1, _, _]) => SetType::Five, - (2, [_, _, 1, 1, _, _]) => SetType::Five, + (3 | 2, [_, _, 1, 1, _, _]) => SetType::Five, (_, [_, _, 1, 1, _, _]) => SetType::FullHouse, - (3, [_, 2, _, 1, _, _]) => SetType::Four, - (1, [_, 2, _, 1, _, _]) => SetType::Four, + (3 | 1, [_, 2, _, 1, _, _]) => SetType::Four, (_, [_, 2, _, 1, _, _]) => SetType::Three, (2, [_, 1, 2, _, _, _]) => SetType::Four, (1, [_, 1, 2, _, _, _]) => SetType::FullHouse, (_, [_, 1, 2, _, _, _]) => SetType::Two, - (2, [_, 3, 1, _, _, _]) => SetType::Three, - (1, [_, 3, 1, _, _, _]) => SetType::Three, + (2 | 1, [_, 3, 1, _, _, _]) => SetType::Three, (_, [_, 3, 1, _, _, _]) => SetType::One, (1, [_, 5, _, _, _, _]) => SetType::One, (_, [_, 5, _, _, _, _]) => SetType::High, - (_, _) => unreachable!(), + // Never + (_, _) => SetType::High, }; let mut num = 0; let mut pow = 1; for &val in value.iter().rev() { - num += (val - b'0') as u64 * pow; + num += (val - b'0') as usize * pow; pow *= 10; } + let card = (card_weight(card[0]) << 32) + + (card_weight(card[1]) << 24) + + (card_weight(card[2]) << 16) + + (card_weight(card[3]) << 8) + + card_weight(card[4]); cards.push((Card { val: card, ctype }, num)); } cards.sort_unstable_by(|(a, _), (b, _)| match (a.ctype, b.ctype) { - (x, y) if x == y => { - for (a, b) in a.val.iter().zip(b.val.iter()) { - let ordering = cmp(*a, *b); - - if ordering != Ordering::Equal { - return ordering; - } - } - - Ordering::Equal - } + (x, y) if x == y => a.val.cmp(&b.val), (x, y) => { let x = x as u8; let y = y as u8; @@ -114,7 +104,7 @@ fn process(data: &[u8]) -> u64 { for (i, (_, v)) in cards.into_iter().enumerate() { let i = i + 1; - answer += v * i as u64; + answer += v * i; } answer @@ -132,11 +122,11 @@ fn transpose(ip: &[u8; ARRAY_SIZE]) -> [u8; 6] { } #[inline] -const fn card_weight(a: u8) -> u8 { +const fn card_weight(a: u8) -> usize { match a { b'J' => 1, - b'2'..=b'9' => a - b'0', + b'2'..=b'9' => (a - b'0') as usize, b'T' => 10, b'Q' => 11, @@ -147,56 +137,6 @@ const fn card_weight(a: u8) -> u8 { } } -#[inline] -const fn cmp(a: u8, b: u8) -> Ordering { - if a == b { - return Ordering::Equal; - } - - match (a, b) { - (b'A', _) => Ordering::Greater, - (_, b'A') => Ordering::Less, - - (b'K', _) => Ordering::Greater, - (_, b'K') => Ordering::Less, - - (b'Q', _) => Ordering::Greater, - (_, b'Q') => Ordering::Less, - - (b'T', _) => Ordering::Greater, - (_, b'T') => Ordering::Less, - - (b'9', _) => Ordering::Greater, - (_, b'9') => Ordering::Less, - - (b'8', _) => Ordering::Greater, - (_, b'8') => Ordering::Less, - - (b'7', _) => Ordering::Greater, - (_, b'7') => Ordering::Less, - - (b'6', _) => Ordering::Greater, - (_, b'6') => Ordering::Less, - - (b'5', _) => Ordering::Greater, - (_, b'5') => Ordering::Less, - - (b'4', _) => Ordering::Greater, - (_, b'4') => Ordering::Less, - - (b'3', _) => Ordering::Greater, - (_, b'3') => Ordering::Less, - - (b'2', _) => Ordering::Greater, - (_, b'2') => Ordering::Less, - - (b'J', _) => Ordering::Greater, - (_, b'J') => Ordering::Less, - - (_, _) => unreachable!(), - } -} - fn main() { for input in INPUTS.iter() { println!("total = {}", process(input));