From ceb7e5974e25d7177edb79e2d5b3c498b8e3aa57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ortega=20Froysa?= Date: Wed, 3 Dec 2025 21:39:22 +0100 Subject: [PATCH] Restructure code. I'm gonna rewrite this whole thing. --- Cargo.lock | 115 +------------------------------------------ Cargo.toml | 3 +- src/main.rs | 134 +++++++------------------------------------------- src/test.rs | 68 ------------------------- src/worker.rs | 36 ++++++++++++++ 5 files changed, 57 insertions(+), 299 deletions(-) delete mode 100644 src/test.rs create mode 100644 src/worker.rs diff --git a/Cargo.lock b/Cargo.lock index 7bd24c7..a69aa48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "ansi_term" @@ -22,24 +22,12 @@ dependencies = [ "winapi", ] -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - [[package]] name = "clap" version = "2.33.3" @@ -55,56 +43,6 @@ dependencies = [ "vec_map", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" -dependencies = [ - "cfg-if", - "lazy_static", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - [[package]] name = "heck" version = "0.3.2" @@ -127,7 +65,6 @@ dependencies = [ name = "indivisible" version = "2.0.0" dependencies = [ - "rayon", "structopt", ] @@ -143,25 +80,6 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213" -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -204,37 +122,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rayon" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - [[package]] name = "strsim" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index 5fff3e4..b2c6722 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,10 +6,9 @@ description = "A prime number generator and tester" edition = "2018" readme = "README" license = "GPL-3.0" -keywords = ["primes", "math"] +keywords = [ "primes", "math" ] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] structopt = "0.3.13" -rayon = "1.5" diff --git a/src/main.rs b/src/main.rs index 3acff9b..f29e545 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,142 +16,46 @@ * along with this program. If not, see . */ -use structopt::StructOpt; -use std::path::PathBuf; +use std::cell::RefCell; +use std::collections::VecDeque; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::collections::VecDeque; +use std::path::PathBuf; +use std::rc::Rc; +use structopt::StructOpt; -mod test; +mod worker; #[derive(StructOpt)] #[structopt(about = "A prime number generator and tester.")] -struct Opt -{ +struct Opt { #[structopt(short, long, help = "Print all found primes")] verbose:bool, #[structopt(short, long, name = "FILE", help = "Import prime numbers from FILE")] import:Option, #[structopt(short, long, help = "Test if n is prime instead of generation")] test:bool, - #[structopt(help = "Ordinal of the prime to generate")] + #[structopt(help = "Ordinal of the prime to generate or number to test for primality")] n:u64, + #[structopt(short, long, name = "n", help = "Number of threads to spawn")] + jobs:Option, } -fn main() -{ +fn main() { let opts = Opt::from_args(); - // get the first `n` primes - let n = opts.n; - let mut primes:VecDeque = VecDeque::new(); + let mut primes = Rc::new(RefCell::new(VecDeque::::new())); - if opts.import.is_some() - { + if opts.import.is_some() { let in_file = File::open(opts.import.unwrap()).unwrap(); let reader = BufReader::new(in_file); - reader.lines().into_iter().for_each(|x| { - primes.push_back(x.unwrap().parse().unwrap()); - }); - } - - if opts.test - { - let mut res:bool; - // if no primes were imported, test from beginning (2) - if primes.len() == 0 - { - res = test::is_prime(n); - } - // `n` should be in `primes` if the last prime is larger than `n` - else if primes.back().unwrap() >= &(n) - { - res = primes.contains(&(n)); - } - // we can memory test `n` if the last prime is >= sqrt(n) - else if primes.back().unwrap() >= &((n as f64).sqrt() as u64) - { - res = test::is_prime_mem(n, &primes) - } - /* - * if we have less primes than sqrt(n) then we can test all those - * prior to the last prime in the list, and then begin testing odd - * numbers. - */ - else - { - res = test::is_prime_mem(n, &primes); - if res - { - res = test::is_prime_f(n, primes.back().unwrap() + 2); - } - } - - if res - { - if opts.verbose - { - println!("true"); - } - std::process::exit(0); - } - else - { - if opts.verbose - { - println!("false"); - } - std::process::exit(1); + for p in reader.lines().into_iter() { + primes.borrow_mut().push_back(p.unwrap().parse().unwrap()); } } - else - { - // if `primes` already contains the nth prime, print it - if primes.len() >= n as usize - { - println!("{}", primes.get((n as usize) - 1).unwrap()); - } - else - { - let mut candidate:u64; - if primes.len() == 0 - { - // assume 2 as a prime - primes.push_back(2); - if opts.verbose - { - println!("{}", 2); - } - candidate = 3; - } - else if primes.len() == 1 - { - candidate = 3; - } - else - { - candidate = *primes.back().unwrap() + 2; - } - - while primes.len() < n as usize - { - if test::is_prime_mem(candidate, &primes) - { - primes.push_back(candidate); - if opts.verbose - { - println!("{}", candidate); - } - } - - candidate += 2; - } - - if !opts.verbose - { - println!("{}", primes.get((n as usize) - 1).unwrap()); - } - } - } + let jobs = match opts.jobs { + Some(n) => n, + None => 1, // TODO: use number of CPUs + }; } diff --git a/src/test.rs b/src/test.rs deleted file mode 100644 index a05116a..0000000 --- a/src/test.rs +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2021 Ortega Froysa, Nicolás - * Author: Ortega Froysa, Nicolás - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -use std::collections::VecDeque; -use rayon::prelude::*; - -pub fn is_prime_f(n:u64, b:u64) -> bool -{ - assert_ne!(b, 0); - assert_ne!(b, 1); - - if n == 1 - { - return false; - } - - let mut start = b; - if start == 2 - { - if n % 2 == 0 - { - return false; - } - else - { - start += 1; - } - } - // skip even numbers - else if start % 2 == 0 - { - start += 1; - } - - let limit = (n as f64).sqrt() as u64 + 1; - let composite = (start..limit).step_by(2).collect::>() - .par_iter().any(|x| n % x == 0); - return !composite; -} - -pub fn is_prime(n:u64) -> bool -{ - return is_prime_f(n, 2); -} - -pub fn is_prime_mem(n:u64, primes:&VecDeque) -> bool -{ - let limit = (n as f64).sqrt() as u64; - let pp = primes.partition_point(|x| *x < limit); - //let composite = primes.par_iter().take(pp+1).any(|x| n % *x == 0); - let composite = primes.iter().take(pp+1).any(|x| n % *x == 0); - return !composite; -} diff --git a/src/worker.rs b/src/worker.rs new file mode 100644 index 0000000..61d499e --- /dev/null +++ b/src/worker.rs @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2025 Nicolás Ortega Froysa + * Author: Nicolás Ortega Froysa + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +use std::cell::RefCell; +use std::collections::VecDeque; +use std::rc::Rc; + +pub struct Worker { + primes:Rc>>, +} + +impl Worker { + pub fn new(primes_list:Rc>>) -> Worker { + Worker { + primes: primes_list, + } + } + + pub fn run(&mut self) { + } +}