#![cfg_attr(feature = "bench", feature(test))]
mod using_bigint;
mod using_smallbigint;
mod using_u32;
#[cfg(feature = "bench")]
extern crate test;
#[cfg(feature = "bench")]
use test::Bencher;
use smallbigint::Int;
use std::collections::BTreeSet;
use std::str::FromStr;
use structopt::StructOpt;
#[cfg(feature = "bench")]
const SMALL_PRIME_LIMIT: &str = ONE_HUNDRED_THOUSAND;
#[cfg(feature = "bench")]
const ONE_HUNDRED_THOUSAND: &str = "100000";
#[derive(Debug, StructOpt)]
struct Cli {
#[structopt(default_value = "1000000000000000")]
start: String,
#[structopt(default_value = "-1")]
step: String,
#[structopt(default_value = "1000000")]
small_prime_limit: String,
}
fn range(start: &str, stop: &str, step: &str) -> impl Iterator<Item = String> {
num_iter::range_step_inclusive(
Int::from_str(start).unwrap(),
Int::from_str(stop).unwrap(),
Int::from_str(step).unwrap(),
)
.map(|x| format!("{}", x))
}
fn main() -> Result<(), anyhow::Error> {
let args = Cli::from_args();
let mut best_quality = 99999;
for n in range(&args.start, "2", &args.step) {
match using_smallbigint::find_small_prime_factorization_str(&n, &args.small_prime_limit)
.unwrap()
{
None => println!(" Failed to compute factorization for {}", n),
Some(factors) => {
let quality = unique_elements(&factors);
if quality <= best_quality + 2 {
best_quality = quality.min(best_quality);
println!(
"- {} has {} unique factors: [{}]",
n,
&quality,
factors.join(", ")
);
}
}
}
}
Ok(())
}
fn unique_elements<T: Ord>(factors: impl AsRef<[T]>) -> usize {
factors.as_ref().iter().collect::<BTreeSet<&T>>().len()
}
#[cfg(feature = "bench")]
#[bench]
fn strange_factor_100000000000000_bigint(bencher: &mut Bencher) {
use using_bigint::find_small_prime_factorization_str;
bencher.iter(|| {
for v in range("100000000000000", "100000000000006", "1") {
test::bench::black_box(find_small_prime_factorization_str(&v, SMALL_PRIME_LIMIT))
.unwrap();
}
});
}
#[cfg(feature = "bench")]
#[bench]
fn strange_factor_100000000000000_smallbigint(bencher: &mut Bencher) {
use using_smallbigint::find_small_prime_factorization_str;
bencher.iter(|| {
for v in range("100000000000000", "100000000000006", "1") {
test::bench::black_box(find_small_prime_factorization_str(&v, SMALL_PRIME_LIMIT))
.unwrap();
}
});
}
#[cfg(all(feature = "bench", feature = "benchall"))]
#[bench]
fn strange_factor_100000000000000_u32(bencher: &mut Bencher) {
use using_u32::find_small_prime_factorization_str;
bencher.iter(|| {
for v in range("100000000000000", "100000000000006", "1") {
test::bench::black_box(find_small_prime_factorization_str(&v, SMALL_PRIME_LIMIT))
.unwrap();
}
});
}
#[cfg(feature = "bench")]
#[bench]
fn strange_factor_100000_bigint(bencher: &mut Bencher) {
use using_bigint::find_small_prime_factorization_str;
bencher.iter(|| {
for v in range("100000", "100010", "1") {
test::bench::black_box(find_small_prime_factorization_str(&v, SMALL_PRIME_LIMIT))
.unwrap();
}
});
}
#[cfg(feature = "bench")]
#[bench]
fn strange_factor_100000_smallbigint(bencher: &mut Bencher) {
use using_smallbigint::find_small_prime_factorization_str;
bencher.iter(|| {
for v in range("100000", "100010", "1") {
test::bench::black_box(find_small_prime_factorization_str(&v, SMALL_PRIME_LIMIT))
.unwrap();
}
});
}
#[cfg(feature = "bench")]
#[bench]
fn strange_factor_100000_u32(bencher: &mut Bencher) {
use using_u32::find_small_prime_factorization_str;
bencher.iter(|| {
for v in range("100000", "100010", "1") {
test::bench::black_box(find_small_prime_factorization_str(&v, SMALL_PRIME_LIMIT))
.unwrap();
}
});
}
#[cfg(test)]
mod tests {
use super::{using_bigint, using_smallbigint, using_u32};
use std::collections::BTreeSet;
#[test]
fn btreeset_duplicates() {
let mut bs = BTreeSet::<u8>::new();
bs.insert(5);
bs.insert(6);
bs.insert(5);
assert_eq!(bs.len(), 2); }
#[test]
fn works_using_u32() {
assert_eq!(
using_u32::find_small_prime_factorization_str("100000000", "1000000")
.unwrap()
.unwrap(),
vec!["2", "2", "2", "2", "2", "2", "2", "2", "5", "5", "5", "5", "5", "5", "5", "5"]
)
}
#[test]
fn works_using_smallbigint() {
assert_eq!(
using_smallbigint::find_small_prime_factorization_str("100000000", "1000000")
.unwrap()
.unwrap(),
vec!["2", "2", "2", "2", "2", "2", "2", "2", "5", "5", "5", "5", "5", "5", "5", "5"]
)
}
#[test]
fn works_using_bigint() {
assert_eq!(
using_bigint::find_small_prime_factorization_str("100000000", "1000000")
.unwrap()
.unwrap(),
vec!["2", "2", "2", "2", "2", "2", "2", "2", "5", "5", "5", "5", "5", "5", "5", "5"]
)
}
}