Skip to content

Commit

Permalink
add alternate ramp bigint backend
Browse files Browse the repository at this point in the history
  • Loading branch information
tommilligan committed Apr 5, 2019
1 parent cc1c7ff commit 539e620
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 61 deletions.
135 changes: 135 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@ version = "0.1.0"
authors = ["Tom Milligan <tom@reinfer.io>"]
edition = "2018"

[features]
backend-num = ["num-bigint"]
backend-ramp = ["ramp"]
default = ["backend-num"]

[dependencies]
cairo-rs = { version = "0.6.0", features = ["png"] }
clap = "^2.32.0"
env_logger = "^0.6.1"
lazy_static = "^1.3.0"
log = "^0.4.6"
num-bigint = "^0.2.2"
num-bigint = { version = "^0.2.2", optional = true }
num-traits = "^0.2.6"
num_cpus = "^1.10.0"
png = "0.14.0"
ramp = { version = "0.5.1", optional = true }
threadpool = "^1.7.1"

8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
.PHONY: dev integrate test
.PHONY: build-ramp dev integrate test

build-ramp:
cargo +nightly build --no-default-features --features backend-ramp

dev:
rustup component add rustfmt
rustup toolchain install nightly

integrate:
./integrate/check

test:
cargo fmt -- --check
cargo test --locked
./test/check
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ Search for integers with high multiplicative persistence values.

This project uses the standard `rustup` and `cargo` toolchain. Originally tested against `rustc 1.33.0`.

By default the library uses `num-bigint` internally. This can be swapped for `ramp` as a dependency by specifying:

```
multiplicative-persistence = { version = "*", features = ["backend-ramp"], default-features = false }
```

Or as a binary by building with:

```bash
cargo +nightly build --no-default-features --features backend-ramp
```

## Usage

Build binaries with `cargo build --release --bins`, they will be output in `target/release`:
Expand Down
48 changes: 48 additions & 0 deletions src/backend/backend_num_bigint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
extern crate num_bigint;
extern crate num_traits;

use num_bigint::BigUint;
use num_traits::Num;

lazy_static! {
static ref BIG_UINT_NINE: BigUint = BigUint::from(9 as usize);
}

/// Multiply digits of an integer together and return the result.
fn multiply_digits(a: &BigUint) -> BigUint {
a.to_str_radix(10)
.chars()
.map(|c| BigUint::from(c.to_digit(10).expect("Could not convert char to digit.")))
.product()
}

/// Return the multiplicative persistence of a positive integer given as a string.
pub fn multiplicative_persistence(candidate: &str) -> usize {
let mut derived_int: BigUint =
Num::from_str_radix(candidate, 10).expect("Could not convert candidate to BigUint");

let mut counter: usize = 0;
while derived_int > *BIG_UINT_NINE {
derived_int = multiply_digits(&derived_int);
counter += 1;
}
counter
}

#[cfg(test)]
mod test {
use super::*;

/// Test helper to cut down on boilerplate
fn big(n: usize) -> BigUint {
BigUint::from(n)
}

#[test]
fn test_multiply_digits() {
assert_eq!(multiply_digits(&big(0)), big(0));
assert_eq!(multiply_digits(&big(3)), big(3));
assert_eq!(multiply_digits(&big(24)), big(8));
assert_eq!(multiply_digits(&big(12345)), big(120));
}
}
48 changes: 48 additions & 0 deletions src/backend/backend_ramp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
extern crate ramp;

use std::ops::Mul;

use ramp::Int;

lazy_static! {
static ref RAMP_NINE: Int = Int::from(9);
}

/// Multiply digits of an integer together and return the result.
fn multiply_digits(a: &Int) -> Int {
a.to_str_radix(10, false)
.chars()
.map(|c| Int::from(c.to_digit(10).expect("Could not convert char to digit.")))
.fold(Int::one(), Int::mul)
}

/// Return the multiplicative persistence of a positive integer given as a string.
pub fn multiplicative_persistence(candidate: &str) -> usize {
let mut derived_int =
Int::from_str_radix(candidate, 10).expect("Could not convert candidate to BigUint");

let mut counter: usize = 0;
while derived_int > *RAMP_NINE {
derived_int = multiply_digits(&derived_int);
counter += 1;
}
counter
}

#[cfg(test)]
mod test {
use super::*;

/// Test helper to cut down on boilerplate
fn big(n: usize) -> Int {
Int::from(n)
}

#[test]
fn test_multiply_digits() {
assert_eq!(multiply_digits(&big(0)), big(0));
assert_eq!(multiply_digits(&big(3)), big(3));
assert_eq!(multiply_digits(&big(24)), big(8));
assert_eq!(multiply_digits(&big(12345)), big(120));
}
}
Loading

0 comments on commit 539e620

Please sign in to comment.