Skip to content

Commit

Permalink
Now that it compiles, narrow types further
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Jul 23, 2024
1 parent ce27033 commit 34a1184
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 20 deletions.
2 changes: 1 addition & 1 deletion docs/rust/math.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ View source code `here on GitHub! <https://github.com/LivInTheLookingGlass/Euler
Returns the factorial of a given number. Note that it only accepts a ``u8`` because
any number that requires a larger type is *guaranteed* to overflow.

.. rust:fn:: n_choose_r<I: Copy + From<u64> + NumAssign + PartialOrd>(n: u64, r: u64) -> I
.. rust:fn:: n_choose_r<I: Copy + From<u64> + NumAssign + PartialOrd>(n: usize, r: usize) -> I
Returns the number of ways to choose r items from a set of n.

Expand Down
23 changes: 9 additions & 14 deletions rust/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,24 @@ pub fn factorial<I: NumAssign + From<u8>>(n: u8) -> I {
return answer
}

pub fn n_choose_r<I: Copy + From<u64> + NumAssign + PartialOrd>(n: u64, r: u64) -> I {
pub fn n_choose_r<I: Copy + From<u64> + NumAssign + PartialOrd>(n: usize, r: usize) -> I {
// slow path for larger numbers
let mut answer: I = one();
let sn: usize = n.try_into().unwrap();
let sr: usize = r.try_into().unwrap();
let mut tmp: I;
let mut factors: Vec<i8> = vec![0; (n + 1).try_into().unwrap()];
let mut factors: Vec<i8> = vec![0; n + 1];
// collect factors of final number
for i in 2..=sn {
for i in 2..=n {
factors[i] = 1;
}
// negative factor values indicate need to divide
for i in 2..=sr {
for i in 2..=r {
factors[i] -= 1;
}
for i in 2..=(sn - sr) {
for i in 2..=(n - r) {
factors[i] -= 1;
}
// this loop reduces to prime factors only
for i in (1..sn).rev() {
for i in (1..n).rev() {
for j in 2..i {
if i % j == 0 {
factors[j] += factors[i];
Expand All @@ -42,26 +40,23 @@ pub fn n_choose_r<I: Copy + From<u64> + NumAssign + PartialOrd>(n: u64, r: u64)
}
let mut i: usize = 2;
let mut j: usize = 2;
while i <= sn {
while i <= n {
while factors[i] > 0 {
tmp = answer;
answer *= (i as u64).into();
while answer < tmp && j <= sn {
while answer < tmp && j <= n {
while factors[j] < 0 {
tmp /= (j as u64).into();
factors[j] += 1;
}
j += 1;
answer = tmp * (i as u64).into();
}
if answer < tmp {
panic!(); // overflow
}
factors[i] -= 1;
}
i += 1;
}
while j <= sn {
while j <= n {
while factors[j] < 0 {
answer /= (j as u64).into();
factors[j] += 1;
Expand Down
8 changes: 3 additions & 5 deletions rust/src/p0034.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@ use crate::math::factorial;
pub fn p0034() -> i128 {
let mut answer: u32 = 0;
for x in 10..100000 {
let string: String = x.to_string();
let sum =
string.bytes()
.into_iter()
.fold(0, |a, b| a + factorial::<u32>(b - '0' as u8));
let sum = x.to_string()
.bytes()
.fold(0, |a, b| a + factorial::<u32>(b - '0'.into()));
if sum == x {
answer += x;
}
Expand Down

0 comments on commit 34a1184

Please sign in to comment.