This commit is contained in:
nora 2024-12-01 14:34:00 +01:00
parent 1b194e4f1c
commit 9b527751a1
2 changed files with 69 additions and 20 deletions

View file

@ -21,6 +21,7 @@ helper::define_variants! {
faster_parsing => crate::part2_parsing; faster_parsing => crate::part2_parsing;
array => crate::part2_array; array => crate::part2_array;
μopt_parsing => crate::part2_μopt_parsing; μopt_parsing => crate::part2_μopt_parsing;
part2_bytes => crate::part2_bytes;
} }
} }
@ -177,42 +178,90 @@ fn part2_array(input: &str) -> u64 {
score score
} }
fn part2_μopt_parsing(input: &str) -> u64 { fn part2_μopt_parsing(input: &str) -> u64 {
assert_eq!(input.as_bytes().last(), Some(&b'\n'));
const BIGGEST_ELEMENT: usize = 100_000; const BIGGEST_ELEMENT: usize = 100_000;
let mut right_map = vec![0_u16; BIGGEST_ELEMENT]; let mut right_map = vec![0_u16; BIGGEST_ELEMENT];
let mut left = Vec::with_capacity(input.len() / 8); let mut left = Vec::with_capacity(input.len());
let digit_len = input.as_bytes().iter().position(|b| *b == b' ').unwrap();
let line_len = 2 * digit_len + 3 + 1;
fn parse_digit(input: &str, len: usize) -> u64 {
let mut result = 0;
for i in 0..len {
result *= 10;
result += (input.as_bytes()[i] - b'0') as u64;
}
result
}
let mut input = input; let mut input = input;
loop { while input.len() >= line_len {
let Some(space) = input.as_bytes().iter().position(|b| *b == b' ') else { let number = parse_digit(input, digit_len);
break;
}; left.push(number as u32);
let number = input[..space].parse::<u64>().unwrap(); input = &input[(digit_len + 3)..];
left.push(number);
input = &input[(space + 3)..]; let number = parse_digit(input, digit_len);
let Some(newline) = input.as_bytes().iter().position(|b| *b == b'\n') else {
break;
};
let number = input[..space].parse::<u64>().unwrap();
right_map[number as usize] += 1; right_map[number as usize] += 1;
input = &input[newline..]; input = &input[digit_len..];
// handle lack of trailing newline input = &input[1..];
if !input.is_empty() {
input = &input[1..];
}
} }
let mut score = 0; let mut score = 0;
for number in left { for number in left {
let occurs = right_map[number as usize]; let occurs = right_map[number as usize];
score += number * (occurs as u64); score += (number as u64) * (occurs as u64);
} }
score score
} }
fn part2_bytes(input: &str) -> u64 {
let input = input.as_bytes();
assert_eq!(input.last(), Some(&b'\n'));
const BIGGEST_ELEMENT: usize = 100_000;
let mut right_map = vec![0_u16; BIGGEST_ELEMENT];
let mut left = Vec::<u32>::with_capacity(input.len());
let digit_len = input.iter().position(|b| *b == b' ').unwrap();
let line_len = 2 * digit_len + 3 + 1;
fn parse_digit(input: &[u8], len: usize) -> u32 {
let mut result = 0;
for i in 0..len {
result *= 10;
result += (unsafe { input.get_unchecked(i) } - b'0') as u32;
}
result
}
let mut input = input;
while input.len() >= line_len {
let number = parse_digit(input, digit_len);
left.push(number);
input = unsafe { &input.get_unchecked((digit_len + 3)..) };
let number = parse_digit(input, digit_len);
right_map[number as usize] += 1;
input = unsafe { &input.get_unchecked((digit_len + 1)..) };
}
let mut score = 0;
for number in left {
let occurs = right_map[number as usize];
score += number * (occurs as u32);
}
score as u64
}
helper::tests! { helper::tests! {
day01 Day01; day01 Day01;
part1 { part1 {

View file

@ -97,7 +97,7 @@ macro_rules! construct_variants {
( $day:ty; $( ($name:ident, $func:expr, [ $($_:tt)* ]) ),*) => { ( $day:ty; $( ($name:ident, $func:expr, [ $($_:tt)* ]) ),*) => {
$crate::Variants { $crate::Variants {
variants: vec![$( variants: vec![$(
$crate::Variant::new(stringify!($name), $func) $crate::Variant::new(stringify!($name), std::hint::black_box($func))
),*] ),*]
} }
}; };