summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs32
1 files changed, 26 insertions, 6 deletions
diff --git a/src/main.rs b/src/main.rs
index 67840ab..3500847 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,13 +1,25 @@
// LICENSE: WTFPL
use num_bigint::BigUint;
+use num_integer::{Integer, Roots};
+use std::cmp::min;
use std::ffi::OsString;
use std::process::ExitCode;
-use std::cmp::min;
// bnum seems to be slightly faster than ruint,
// and 3x faster than uint.
type UInt = bnum::types::U256;
+fn is_square(n: UInt) -> bool {
+ let sq = n.sqrt();
+ sq * sq == n
+}
+
+fn is_choose2(mut n: UInt) -> bool {
+ n <<= 1;
+ n.inc();
+ is_square(n)
+}
+
fn find_choose_r(mut k: UInt, r: u32) -> Option<UInt> {
// multiply k by r! to avoid future divisions
for i in 1..=r {
@@ -18,11 +30,11 @@ fn find_choose_r(mut k: UInt, r: u32) -> Option<UInt> {
let mut hi = UInt::from(1u8) << (log / r + 2);
let mut lo = UInt::from(r + 1);
'outer: while lo < hi {
- let mid: UInt = (lo + hi) / UInt::from(2u8);
+ let mid: UInt = (lo + hi) >> 1;
let mut i = mid;
let mut mid_falling_r = mid;
for _ in 1..r {
- i -= UInt::from(1u8);
+ i.dec();
mid_falling_r *= i;
if mid_falling_r > k {
hi = mid;
@@ -30,7 +42,8 @@ fn find_choose_r(mut k: UInt, r: u32) -> Option<UInt> {
}
}
if mid_falling_r < k {
- lo = mid + UInt::from(1u8);
+ lo = mid;
+ lo.inc();
} else {
return Some(mid);
}
@@ -174,7 +187,11 @@ fn search_row_limit(row_limit: u32) {
for row in 0..row_limit {
if row > 0 && row % 2 == 0 {
pascal_row[row as usize / 2] = pascal_row[row as usize / 2 - 1].wrapping_mul(2);
- entries.push(PascalEntry::new(pascal_row[row as usize / 2], row, (row / 2) as u16));
+ entries.push(PascalEntry::new(
+ pascal_row[row as usize / 2],
+ row,
+ (row / 2) as u16,
+ ));
}
for col in (2..=(std::cmp::max(3, row) - 1) / 2).rev() {
pascal_row[col as usize] =
@@ -221,7 +238,10 @@ fn search_col_limit(col_limit: u16) {
// we already know the solutions with both columns ≤ 4
continue;
}
- for col2 in 2..min(col, col_limit as usize + 1) {
+ if is_choose2(pascal_row[col]) {
+ println!("({row} choose {col}) = (something choose 2)");
+ }
+ for col2 in 3..min(col, col_limit as usize + 1) {
if let Some(x) = find_choose_r(pascal_row[col], col2 as u32) {
println!("({row} choose {col}) = ({x} choose {col2})");
}