day4: optimized

This commit is contained in:
Ishan Jain 2023-12-04 18:02:18 +05:30
parent 2b64d5de7c
commit bf1364e85e
Signed by: ishan
GPG Key ID: 0506DB2A1CC75C27
2 changed files with 24 additions and 57 deletions

View File

@ -1,5 +1,6 @@
#![feature(slice_split_once)] #![feature(slice_split_once)]
#![feature(test)] #![feature(test)]
extern crate test; extern crate test;
const INPUTS: [&[u8]; 2] = [ const INPUTS: [&[u8]; 2] = [
@ -22,30 +23,19 @@ fn process(data: &[u8]) -> u64 {
} }
let (_, nums) = data.split_at(colon_pos + 2); let (_, nums) = data.split_at(colon_pos + 2);
let (nums, wins) = nums.split_at(vert_tab_pos + 1 - colon_pos - 2); let (nums, wins) = nums.split_at(vert_tab_pos + 1 - colon_pos - 2);
let nums = nums[..nums.len() - 2].split(|&x| x == b' ');
let wins = wins.split(|&x| x == b' ');
let mut bit_map = BitMap::new(); let mut bit_map = BitMap::new();
for win in wins { for c in wins.chunks_exact(3) {
if win.is_empty() { let num = parse(&c[1..3]);
continue;
}
let win = parse(win);
bit_map.set(win); bit_map.set(num);
} }
let mut val = 0; let mut val = 0;
for num in nums { for c in nums.chunks_exact(3) {
if num.is_empty() { let num = parse(&c[0..2]);
continue;
}
let num = parse(num);
if bit_map.get(num) { if bit_map.get(num) {
if val == 0 { if val == 0 {
val = 1; val = 1;
@ -68,28 +58,20 @@ impl BitMap {
Self(0) Self(0)
} }
#[inline] #[inline]
pub fn set(&mut self, idx: usize) { pub fn set(&mut self, idx: u8) {
debug_assert!(idx < 128); debug_assert!(idx < 128);
self.0 |= 1 << idx; self.0 |= 1 << idx;
} }
#[inline] #[inline]
pub const fn get(&self, idx: usize) -> bool { pub const fn get(&self, idx: u8) -> bool {
debug_assert!(idx < 128); debug_assert!(idx < 128);
(self.0 >> idx) & 1 == 1 (self.0 >> idx) & 1 == 1
} }
} }
#[inline] #[inline]
fn parse(b: &[u8]) -> usize { const fn parse(b: &[u8]) -> u8 {
let mut out = 0; 10 * (b[0] & 0xf) + (b[1] & 0xf)
let mut pow = 1;
for c in b.iter().rev() {
out += (c - b'0') as usize * pow;
pow *= 10;
}
out
} }
fn main() { fn main() {

View File

@ -8,7 +8,7 @@ const INPUTS: [&[u8]; 2] = [
include_bytes!("./input.txt"), include_bytes!("./input.txt"),
]; ];
fn process(data: &[u8]) -> usize { fn process(data: &[u8]) -> u64 {
let mut counter = vec![0]; let mut counter = vec![0];
let mut colon_pos = 0; let mut colon_pos = 0;
@ -25,27 +25,19 @@ fn process(data: &[u8]) -> usize {
let (x, nums) = data.split_at(colon_pos + 2); let (x, nums) = data.split_at(colon_pos + 2);
let id = parse(&x[4..x.len() - 2]); let id = parse(&x[4..x.len() - 2]) as usize;
let (nums, wins) = nums.split_at(vert_tab_pos + 1 - colon_pos - 2); let (nums, wins) = nums.split_at(vert_tab_pos + 1 - colon_pos - 2);
let nums = nums[..nums.len() - 2].split(|&x| x == b' ');
let wins = wins.split(|&x| x == b' ');
let mut win = BitMap::new(); let mut win = BitMap::new();
for w in wins { for c in wins.chunks_exact(3) {
if w.is_empty() { let num = parse(&c[1..3]);
continue;
}
let num = parse(w);
win.set(num); win.set(num);
} }
let sum = nums let sum = nums
.into_iter() .chunks_exact(3)
.filter(|x| !x.is_empty()) .map(|x| parse(&x[0..2]))
.map(parse)
.fold(0, |a, x| a + win.get(x) as usize); .fold(0, |a, x| a + win.get(x) as usize);
if id + 1 + sum >= counter.len() { if id + 1 + sum >= counter.len() {
@ -58,7 +50,7 @@ fn process(data: &[u8]) -> usize {
} }
} }
counter.into_iter().sum::<usize>() counter.into_iter().sum::<u64>()
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -69,31 +61,24 @@ impl BitMap {
Self(0) Self(0)
} }
#[inline] #[inline]
pub fn set(&mut self, idx: usize) { pub fn set(&mut self, idx: u8) {
debug_assert!(idx < 128); debug_assert!(idx < 128);
self.0 |= 1 << idx; self.0 |= 1 << idx;
} }
#[inline] #[inline]
pub const fn get(&self, idx: usize) -> bool { pub const fn get(&self, idx: u8) -> bool {
debug_assert!(idx < 128); debug_assert!(idx < 128);
(self.0 >> idx) & 1 == 1 (self.0 >> idx) & 1 == 1
} }
} }
#[inline] #[inline]
fn parse(b: &[u8]) -> usize { const fn parse(b: &[u8]) -> u8 {
let mut out = 0; match b.len() {
2 => 10 * (b[0] & 0xf) + (b[1] & 0xf),
let mut pow = 1; 4 => 100 * (b[1] & 0xf) + 10 * (b[2] & 0xf) + (b[3] & 0xf),
for c in b.iter().rev() { _ => unreachable!(),
if !c.is_ascii_digit() {
break;
}
out += (c - b'0') as usize * pow;
pow *= 10;
} }
out
} }
fn main() { fn main() {