heh
bendn 2024-12-08
parent 2bd7f3f · commit 5765be6
-rw-r--r--src/main.rs54
-rw-r--r--src/util.rs31
2 files changed, 40 insertions, 45 deletions
diff --git a/src/main.rs b/src/main.rs
index c1a5d37..1c7507c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -14,6 +14,7 @@
get_many_mut,
maybe_uninit_uninit_array,
iter_collect_into,
+ hint_assert_unchecked,
let_chains,
anonymous_lifetime_in_impl_trait,
array_windows,
@@ -32,16 +33,17 @@ pub use util::prelude::*;
#[inline]
fn do_(i: &str, search: fn(&[u64], u64) -> bool) -> u64 {
- let mut v = Vec::with_capacity(10);
- i.行()
- .map(|x| {
- v.clear();
- let (a, b) = x.μ(':');
- let should = reading::all(a);
- reading::κ(C! { &b[1..] }, &mut v);
- should * search(&v, should) as u64
- })
- .sum::<u64>()
+ let mut v = [0u64; 12];
+ let mut i = i.as_bytes();
+ let mut sum = 0;
+ while !i.is_empty() {
+ let should = reading::until(&mut i, b':');
+ i.skip(1);
+ let i = i.take_line().ψ();
+ let read = reading::κ(i, &mut v);
+ sum += should * search(C! { &v[..read] }, should) as u64;
+ }
+ sum
}
#[no_mangle]
@@ -51,16 +53,12 @@ pub fn run(i: &str) -> impl Display {
match nums {
&[tail] => tv == tail,
[head @ .., tail] => {
- let (q, r) = (tv / tail, tv % tail);
- if r == 0 && search(head, q) {
- return true;
- }
- let Some(result) = tv.checked_sub(*tail) else {
- return false;
- };
- search(head, result)
+ let &tail = tail;
+ unsafe { core::hint::assert_unchecked(tail != 0) };
+ (tv % tail == 0 && search(head, tv / tail))
+ || (tv > tail && search(head, tv - tail))
}
- [] => unreachable!(),
+ [] => shucks!(),
}
}
do_(i, search)
@@ -72,21 +70,19 @@ pub fn p2(i: &str) -> impl Display {
match nums {
&[tail] => tv == tail,
[head @ .., tail] => {
- let (q, r) = (tv / tail, tv % tail);
- if r == 0 && search(head, q) {
+ if tv % tail == 0 && search(head, tv / tail) {
+ return true;
+ }
+ let &d = unsafe { util::powers.get_unchecked(tail.ͱ() as usize) };
+ if (tv - tail) % d == 0 && search(head, tv / d) {
return true;
}
- let Some(result) = tv.checked_sub(*tail) else {
- return false;
- };
- if (tv - *tail) % util::powers[tail.ͱ() as usize] == 0
- && search(head, tv / util::powers[tail.ͱ() as usize])
- {
+ if tv > *tail && search(head, tv - tail) {
return true;
}
- search(head, result)
+ return false;
}
- [] => unreachable!(),
+ [] => shucks!(),
}
}
do_(i, |n, should| search(n, should))
diff --git a/src/util.rs b/src/util.rs
index 72e0457..9654aea 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -564,7 +564,7 @@ impl DigiCount for u64 {
static mdigs: [u32; 65] = car::from_fn!(|x| 2u128.pow(x as u32).ilog10() + 1);
let bit = std::mem::size_of::<Self>() * 8 - self.leading_zeros() as usize;
let mut digs = mdigs[bit];
- if self < powers[digs as usize - 1] {
+ if self < C! { powers[digs as usize - 1] } {
digs -= 1;
}
digs
@@ -577,7 +577,7 @@ impl DigiCount for u32 {
static mdigs: [u32; 33] = car::from_fn!(|x| 2u128.pow(x as u32).ilog10() + 1);
let bit = std::mem::size_of::<Self>() * 8 - self.leading_zeros() as usize;
let mut digs = mdigs[bit];
- if self < powers[digs as usize - 1] {
+ if self < C! { powers[digs as usize - 1] } {
digs -= 1;
}
digs
@@ -733,9 +733,7 @@ pub trait Μ where
impl Μ for &[u8] {
fn μ(self, d: char) -> (Self, Self) {
- let i = self
- .iter()
- .position(|&x| x == d as u8)
+ let i = memchr::memchr(d as u8, self)
.unwrap_or_else(|| shucks!("{} should split at {d} fine", self.p()));
(&self[..i], &self[i + 1..])
}
@@ -998,16 +996,18 @@ pub mod reading {
}
use crate::util::prelude::*;
pub fn κ<
- T: Default + std::ops::Mul<T, Output = T> + Add<T, Output = T> + From<u8> + Copy + Ten,
+ T: Default + std::ops::Mul<T, Output = T> + Add<T, Output = T> + From<u8> + Copy + Ten + Debug,
>(
x: &[u8],
- v: &mut Vec<T>,
- ) {
+ v: &mut [T],
+ ) -> usize {
+ let mut n = 0;
let mut s = T::default();
for &b in x {
match b {
b' ' => {
- v.push(s);
+ C! { v[n] = s };
+ n += 1;
s = T::default();
}
b => {
@@ -1015,7 +1015,8 @@ pub mod reading {
}
}
}
- v.push(s);
+ C! {v[n] = s};
+ n + 1
}
pub trait Ten {
fn ten() -> Self;
@@ -1109,13 +1110,11 @@ pub mod reading {
}
}
- pub fn 迄<
- T: Default + std::ops::Mul<T, Output = T> + Add<T, Output = T> + From<u8> + Copy + Ten,
- >(
+ pub fn until<T: std::ops::Mul<T, Output = T> + Add<T, Output = T> + From<u8> + Copy + Ten>(
x: &mut &[u8],
until: u8,
) -> T {
- let mut n = T::default();
+ let mut n = T::from(x.by().ψ() - b'0');
loop {
let byte = x.by().ψ();
if byte == until {
@@ -1372,8 +1371,8 @@ impl<'b> TakeLine<'b> for &'b [u8] {
None if self.is_empty() => None,
None => Some(std::mem::replace(self, b"")),
Some(end) => {
- let line = &self[..end];
- *self = &self[end + 1..];
+ let line = C! { &self[..end]};
+ *self = C! { &self[end + 1..]};
Some(line)
}
}