mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-04 23:17:46 +00:00
factor: Split the CLI and I/O code off the factoring logic
This commit is contained in:
parent
bb01e67521
commit
bd4d6fcac5
3 changed files with 73 additions and 61 deletions
|
@ -11,9 +11,6 @@ keywords = ["coreutils", "uutils", "cross-platform", "cli", "utility"]
|
||||||
categories = ["command-line-utilities"]
|
categories = ["command-line-utilities"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[lib]
|
|
||||||
path = "src/factor.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.5"
|
rand = "0.5"
|
||||||
uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" }
|
uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" }
|
||||||
|
@ -22,3 +19,6 @@ uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.co
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "factor"
|
name = "factor"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/cli.rs"
|
||||||
|
|
63
src/uu/factor/src/cli.rs
Normal file
63
src/uu/factor/src/cli.rs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
// * This file is part of the uutils coreutils package.
|
||||||
|
// *
|
||||||
|
// * (c) 2014 T. Jameson Little <t.jameson.little@gmail.com>
|
||||||
|
// * (c) 2020 nicoo <nicoo@debian.org>
|
||||||
|
// *
|
||||||
|
// * For the full copyright and license information, please view the LICENSE file
|
||||||
|
// * that was distributed with this source code.
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate uucore;
|
||||||
|
|
||||||
|
use std::error::Error;
|
||||||
|
use std::io::{self, stdin, stdout, BufRead, Write};
|
||||||
|
|
||||||
|
mod factor;
|
||||||
|
pub(crate) use factor::*;
|
||||||
|
|
||||||
|
mod miller_rabin;
|
||||||
|
mod numeric;
|
||||||
|
mod rho;
|
||||||
|
mod table;
|
||||||
|
|
||||||
|
static SYNTAX: &str = "[OPTION] [NUMBER]...";
|
||||||
|
static SUMMARY: &str = "Print the prime factors of the given number(s).
|
||||||
|
If none are specified, read from standard input.";
|
||||||
|
static LONG_HELP: &str = "";
|
||||||
|
|
||||||
|
fn print_factors_str(num_str: &str, w: &mut impl io::Write) -> Result<(), Box<dyn Error>> {
|
||||||
|
num_str
|
||||||
|
.parse::<u64>()
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
.and_then(|x| writeln!(w, "{}:{}", x, factor(x)).map_err(|e| e.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
|
let matches = app!(SYNTAX, SUMMARY, LONG_HELP).parse(args.collect_str());
|
||||||
|
let stdout = stdout();
|
||||||
|
let mut w = io::BufWriter::new(stdout.lock());
|
||||||
|
|
||||||
|
if matches.free.is_empty() {
|
||||||
|
let stdin = stdin();
|
||||||
|
|
||||||
|
for line in stdin.lock().lines() {
|
||||||
|
for number in line.unwrap().split_whitespace() {
|
||||||
|
if let Err(e) = print_factors_str(number, &mut w) {
|
||||||
|
show_warning!("{}: {}", number, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for number in &matches.free {
|
||||||
|
if let Err(e) = print_factors_str(number, &mut w) {
|
||||||
|
show_warning!("{}: {}", number, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(e) = w.flush() {
|
||||||
|
show_error!("{}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
// * This file is part of the uutils coreutils package.
|
// * This file is part of the uutils coreutils package.
|
||||||
// *
|
// *
|
||||||
// * (c) 2014 T. Jameson Little <t.jameson.little@gmail.com>
|
|
||||||
// * (c) 2020 nicoo <nicoo@debian.org>
|
// * (c) 2020 nicoo <nicoo@debian.org>
|
||||||
// *
|
// *
|
||||||
// * For the full copyright and license information, please view the LICENSE file
|
// * For the full copyright and license information, please view the LICENSE file
|
||||||
|
@ -8,48 +7,35 @@
|
||||||
|
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate uucore;
|
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::error::Error;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{self, stdin, stdout, BufRead, Write};
|
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
|
||||||
mod miller_rabin;
|
use crate::{miller_rabin, rho, table};
|
||||||
mod numeric;
|
|
||||||
mod rho;
|
|
||||||
mod table;
|
|
||||||
|
|
||||||
static SYNTAX: &str = "[OPTION] [NUMBER]...";
|
pub struct Factors {
|
||||||
static SUMMARY: &str = "Print the prime factors of the given number(s).
|
|
||||||
If none are specified, read from standard input.";
|
|
||||||
static LONG_HELP: &str = "";
|
|
||||||
|
|
||||||
struct Factors {
|
|
||||||
f: BTreeMap<u64, u8>,
|
f: BTreeMap<u64, u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Factors {
|
impl Factors {
|
||||||
fn one() -> Factors {
|
pub fn one() -> Factors {
|
||||||
Factors { f: BTreeMap::new() }
|
Factors { f: BTreeMap::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prime(p: u64) -> Factors {
|
pub fn prime(p: u64) -> Factors {
|
||||||
debug_assert!(miller_rabin::is_prime(p));
|
debug_assert!(miller_rabin::is_prime(p));
|
||||||
let mut f = Factors::one();
|
let mut f = Factors::one();
|
||||||
f.push(p);
|
f.push(p);
|
||||||
f
|
f
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(&mut self, prime: u64, exp: u8) {
|
pub fn add(&mut self, prime: u64, exp: u8) {
|
||||||
debug_assert!(exp > 0);
|
debug_assert!(exp > 0);
|
||||||
let n = *self.f.get(&prime).unwrap_or(&0);
|
let n = *self.f.get(&prime).unwrap_or(&0);
|
||||||
self.f.insert(prime, exp + n);
|
self.f.insert(prime, exp + n);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push(&mut self, prime: u64) {
|
pub fn push(&mut self, prime: u64) {
|
||||||
self.add(prime, 1)
|
self.add(prime, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +67,7 @@ impl fmt::Display for Factors {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn factor(mut n: u64) -> Factors {
|
pub fn factor(mut n: u64) -> Factors {
|
||||||
let mut factors = Factors::one();
|
let mut factors = Factors::one();
|
||||||
|
|
||||||
if n < 2 {
|
if n < 2 {
|
||||||
|
@ -109,43 +95,6 @@ fn factor(mut n: u64) -> Factors {
|
||||||
factors
|
factors
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_factors_str(num_str: &str, w: &mut impl io::Write) -> Result<(), Box<dyn Error>> {
|
|
||||||
num_str
|
|
||||||
.parse::<u64>()
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
.and_then(|x| writeln!(w, "{}:{}", x, factor(x)).map_err(|e| e.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
|
||||||
let matches = app!(SYNTAX, SUMMARY, LONG_HELP).parse(args.collect_str());
|
|
||||||
let stdout = stdout();
|
|
||||||
let mut w = io::BufWriter::new(stdout.lock());
|
|
||||||
|
|
||||||
if matches.free.is_empty() {
|
|
||||||
let stdin = stdin();
|
|
||||||
|
|
||||||
for line in stdin.lock().lines() {
|
|
||||||
for number in line.unwrap().split_whitespace() {
|
|
||||||
if let Err(e) = print_factors_str(number, &mut w) {
|
|
||||||
show_warning!("{}: {}", number, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for number in &matches.free {
|
|
||||||
if let Err(e) = print_factors_str(number, &mut w) {
|
|
||||||
show_warning!("{}: {}", number, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(e) = w.flush() {
|
|
||||||
show_error!("{}", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::factor;
|
use super::factor;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue