a-conjecture-of-mine

An exercise on polyglossy: the same problem solved on multiple languages

commit 91bcaf293d5cfee408f6cdc4cde0515ed19e1d8b
parent b35f3b6b80ecaab097c95dba99993bcd877ed261
Author: Gark Garcia <37553739+GarkGarcia@users.noreply.github.com>
Date:   Mon, 10 Dec 2018 21:20:47 -0200

Optimized threading functionalities.

Shuffled the values in the range (0..max) to get an even distribution of calculations across different threads.

Diffstat:
MCargo.lock | 144++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
MCargo.toml | 7++++---
Msrc/main.rs | 46++++++++++++++++++++++++++--------------------
3 files changed, 166 insertions(+), 31 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -1,24 +1,52 @@
 [[package]]
+name = "bitflags"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "cloudabi"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "conjecture_tester"
 version = "0.1.0"
 dependencies = [
- "crossterm 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossterm 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "crossterm"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
  "termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "fuchsia-zircon"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "fuchsia-zircon-sys"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "libc"
-version = "0.2.43"
+version = "0.2.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -26,15 +54,101 @@ name = "num_cpus"
 version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rand_hc"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_isaac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "rand_pcg"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_xorshift"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc_version"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "termios"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -57,9 +171,23 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
-"checksum crossterm 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3069b1b614f818b56d12eabb91d3fe39bfedb40d99f111b07969ac86039ce60e"
-"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
+"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
+"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+"checksum crossterm 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c9d2256dbdfabccaf577d59b1a4058bd4a7cd28823e8bc31a74a5781df12d30e"
+"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
+"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
+"checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311"
 "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
+"checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a"
+"checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a"
+"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
+"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
+"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
+"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05"
+"checksum rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3"
+"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625"
 "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
 "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
diff --git a/Cargo.toml b/Cargo.toml
@@ -4,5 +4,6 @@ version = "0.1.0"
 authors = ["Gark Garcia <37553739+GarkGarcia@users.noreply.github.com>"]
 
 [dependencies]
-crossterm = "0.4.0"
-num_cpus = "1.0"-
\ No newline at end of file
+crossterm = "0.4.3"
+num_cpus = "1.0"
+rand = "0.6.1"+
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
@@ -5,17 +5,18 @@
 
 extern crate crossterm;
 extern crate num_cpus;
+extern crate rand;
 
 use std::io::{stdin, stdout, prelude::*};
 use std::sync::mpsc::{Sender, Receiver};
 use std::sync::mpsc;
 use std::thread;
-use std::ops::Range;
 use std::env;
 use std::process::Command;
 use std::time::Instant;
 use crossterm::terminal::{terminal,ClearType};
 use crossterm::Screen;
+use rand::prelude::*;
 
 fn main() {
     let args: Vec<String> = env::args().collect();
@@ -24,9 +25,9 @@ fn main() {
 
     // Assign the correct number of threads to run the application with
     // The default is the number of cores in the machine
-    let n_cores = num_cpus::get_physical() as i32;
+    let n_cores = num_cpus::get_physical() as i64;
     let n_threads = if args.len() == 0 { n_cores } else {
-        match args[0].trim().parse::<i32>() {
+        match args[0].trim().parse::<i64>() {
             Ok(n) => std::cmp::min(n.abs(), n_cores),
             Err(_) => n_cores
         }
@@ -40,7 +41,7 @@ For all A and B in N, S(A + B) = S(A) + S(B) - 9k, where k is an integer.");
     // Listen for user input
     let user_input = ask("\nWhat value would you like to test the conjecture for?");
 
-    match user_input.trim().parse::<i32>() {
+    match user_input.trim().parse::<i64>() {
         Ok(max) => {
             let start_time = Instant::now();
             println!("\nLOADING. . .");
@@ -71,26 +72,32 @@ For all A and B in N, S(A + B) = S(A) + S(B) - 9k, where k is an integer.");
     }
 }
 
-fn get_all_countrexpls(max: i32, n_threads: i32) -> Vec<[i32; 2]> {
+fn get_all_countrexpls(max: i64, n_threads: i64) -> Vec<[i64; 2]> {
     if n_threads < 1 { panic!("The number {} is not a valid number of threads.", n_threads) }
 
     if max / n_threads > 0 && n_threads > 1 {
 
         // Thread related variables
-        let (coutexpl_sender, coutexpl_reciever): (Sender<Vec<[i32; 2]>>, Receiver<Vec<[i32; 2]>>) = mpsc::channel();
+        let (coutexpl_sender, coutexpl_reciever): (Sender<Vec<[i64; 2]>>, Receiver<Vec<[i64; 2]>>) = mpsc::channel();
         let mut child_threads = Vec::new();
-        let range_lenght = ((max as f32) / n_threads as f32).ceil() as i32;
+        let range_lenght = ((max as f64) / n_threads as f64).ceil() as i64;
+        let mut range: Vec<i64> = (0..max).collect();
 
         // Conjecture related variables
-        let mut counterexpls: Vec<[i32; 2]> = Vec::new();
+        let mut counterexpls: Vec<[i64; 2]> = Vec::new();
+
+        // Shuffle the values in the range to get an even distribution of calculations across all threads
+        range.shuffle(&mut thread_rng());
 
         for i in 1..n_threads {
             let thread_countr_sd = coutexpl_sender.clone();
-            let end = std::cmp::min(i * (range_lenght + 1) + range_lenght, max);
-            let range = Range { start: i * (range_lenght + 1), end: end };
+
+            let start = (i - 1) * range_lenght;
+            let end = start + range_lenght - 1;
+            let thread_range = range[(start as usize)..(end as usize)].to_vec();
 
             let child = thread::spawn(move || {
-                thread_countr_sd.send(get_range_countrexpls(range, max))
+                thread_countr_sd.send(get_range_countrexpls(thread_range, max))
                     .expect(&*format!("Thread n°{} was unable to sent a message trought the channel", i));
             });
             child_threads.push(child);
@@ -107,16 +114,16 @@ fn get_all_countrexpls(max: i32, n_threads: i32) -> Vec<[i32; 2]> {
         return counterexpls;
 
     } else {
-        return get_range_countrexpls(0..max, max);
+        return get_range_countrexpls((0..max).collect(), max);
     }
 }
 
-fn get_range_countrexpls(range: Range<i32>, max: i32) -> Vec<[i32; 2]> {
+fn get_range_countrexpls(range: Vec<i64>, max: i64) -> Vec<[i64; 2]> {
     let mut counterexpls = Vec::new();
 
     for a in range {
         for b in a..max {
-            let difference: i32 = sum_digits(a + b) - sum_digits(a) - sum_digits(b);
+            let difference: i64 = sum_digits(a + b) - sum_digits(a) - sum_digits(b);
 
             if !is_multiple_of_nine(difference) {
                 counterexpls.push([a, b]);
@@ -127,23 +134,22 @@ fn get_range_countrexpls(range: Range<i32>, max: i32) -> Vec<[i32; 2]> {
     return counterexpls;
 }
 
-fn is_multiple_of_nine(n: i32) -> bool {
+fn is_multiple_of_nine(n: i64) -> bool {
     let floor = n / 9;
     let neerest_mult = floor * 9;
 
     return n == neerest_mult;
 }
 
-fn get_digits(n: i32) -> Vec<u32> {
-    return n.to_string().chars().map(|d| d.to_digit(10).unwrap()).collect();
+fn get_digits(n: i64) -> Vec<i64> {
+    return n.to_string().chars().map(|d| d.to_digit(10).unwrap() as i64).collect();
 }
 
-fn sum_digits(n: i32) -> i32 {
+fn sum_digits(n: i64) -> i64 {
     let mut sum = 0;
 
     for d in get_digits(n) {
-        let _d = d as i32;
-        sum += _d;
+        sum += d;
     }
 
     return sum;