From 70dc697e578619057d5c9d9f5c68e3d0430c50fc Mon Sep 17 00:00:00 2001 From: javalsai Date: Thu, 4 Dec 2025 01:26:28 +0100 Subject: [PATCH] perf: trying to make error's code more performant, no heap now but slower fsr --- 2025/02/errors-all-heapless.rs | 112 +++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 2025/02/errors-all-heapless.rs diff --git a/2025/02/errors-all-heapless.rs b/2025/02/errors-all-heapless.rs new file mode 100644 index 0000000..fd30927 --- /dev/null +++ b/2025/02/errors-all-heapless.rs @@ -0,0 +1,112 @@ +//! Based from from ErrorNoInternet's . Not public code but +//! got permission to tweak it to perfection. +//! +//! Ugh, I guess all rights reserved to him unless he indicates otherwise explicitly. +//! +//! Insane speed tho, the magic of doing the math. + +struct StackLinkedList<'a, T> { + next: Option<&'a Self>, + data: T, +} +impl<'a, T> IntoIterator for &'a StackLinkedList<'a, T> { + type Item = &'a T; + type IntoIter = SLLIter<'a, T>; + + fn into_iter(self) -> Self::IntoIter { + SLLIter { node: Some(self) } + } +} + +use StackLinkedList as SLL; + +pub struct SLLIter<'a, T> { + node: Option<&'a SLL<'a, T>>, +} +impl<'a, T> Iterator for SLLIter<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + if let Some(node) = self.node { + self.node = node.next; + Some(&node.data) + } else { + None + } + } +} + +#[unsafe(no_mangle)] +fn challenge_usize_duple(b: &[u8]) -> (usize, usize) { + let s = unsafe { str::from_utf8_unchecked(b) }; + let mut parsing_iter = s.trim_end().split(",").map(|range| { + let (left, right) = range.trim().split_once("-").unwrap(); + (left.parse().unwrap(), right.parse().unwrap()) + }); + + collect_to_stack_ll_and_call(&mut parsing_iter, |ranges| { + let a = sum(ranges, &[2, 4, 6, 8, 10], &[1, 2, 3, 4, 5]); + let b = sum(ranges, &[3, 5, 6, 7, 9, 10], &[1, 1, 2, 1, 3, 2]) + - sum(ranges, &[6, 10], &[1, 1]); + + (a, a + b) + }).unwrap() +} + +fn collect_to_stack_ll_and_call( + from: &mut impl Iterator, + f: impl FnOnce(&SLL<(usize, usize)>) -> R, +) -> Option { + fn _rec( + from: &mut impl Iterator, + link_to: &SLL<(usize, usize)>, + f: impl FnOnce(&SLL<(usize, usize)>) -> R, + ) -> R { + if let Some(e) = from.next() { + let node = StackLinkedList { + next: Some(link_to), + data: e, + }; + _rec(from, &node, f) + } else { + (f)(link_to) + } + } + + if let Some(e) = from.next() { + let node = StackLinkedList { + next: None, + data: e, + }; + Some(_rec(from, &node, f)) + } else { + None + } +} + +fn sum<'a>(ranges: impl IntoIterator + Copy, digits: &[u32], lengths: &[u32]) -> usize { + let mut result = 0; + + for (d, l) in digits.iter().zip(lengths) { + let repetitions = d / l; + let power = 10_usize.pow(*l); + let mut step = 0; + for _ in 0..repetitions { + step = step * power + 1; + } + let invalid_start = step * (power / 10); + let invalid_end = step * (power - 1); + + for &(start, end) in ranges.into_iter() { + let lower = start.next_multiple_of(step).max(invalid_start); + let upper = end.min(invalid_end); + if lower <= upper { + let n = (upper - lower) / step; + let m = n * (n + 1) / 2; + result += lower * (n + 1) + step * m; + } + } + } + + result +}