From 2c36198ba88a33afee05a4dd29a3e34aa7cc10aa Mon Sep 17 00:00:00 2001 From: javalsai Date: Thu, 4 Dec 2025 11:38:32 +0100 Subject: [PATCH] perf --- 2025/04/all.rs | 111 +++++++++++++++++++++++++++++++++++++++++++++++++ 2025/04/p1.rs | 47 ++++++++++++++------- 2025/04/p2.rs | 77 +++++++++++++++++++--------------- 3 files changed, 188 insertions(+), 47 deletions(-) create mode 100644 2025/04/all.rs diff --git a/2025/04/all.rs b/2025/04/all.rs new file mode 100644 index 0000000..91c5fc7 --- /dev/null +++ b/2025/04/all.rs @@ -0,0 +1,111 @@ +// The use of these 2 could be optimized but not fatal performance + +fn is_paperroll(slice: &[u8], idx: usize) -> bool { + slice.get(idx).is_some_and(|&x| x == b'@') +} + +fn count_rolls_at_postns( + slice: &[u8], + idx: usize, + postns: impl IntoIterator, +) -> usize { + let mut count = 0; + for pos in postns.into_iter() { + if is_paperroll(slice, idx.wrapping_add_signed(pos)) { + count += 1; + } + } + + count +} + +#[unsafe(no_mangle)] +fn challenge_usize_duple(buf: &[u8]) -> (usize, usize) { + let mut v = buf.to_vec(); + let trimmed_endl = v.len() - 1; + + let p1 = challenge_usize_inplace::(&mut v[0..trimmed_endl]); + + let mut total = 0; + let mut toadd = challenge_usize_inplace::(&mut v[0..trimmed_endl]); + while toadd > 0 { + // println!("{}", unsafe { str::from_utf8_unchecked(&cleaned_lines) }); + total += toadd; + toadd = challenge_usize_inplace::(&mut v[0..trimmed_endl]); + } + + (p1, total) +} + +fn challenge_usize_inplace(buf: &mut [u8]) -> usize { + let mut prev_line: Option<&mut [u8]> = None; + let mut surrounded_line: Option<&mut [u8]> = None; + + let mut total = 0; + + for ln in buf.split_mut(|&b| b == b'\n') { + if let Some(fln) = surrounded_line { + if prev_line.is_none() { + for i in 0..fln.len() { + if fln[i] != b'@' { + continue; + } + let adj_count = count_rolls_at_postns(fln, i, [-1, 1]) + + count_rolls_at_postns(ln, i, [-1, 0, 1]); + if adj_count < 4 { + if REPLACE { + fln[i] = b'x'; + } + total += 1; + } + } + } + surrounded_line = Some(fln); + } + + if let Some(pln) = prev_line { + let sln = surrounded_line.unwrap(); + + for i in 0..sln.len() { + if sln[i] != b'@' { + continue; + } + + let adj_count = count_rolls_at_postns(pln, i, [-1, 0, 1]) + + count_rolls_at_postns(sln, i, [-1, 1]) + + count_rolls_at_postns(ln, i, [-1, 0, 1]); + if adj_count < 4 { + if REPLACE { + sln[i] = b'x'; + } + total += 1; + } + } + + surrounded_line = Some(sln); + } + + prev_line = surrounded_line.take(); + surrounded_line = Some(ln); + } + + let pln = prev_line.unwrap(); + let lln = surrounded_line.unwrap(); + + for i in 0..lln.len() { + if lln[i] != b'@' { + continue; + } + + let adj_count = + count_rolls_at_postns(pln, i, [-1, 0, 1]) + count_rolls_at_postns(lln, i, [-1, 1]); + if adj_count < 4 { + if REPLACE { + lln[i] = b'x'; + } + total += 1; + } + } + + total +} diff --git a/2025/04/p1.rs b/2025/04/p1.rs index 07f6636..2b04443 100644 --- a/2025/04/p1.rs +++ b/2025/04/p1.rs @@ -1,4 +1,4 @@ -use std::mem; +// The use of these 2 could be optimized but not fatal performance fn is_paperroll(slice: &[u8], idx: usize) -> bool { slice.get(idx).is_some_and(|&x| x == b'@') @@ -21,28 +21,40 @@ fn count_rolls_at_postns( #[unsafe(no_mangle)] fn challenge_usize(buf: &[u8]) -> usize { - let mut prev_line = None; + challenge_usize_inplace(&buf[0..buf.len() - 1]) +} + +fn challenge_usize_inplace(buf: &[u8]) -> usize { + let mut prev_line: Option<&[u8]> = None; let mut surrounded_line: Option<&[u8]> = None; let mut total = 0; - for ln in buf[0..(buf.len() - 1)].split(|&b| b == b'\n') { - if let Some(fln) = surrounded_line - && prev_line.is_none() - { - for (i, _) in fln.iter().enumerate().filter(|(_, b)| **b == b'@') { - let adj_count = count_rolls_at_postns(fln, i, [-1, 1]) - + count_rolls_at_postns(ln, i, [-1, 0, 1]); - if adj_count < 4 { - total += 1; + for ln in buf.split(|&b| b == b'\n') { + if let Some(fln) = surrounded_line { + if prev_line.is_none() { + for i in 0..fln.len() { + if fln[i] != b'@' { + continue; + } + let adj_count = count_rolls_at_postns(fln, i, [-1, 1]) + + count_rolls_at_postns(ln, i, [-1, 0, 1]); + if adj_count < 4 { + total += 1; + } } } + surrounded_line = Some(fln); } if let Some(pln) = prev_line { let sln = surrounded_line.unwrap(); - for (i, _) in sln.iter().enumerate().filter(|(_, b)| **b == b'@') { + for i in 0..sln.len() { + if sln[i] != b'@' { + continue; + } + let adj_count = count_rolls_at_postns(pln, i, [-1, 0, 1]) + count_rolls_at_postns(sln, i, [-1, 1]) + count_rolls_at_postns(ln, i, [-1, 0, 1]); @@ -50,15 +62,22 @@ fn challenge_usize(buf: &[u8]) -> usize { total += 1; } } + + surrounded_line = Some(sln); } - prev_line = surrounded_line; + prev_line = surrounded_line.take(); surrounded_line = Some(ln); } let pln = prev_line.unwrap(); let lln = surrounded_line.unwrap(); - for (i, _) in lln.iter().enumerate().filter(|(_, b)| **b == b'@') { + + for i in 0..lln.len() { + if lln[i] != b'@' { + continue; + } + let adj_count = count_rolls_at_postns(pln, i, [-1, 0, 1]) + count_rolls_at_postns(lln, i, [-1, 1]); if adj_count < 4 { diff --git a/2025/04/p2.rs b/2025/04/p2.rs index c539e08..dc9128f 100644 --- a/2025/04/p2.rs +++ b/2025/04/p2.rs @@ -1,4 +1,4 @@ -use std::mem; +// The use of these 2 could be optimized but not fatal performance fn is_paperroll(slice: &[u8], idx: usize) -> bool { slice.get(idx).is_some_and(|&x| x == b'@') @@ -21,73 +21,84 @@ fn count_rolls_at_postns( #[unsafe(no_mangle)] fn challenge_usize(buf: &[u8]) -> usize { - let mut prev_line = None; - let mut surrounded_line: Option<&[u8]> = None; + let mut v = buf.to_vec(); + let trimmed_endl = v.len() - 1; let mut total = 0; - let mut cleaned_lines = Vec::new(); + let mut toadd = challenge_usize_inplace(&mut v[0..trimmed_endl]); + while toadd > 0 { + // println!("{}", unsafe { str::from_utf8_unchecked(&cleaned_lines) }); + total += toadd; + toadd = challenge_usize_inplace(&mut v[0..trimmed_endl]); + } - for ln in buf[0..(buf.len() - 1)].split(|&b| b == b'\n') { - if let Some(fln) = surrounded_line - && prev_line.is_none() - { - let cleaned_start_idx = cleaned_lines.len(); - cleaned_lines.extend_from_slice(fln); - cleaned_lines.push(b'\n'); + total +} - for (i, _) in fln.iter().enumerate().filter(|(_, b)| **b == b'@') { - let adj_count = count_rolls_at_postns(fln, i, [-1, 1]) - + count_rolls_at_postns(ln, i, [-1, 0, 1]); - if adj_count < 4 { - cleaned_lines[cleaned_start_idx + i] = b'x'; - total += 1; +fn challenge_usize_inplace(buf: &mut [u8]) -> usize { + let mut prev_line: Option<&mut [u8]> = None; + let mut surrounded_line: Option<&mut [u8]> = None; + + let mut total = 0; + + for ln in buf.split_mut(|&b| b == b'\n') { + if let Some(fln) = surrounded_line { + if prev_line.is_none() { + for i in 0..fln.len() { + if fln[i] != b'@' { + continue; + } + let adj_count = count_rolls_at_postns(fln, i, [-1, 1]) + + count_rolls_at_postns(ln, i, [-1, 0, 1]); + if adj_count < 4 { + fln[i] = b'x'; + total += 1; + } } } + surrounded_line = Some(fln); } if let Some(pln) = prev_line { let sln = surrounded_line.unwrap(); - let cleaned_start_idx = cleaned_lines.len(); - cleaned_lines.extend_from_slice(sln); - cleaned_lines.push(b'\n'); + for i in 0..sln.len() { + if sln[i] != b'@' { + continue; + } - for (i, _) in sln.iter().enumerate().filter(|(_, b)| **b == b'@') { let adj_count = count_rolls_at_postns(pln, i, [-1, 0, 1]) + count_rolls_at_postns(sln, i, [-1, 1]) + count_rolls_at_postns(ln, i, [-1, 0, 1]); if adj_count < 4 { - cleaned_lines[cleaned_start_idx + i] = b'x'; + sln[i] = b'x'; total += 1; } } + + surrounded_line = Some(sln); } - prev_line = surrounded_line; + prev_line = surrounded_line.take(); surrounded_line = Some(ln); } let pln = prev_line.unwrap(); let lln = surrounded_line.unwrap(); - let cleaned_start_idx = cleaned_lines.len(); - cleaned_lines.extend_from_slice(lln); - cleaned_lines.push(b'\n'); + for i in 0..lln.len() { + if lln[i] != b'@' { + continue; + } - for (i, _) in lln.iter().enumerate().filter(|(_, b)| **b == b'@') { let adj_count = count_rolls_at_postns(pln, i, [-1, 0, 1]) + count_rolls_at_postns(lln, i, [-1, 1]); if adj_count < 4 { - cleaned_lines[cleaned_start_idx + i] = b'x'; + lln[i] = b'x'; total += 1; } } - if total > 0 { - // println!("{}", unsafe { str::from_utf8_unchecked(&cleaned_lines) }); - total += challenge_usize(&cleaned_lines); - } - total }