Skip to content

Commit

Permalink
finish debug of nCr
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Aug 27, 2024
1 parent e7a05eb commit c78e4af
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 9 deletions.
4 changes: 3 additions & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ license = "GPL-3.0"
chrono = "0.4.38"
itertools = "0.13.0"
num-traits = "0.2.19"
rstest = "0.21.0"
seq-macro = "0.3.5"

[dev-dependencies]
rstest = "0.21.0"

[target.'cfg(any(target_arch="wasm32",target_arch="wasm64"))'.dependencies]
js-sys = "0.3"
wasm-bindgen = "0.2"
Expand Down
1 change: 1 addition & 0 deletions rust/src/include/factors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use itertools::Itertools;

use crate::include::primes::prime_factors;

#[derive(Clone, Debug)]
pub struct ProperDivisors<I>
{
seen: HashSet<I>,
Expand Down
2 changes: 2 additions & 0 deletions rust/src/include/fibonacci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub fn fib_by_3<I>() -> impl Iterator<Item = I> where I: Copy + Zero + One + Add
return cache_iterator(FibonacciBy3::<I>::new());
}

#[derive(Clone, Copy, Debug, Hash)]
pub struct Fibonacci<I> {
a: I,
b: I,
Expand Down Expand Up @@ -44,6 +45,7 @@ impl<I> Iterator for Fibonacci<I> where I: Zero + One + Add + Copy {
}
}

#[derive(Clone, Copy, Debug, Hash)]
pub struct FibonacciBy3<I> {
a: I,
b: I,
Expand Down
1 change: 1 addition & 0 deletions rust/src/include/iter_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ where
return CachingIterator::new(iterator);
}

#[derive(Clone, Copy, Debug, Hash)]
pub struct CachingIterator<I, T>
where
I: Iterator<Item = T> + 'static,
Expand Down
15 changes: 8 additions & 7 deletions rust/src/include/math.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::cmp::PartialOrd;
use std::fmt::Debug;
use std::mem::size_of;

use num_traits::NumAssign;
use num_traits::one;
use num_traits::CheckedMul;

const MAX_FACTORIAL: [u8; 16] = [
5, // u8
Expand All @@ -23,7 +25,7 @@ where I: NumAssign + From<u8>
}

pub fn n_choose_r<I>(n: usize, r: usize) -> I
where I: Copy + From<u8> + From<u64> + NumAssign + PartialOrd
where I: Copy + From<u8> + From<u64> + NumAssign + PartialOrd + CheckedMul + Debug
{
if n < r {
panic!("Out of function's bounds");
Expand All @@ -33,7 +35,6 @@ where I: Copy + From<u8> + From<u64> + NumAssign + PartialOrd
}
// slow path for larger numbers
let mut answer: I = one();
let mut tmp: I;
let mut factors: Vec<i8> = vec![1; n + 1];
factors[0] = 0;
factors[1] = 0;
Expand All @@ -59,17 +60,17 @@ where I: Copy + From<u8> + From<u64> + NumAssign + PartialOrd
let mut j: usize = 2;
while i <= n {
while factors[i] > 0 {
tmp = answer;
answer *= (i as u64).into();
while answer < tmp && j <= n {
let mut result = answer.checked_mul(&(i as u64).into());
while result.is_none() && j <= n {
while factors[j] < 0 {
tmp /= (j as u64).into();
answer /= (j as u64).into();
factors[j] += 1;
}
j += 1;
answer = tmp * (i as u64).into();
result = answer.checked_mul(&(i as u64).into());
}
factors[i] -= 1;
answer = result.unwrap_or_else(|| panic!("nCr overflow: {:?} * {}", answer, i));
}
i += 1;
}
Expand Down
2 changes: 2 additions & 0 deletions rust/src/include/primes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use num_traits::{one,zero,One,Zero};

use crate::include::iter_cache::cache_iterator;

#[derive(Clone, Debug)]
pub struct Eratosthenes<I> where I: Hash {
sieve: HashMap<I, Vec<I>>,
prime: I,
Expand Down Expand Up @@ -68,6 +69,7 @@ pub fn primes_until<I>(x: I) -> impl Iterator<Item = I> where I: Hash + One + Ze
return primes::<I>().take_while(move |n| *n < x);
}

#[derive(Clone, Copy, Debug, Hash)]
pub struct PrimeFactors<I> {
number: I
}
Expand Down
13 changes: 13 additions & 0 deletions rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use itertools::Itertools;
pub mod include;
use include::primes;
use include::factors;
#[cfg(test)]
use include::math;
#[cfg(not(test))]
use include::problems::generate_supported_problems;
use include::problems::get_problem;
Expand Down Expand Up @@ -150,3 +152,14 @@ fn test_proper_divisors() -> Result<(), String> {
}
Ok(())
}

#[cfg(test)]
#[test]
fn test_n_choose_r() -> Result<(), String> {
for i in 0..68usize {
for j in 0..i {
assert_eq!((0..i).combinations(j).count() as u128, math::n_choose_r::<u128>(i, j));
}
}
Ok(())
}
2 changes: 1 addition & 1 deletion rust/src/p0053.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn p0053() -> Answer {
let mut answer: u64 = 0;
for n in 1..101 {
for r in 2..(n-1) {
if n_choose_r::<u64>(n, r) > 1_000_000 {
if n_choose_r::<u128>(n, r) > 1_000_000 {
answer += 1;
}
}
Expand Down

0 comments on commit c78e4af

Please sign in to comment.