1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-04 23:17:46 +00:00

Merge pull request #1547 from nbraud/factor/faster/display

factors: Speed up displaying the results
This commit is contained in:
Alex Lyon 2020-06-18 23:36:04 -07:00 committed by GitHub
commit 486022307c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -11,9 +11,10 @@ extern crate rand;
#[macro_use] #[macro_use]
extern crate uucore; extern crate uucore;
use std::collections::HashMap; use std::collections::BTreeMap;
use std::error::Error;
use std::fmt; use std::fmt;
use std::io::{stdin, BufRead}; use std::io::{self, stdin, stdout, BufRead, Write};
use std::ops; use std::ops;
mod miller_rabin; mod miller_rabin;
@ -27,12 +28,12 @@ static SUMMARY: &str = "Print the prime factors of the given number(s).
static LONG_HELP: &str = ""; static LONG_HELP: &str = "";
struct Factors { struct Factors {
f: HashMap<u64, u8>, f: BTreeMap<u64, u8>,
} }
impl Factors { impl Factors {
fn new() -> Factors { fn new() -> Factors {
Factors { f: HashMap::new() } Factors { f: BTreeMap::new() }
} }
fn add(&mut self, prime: u64, exp: u8) { fn add(&mut self, prime: u64, exp: u8) {
@ -63,12 +64,8 @@ impl ops::MulAssign<Factors> for Factors {
impl fmt::Display for Factors { impl fmt::Display for Factors {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// TODO: Use a representation with efficient in-order iteration for (p, exp) in self.f.iter() {
let mut primes: Vec<&u64> = self.f.keys().collect(); for _ in 0..*exp {
primes.sort();
for p in primes {
for _ in 0..self.f[&p] {
write!(f, " {}", p)? write!(f, " {}", p)?
} }
} }
@ -105,35 +102,40 @@ fn factor(mut n: u64) -> Factors {
factors factors
} }
fn print_factors(num: u64) { fn print_factors_str(num_str: &str, w: &mut impl io::Write) -> Result<(), Box<dyn Error>> {
print!("{}:{}", num, factor(num)); num_str
println!(); .parse::<u64>()
} .map_err(|e| e.into())
.and_then(|x| writeln!(w, "{}:{}", x, factor(x)).map_err(|e| e.into()))
fn print_factors_str(num_str: &str) {
if let Err(e) = num_str.parse::<u64>().and_then(|x| {
print_factors(x);
Ok(())
}) {
show_warning!("{}: {}", num_str, e);
}
} }
pub fn uumain(args: impl uucore::Args) -> i32 { pub fn uumain(args: impl uucore::Args) -> i32 {
let matches = app!(SYNTAX, SUMMARY, LONG_HELP).parse(args.collect_str()); 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() { if matches.free.is_empty() {
let stdin = stdin(); let stdin = stdin();
for line in stdin.lock().lines() { for line in stdin.lock().lines() {
for number in line.unwrap().split_whitespace() { for number in line.unwrap().split_whitespace() {
print_factors_str(number); if let Err(e) = print_factors_str(number, &mut w) {
show_warning!("{}: {}", number, e);
}
} }
} }
} else { } else {
for num_str in &matches.free { for number in &matches.free {
print_factors_str(num_str); if let Err(e) = print_factors_str(number, &mut w) {
show_warning!("{}: {}", number, e);
}
} }
} }
if let Err(e) = w.flush() {
show_error!("{}", e);
}
0 0
} }