More simplification

This commit is contained in:
Avery Winters 2024-11-06 14:50:01 -06:00
parent 664ea1528a
commit c4e1e274f9
Signed by: avery
SSH key fingerprint: SHA256:eesvLB5MMqHLZrAMFt6kEhqJWnASMLcET6Sgmw0FqZI

View file

@ -1,28 +1,22 @@
pub fn factors(n: u64) -> Vec<u64> { pub fn factors(n: u64) -> Vec<u64> {
let n = n
.try_into()
.expect("usize is not large enough to factor a u64");
let bound = isqrt(n); let bound = isqrt(n);
let mut factors = { let mut factors = {
// Worst case number of factors is a power of 2, number of // Worst case number of factors is a power of 2, number of
// factors will be the number of bits needed to represent // factors will be the number of bits needed to represent
// the number. // the number.
let capacity = ilog2(n); let capacity = ilog2(n)
.try_into()
.expect("number of bits should not exceed usize::MAX");
Vec::with_capacity(capacity) Vec::with_capacity(capacity)
}; };
let mut reduced = n; let mut reduced = n;
'outer: for i in 2..=bound { 'outer: for i in 2..=bound {
while reduced % i == 0 { while reduced % i == 0 {
{ // Ensure we allocated enough capacity for all factors.
let i = i assert!(factors.len() < factors.capacity());
.try_into() factors.push(i);
.expect("round-trip conversion from u64 to usize loses precision");
// Ensure we allocated enough capacity for all factors.
assert!(factors.len() < factors.capacity());
factors.push(i);
}
reduced /= i; reduced /= i;
if reduced == 0 { if reduced == 0 {
break 'outer; break 'outer;
@ -31,9 +25,6 @@ pub fn factors(n: u64) -> Vec<u64> {
} }
if reduced > 1 { if reduced > 1 {
let reduced = reduced
.try_into()
.expect("round-trip conversion from u64 to usize loses precision");
// Ensure we allocated enough capacity for all factors. // Ensure we allocated enough capacity for all factors.
assert!(factors.len() < factors.capacity()); assert!(factors.len() < factors.capacity());
factors.push(reduced); factors.push(reduced);
@ -42,10 +33,10 @@ pub fn factors(n: u64) -> Vec<u64> {
factors factors
} }
fn ilog2(n: usize) -> usize { fn ilog2(n: u64) -> u32 {
(n.checked_ilog2().unwrap_or(0)) as _ n.checked_ilog2().unwrap_or(0)
} }
fn isqrt(n: usize) -> usize { fn isqrt(n: u64) -> u64 {
(n as f64).sqrt() as _ (n as f64).sqrt() as _
} }