diff --git a/.vscode/launch.json b/.vscode/launch.json index f8d62f6..125d88e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,15 +7,34 @@ { "type": "lldb", "request": "launch", - "name": "Debug executable 'tgm_acc_2019_expert_level3'", + "name": "Debug unit tests in library 'tgm_acc_2019_expert_level3'", "cargo": { "args": [ - "build", - "--bin=tgm_acc_2019_expert_level3", + "test", + "--no-run", + "--lib", "--package=tgm_acc_2019_expert_level3" ], "filter": { "name": "tgm_acc_2019_expert_level3", + "kind": "lib" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'level3'", + "cargo": { + "args": [ + "build", + "--bin=level3", + "--package=tgm_acc_2019_expert_level3" + ], + "filter": { + "name": "level3", "kind": "bin" } }, @@ -25,21 +44,135 @@ { "type": "lldb", "request": "launch", - "name": "Debug unit tests in executable 'tgm_acc_2019_expert_level3'", + "name": "Debug unit tests in executable 'level3'", "cargo": { "args": [ "test", "--no-run", - "--bin=tgm_acc_2019_expert_level3", + "--bin=level3", "--package=tgm_acc_2019_expert_level3" ], "filter": { - "name": "tgm_acc_2019_expert_level3", + "name": "level3", "kind": "bin" } }, "args": [], "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug benchmark 'initial'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bench=initial", + "--package=tgm_acc_2019_expert_level3" + ], + "filter": { + "name": "initial", + "kind": "bench" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug benchmark 'rayon'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bench=rayon", + "--package=tgm_acc_2019_expert_level3" + ], + "filter": { + "name": "rayon", + "kind": "bench" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug benchmark 'parallel'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bench=parallel", + "--package=tgm_acc_2019_expert_level3" + ], + "filter": { + "name": "parallel", + "kind": "bench" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug benchmark 'linear'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bench=linear", + "--package=tgm_acc_2019_expert_level3" + ], + "filter": { + "name": "linear", + "kind": "bench" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug benchmark 'cycle'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bench=cycle", + "--package=tgm_acc_2019_expert_level3" + ], + "filter": { + "name": "cycle", + "kind": "bench" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug benchmark 'hardcoded'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bench=hardcoded", + "--package=tgm_acc_2019_expert_level3" + ], + "filter": { + "name": "hardcoded", + "kind": "bench" + } + }, + "args": [], + "cwd": "${workspaceFolder}" } ] } \ No newline at end of file diff --git a/src/cycle.rs b/src/cycle.rs index 8c14c52..e94c2bc 100644 --- a/src/cycle.rs +++ b/src/cycle.rs @@ -3,7 +3,7 @@ use num::BigUint; use crate::generator::*; use crate::linear::LinearCalc; -pub fn m(n: usize) -> BigUint { +pub fn m(n: u128) -> BigUint { let mut s = S::new(); let n = n - 1; @@ -11,10 +11,10 @@ pub fn m(n: usize) -> BigUint { let (min, min_index, min_cycle, linear_sums) = { let mut min = s.next().unwrap(); let mut min_index = 0; - let min_cycle: usize; + let min_cycle; let mut i = 0; - let mut linear_calc = LinearCalc::new(min, Some(n + 1)); + let mut linear_calc = LinearCalc::new(min, Some((n + 1) as usize)); let mut linear_sums = vec![linear_calc.sum.clone()]; loop { @@ -59,12 +59,12 @@ pub fn m(n: usize) -> BigUint { let first_min_distance = n - min_index; let cycle_index = first_min_distance / cycle_width; let cycle_local_index = first_min_distance % cycle_width; - let mut cycle_local_sum = linear_sums[min_index + cycle_local_index].clone(); + let mut cycle_local_sum = linear_sums[(min_index + cycle_local_index) as usize].clone(); // Add sums consistent for every cycle + global minima for the prefix cycle_local_sum += { - let mut first_cycle_sum = linear_sums[min_cycle - 1].clone(); - let prefix_sum = linear_sums[min_index - 1].clone(); + let mut first_cycle_sum = linear_sums[(min_cycle - 1) as usize].clone(); + let prefix_sum = linear_sums[(min_index - 1) as usize].clone(); first_cycle_sum -= prefix_sum; first_cycle_sum *= cycle_index; diff --git a/src/hardcoded.rs b/src/hardcoded.rs index 81170c8..01bedcb 100644 --- a/src/hardcoded.rs +++ b/src/hardcoded.rs @@ -3,16 +3,16 @@ use num::BigUint; use crate::generator::*; use crate::{linear, linear::LinearCalc}; -const MIN: usize = 3; -const MIN_INDEX: usize = 2633996; -const MIN_CYCLE: usize = 8942944; -const CYCLE_WIDTH: usize = 6308948; -const FIRST_CYCLE_SUM: usize = 4638033462857199; -const MIN_FILL_STEP: usize = 119408474600112; - -pub fn m(n: usize) -> BigUint { +const MIN: u128 = 3; +const MIN_INDEX: u128 = 2633996; +const MIN_CYCLE: u128 = 8942944; +const CYCLE_WIDTH: u128 = 6308948; +const FIRST_CYCLE_SUM: u128 = 4638033462857199; +const MIN_FILL_STEP: u128 = 119408474600112; + +pub fn m(n: u128) -> BigUint { if n < MIN_INDEX { - return linear::m(n); + return linear::m(n as usize); } let n = n - 1; diff --git a/src/linear.rs b/src/linear.rs index 18a3341..80923f5 100644 --- a/src/linear.rs +++ b/src/linear.rs @@ -34,7 +34,7 @@ impl LinearCalc { if elem > self.min { if elem < self.last_elem { let mut local_min = usize::MAX; - + for &elem2 in self.local_buffer.iter().rev() { if elem2 < elem { break; @@ -71,7 +71,7 @@ pub fn m(n: usize) -> BigUint { for _i in 1..n { if _i & u16::MAX as usize == 0 { - print!("\r{}/{} {}%\x1B[0K", _i, n, (_i as f32)/(n as f32)*(100.0)); + print!("\r{}/{} {}%\x1B[0K", _i, n, (_i as f32) / (n as f32) * (100.0)); } linear_calc.next(s.next().unwrap()); diff --git a/src/main.rs b/src/main.rs index e83b3c7..40f74a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,15 @@ -const N: usize = 10; +const N: u128 = 10; use clap::{Parser, Subcommand, ValueEnum}; -use tgm_acc_2019_expert_level3::{initial, rayon, parallel, linear, cycle, hardcoded}; +use tgm_acc_2019_expert_level3::{cycle, hardcoded, initial, linear, parallel, rayon}; #[derive(Parser)] -#[command(author, version, about, long_about = "A collection of solutions for the problem S[0]=290797 S[n+1]=S[n]^2 mod 50515093 Let A(i,j) min S[i],S[i+1],…,S[j] for i≤j. Let M(N) = ∑A(i,j) for 1≤i≤j≤N. M(n)=?")] +#[command( + author, + version, + about, + long_about = "A collection of solutions for the problem S[0]=290797 S[n+1]=S[n]^2 mod 50515093 Let A(i,j) min S[i],S[i+1],…,S[j] for i≤j. Let M(N) = ∑A(i,j) for 1≤i≤j≤N. M(n)=?" +)] struct Cli { #[command(subcommand)] command: Commands, @@ -19,11 +24,11 @@ enum Commands { algorithm: Algorithms, /// The argument n for the function m #[arg(default_value_t = N)] - n: usize, + n: u128, }, } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +#[derive(Clone, Copy, PartialEq, Eq, ValueEnum)] enum Algorithms { /// The algorithm as the exercise puts it (WARNING doesn't scale well) /// time: O(n^4), mem: O(1)) @@ -63,15 +68,15 @@ fn main() { match command { Commands::Solve { algorithm, n } => { let result = match algorithm { - Algorithms::Initial | Algorithms::I => initial::m(n), - Algorithms::Rayon | Algorithms::R => rayon::m(n), - Algorithms::Parallel | Algorithms::P => parallel::m(n), - Algorithms::Linear | Algorithms::L => linear::m(n), + Algorithms::Initial | Algorithms::I => initial::m(n as usize), + Algorithms::Rayon | Algorithms::R => rayon::m(n as usize), + Algorithms::Parallel | Algorithms::P => parallel::m(n as usize), + Algorithms::Linear | Algorithms::L => linear::m(n as usize), Algorithms::Cycle | Algorithms::C => cycle::m(n), Algorithms::Hardcoded | Algorithms::H => hardcoded::m(n), }; println!("M({}) = {}", n, result); - }, + } }; }