From f59a401a226b44259045921d311c7c1df5d9e2f1 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 8 Feb 2020 22:53:11 +0100 Subject: [PATCH] Add calculations for the numbers Add calculations for right-rotate self-multiples. The calculation for the end result is still missing. --- .gitignore | 3 ++ Cargo.lock | 74 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 13 ++++++++ src/main.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 182 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4ae822d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +.idea \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..edb6e89 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,74 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "euler-168" +version = "0.1.0" +dependencies = [ + "num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hermit-abi" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.66" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num_cpus" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" +"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" +"checksum num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..84f716a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "euler-168" +version = "0.1.0" +authors = ["trivernis "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +num_cpus = "1.12.0" +num-bigint = "0.2.6" +num-traits = "0.2.11" +num-integer = "0.1.42" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..20cf922 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,92 @@ +use num_bigint::{BigUint, ToBigUint}; +use num_integer::Integer; +use num_traits::ToPrimitive; +use std::sync::mpsc::*; +use std::ops::MulAssign; +use std::thread; +use std::time::Instant; + +fn main() { + let num_threads: u64 = num_cpus::get() as u64; + let (tx, rx) = channel::(); + let (sen_timing, rec_timing) = channel::(); + let end: BigUint = ubig_pow(10.to_biguint().unwrap(), 100); + println!("Starting {} threads...", num_threads); + for i in 0u64..num_threads { + let tx = tx.clone(); + let sen_timing = sen_timing.clone(); + let end = end.clone(); + thread::spawn(move || { + get_rotatable(tx, sen_timing, 10+i, end, num_threads); + }); + println!("Started thread {}", i); + } + // spawns a new thread to calculate the iterations / second + thread::spawn(move || { + let mut last_sent = Instant::now(); + let mut iterations = 0; + loop { + rec_timing.recv().unwrap(); + iterations += 1; + if last_sent.elapsed().as_secs() > 10 { + println!("{:.2} iter/sec", iterations as f64/last_sent.elapsed().as_secs() as f64); + last_sent = Instant::now(); + iterations = 0; + } + } + }); + loop { + println!("{}", rx.recv().unwrap()); + } +} + +/// searches for numbers according to [euler-168](https://projecteuler.net/problem=168) +/// the resulting numbers are sent via the tx-sender into a channel. +/// every iteration a timing-boolean is sent in via the sen_time-sender to calculate +/// the speed of the iterations +fn get_rotatable(tx: Sender, sen_time: Sender, start: u64, end: BigUint, step: u64) { + let mut num: BigUint = start.to_biguint().unwrap(); + let zero: BigUint = 0.to_biguint().unwrap(); + while num < end { + let mut digits = ubig_digits(num.clone()); + digits.rotate_right(1); + let num_rotated = ubig_from_digits(digits); + if (num_rotated % &num) == zero { + let _ = tx.send(num.clone()); + } + num += step; + let _ = sen_time.send(true); + } +} + +/// returns a vector containing the digits of the BigUint +fn ubig_digits(big_number: BigUint) -> Vec { + let mut num: BigUint = big_number; + let mut digits: Vec = vec![]; + let zero: BigUint = 0.to_biguint().unwrap(); + let ten: BigUint = 10.to_biguint().unwrap(); + while num > zero { + let (quot, rem) = num.div_rem(&ten); + num = quot; + digits.push(rem.to_u32().unwrap()); + } + digits +} + +/// returns a BigUint for a vector of digits +fn ubig_from_digits(digits: Vec) -> BigUint { + let mut num: BigUint = 0.to_biguint().unwrap(); + for (index, digit) in digits.iter().enumerate() { + num += digit * (10 as u32).pow(index as u32); + } + num +} + +/// returns ubig^exp +fn ubig_pow(ubig: BigUint, exp: usize) -> BigUint { + let mut num = ubig.clone(); + for _ in 0..exp { + num.mul_assign(ubig.clone()) + } + num +} \ No newline at end of file