diff --git a/.gitignore b/.gitignore index a2f1da53e..c40dace37 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/src/*/gen_table /build/ /target/ /tmp/ diff --git a/Makefile b/Makefile index ddd4796f5..174ae078e 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ RUSTCTESTFLAGS := $(RUSTCFLAGS) # Handle config setup ifeq ($(ENABLE_LTO),y) -RUSTCBINFLAGS := $(RUSTCLIBFLAGS) -Z lto +RUSTCBINFLAGS := $(RUSTCLIBFLAGS) -C lto else RUSTCBINFLAGS := $(RUSTCLIBFLAGS) endif @@ -161,6 +161,7 @@ TEST_PROGS := \ cat \ cp \ env \ + factor \ mkdir \ mv \ nl \ @@ -305,6 +306,9 @@ $(BUILDDIR)/mkuutils: mkuutils.rs | $(BUILDDIR) $(SRCDIR)/cksum/crc_table.rs: $(SRCDIR)/cksum/gen_table.rs cd $(SRCDIR)/cksum && $(RUSTC) $(RUSTCBINFLAGS) gen_table.rs && ./gen_table && $(RM) gen_table +$(SRCDIR)/factor/prime_table.rs: $(SRCDIR)/factor/gen_table.rs + cd $(SRCDIR)/factor && $(RUSTC) $(RUSTCBINFLAGS) gen_table.rs && ./gen_table > $@ && $(RM) gen_table + crates: echo $(EXES) diff --git a/mkuutils.rs b/mkuutils.rs index 48f167360..2d9dfa01a 100644 --- a/mkuutils.rs +++ b/mkuutils.rs @@ -39,7 +39,11 @@ fn main() { util_map.push_str("map.insert(\"false\", uufalse as fn(Vec) -> i32);\n"); }, _ => { - crates.push_str(&(format!("extern crate {0} as uu{0};\n", prog))[..]); + if prog == "test" { + crates.push_str(&(format!("extern crate uu{0} as uu{0};\n", prog))[..]); + } else { + crates.push_str(&(format!("extern crate {0} as uu{0};\n", prog))[..]); + } util_map.push_str(&(format!("map.insert(\"{prog}\", uu{prog}::uumain as fn(Vec) -> i32);\n", prog = prog))[..]); } } diff --git a/src/cksum/cksum.rs b/src/cksum/cksum.rs index e288287f7..96f5b68ae 100644 --- a/src/cksum/cksum.rs +++ b/src/cksum/cksum.rs @@ -1,5 +1,5 @@ #![crate_name = "cksum"] -#![feature(collections, core, old_io, old_path, rustc_private)] +#![feature(rustc_private)] /* * This file is part of the uutils coreutils package. @@ -12,8 +12,9 @@ extern crate getopts; -use std::old_io::{EndOfFile, File, IoError, IoResult, print}; -use std::old_io::stdio::stdin_raw; +use std::io::{self, stdin, Read, Write, BufReader}; +use std::path::Path; +use std::fs::File; use std::mem; use crc_table::CRC_TABLE; @@ -43,20 +44,18 @@ fn crc_final(mut crc: u32, mut length: usize) -> u32 { } #[inline] -fn cksum(fname: &str) -> IoResult<(u32, usize)> { +fn cksum(fname: &str) -> io::Result<(u32, usize)> { let mut crc = 0u32; let mut size = 0usize; - let mut stdin_buf; - let mut file_buf; - let rd = match fname { + let file; + let mut rd : Box = match fname { "-" => { - stdin_buf = stdin_raw(); - &mut stdin_buf as &mut Reader + Box::new(stdin()) } _ => { - file_buf = try!(File::open(&Path::new(fname))); - &mut file_buf as &mut Reader + file = try!(File::open(&Path::new(fname))); + Box::new(BufReader::new(file)) } }; @@ -64,12 +63,14 @@ fn cksum(fname: &str) -> IoResult<(u32, usize)> { loop { match rd.read(&mut bytes) { Ok(num_bytes) => { + if num_bytes == 0 { + return Ok((crc_final(crc, size), size)); + } for &b in bytes[..num_bytes].iter() { crc = crc_update(crc, b); } size += num_bytes; } - Err(IoError { kind: EndOfFile, .. }) => return Ok((crc_final(crc, size), size)), Err(err) => return Err(err) } } @@ -81,7 +82,7 @@ pub fn uumain(args: Vec) -> i32 { getopts::optflag("V", "version", "output version information and exit"), ]; - let matches = match getopts::getopts(args.tail(), &opts) { + let matches = match getopts::getopts(&args[1..], &opts) { Ok(m) => m, Err(err) => panic!("{}", err), }; @@ -92,7 +93,7 @@ pub fn uumain(args: Vec) -> i32 { println!("Usage:"); println!(" {} [OPTIONS] [FILE]...", NAME); println!(""); - print(getopts::usage("Print CRC and size for each file.", opts.as_slice()).as_slice()); + println!("{}", getopts::usage("Print CRC and size for each file.", opts.as_ref())); return 0; } @@ -116,7 +117,7 @@ pub fn uumain(args: Vec) -> i32 { let mut exit_code = 0; for fname in files.iter() { - match cksum(fname.as_slice()) { + match cksum(fname.as_ref()) { Ok((crc, size)) => println!("{} {} {}", crc, size, fname), Err(err) => { show_error!("'{}' {}", fname, err); diff --git a/src/common/time.rs b/src/common/time.rs index 73a7da0f7..608601fe1 100644 --- a/src/common/time.rs +++ b/src/common/time.rs @@ -13,11 +13,11 @@ pub fn from_str(string: &str) -> Result { return Err("empty string".to_string()) } let slice = &string[..len - 1]; - let (numstr, times) = match string.char_at(len - 1) { - 's' | 'S' => (slice, 1usize), - 'm' | 'M' => (slice, 60usize), - 'h' | 'H' => (slice, 60usize * 60), - 'd' | 'D' => (slice, 60usize * 60 * 24), + let (numstr, times) = match string.chars().next_back().unwrap() { + 's' | 'S' => (slice, 1), + 'm' | 'M' => (slice, 60), + 'h' | 'H' => (slice, 60 * 60), + 'd' | 'D' => (slice, 60 * 60 * 24), val => { if !val.is_alphabetic() { (string, 1) diff --git a/src/factor/deps.mk b/src/factor/deps.mk new file mode 100644 index 000000000..ea0f8a6b8 --- /dev/null +++ b/src/factor/deps.mk @@ -0,0 +1 @@ +DEPLIBS += rand diff --git a/src/factor/factor.rs b/src/factor/factor.rs index e3822bf4e..64aeee8b6 100644 --- a/src/factor/factor.rs +++ b/src/factor/factor.rs @@ -1,10 +1,14 @@ #![crate_name = "factor"] -#![feature(collections, core, old_io, rustc_private)] +#![feature(rustc_private)] /* * This file is part of the uutils coreutils package. * * (c) T. Jameson Little +* (c) Wiktor Kuropatwa +* 20150223 added Pollard rho method implementation +* (c) kwantam +* 20150429 sped up trial division by adding table of prime inverses * * For the full copyright and license information, please view the LICENSE file * that was distributed with this source code. @@ -12,66 +16,153 @@ extern crate getopts; extern crate libc; +extern crate rand; -use std::vec::Vec; -use std::old_io::BufferedReader; -use std::old_io::stdio::stdin_raw; +use numeric::*; +use prime_table::P_INVS_U64; +use std::cmp::{max, min}; +use std::io::{stdin, BufRead, BufReader, Write}; +use std::num::Wrapping; +use std::mem::swap; +use rand::weak_rng; +use rand::distributions::{Range, IndependentSample}; #[path="../common/util.rs"] #[macro_use] mod util; +mod numeric; +mod prime_table; static VERSION: &'static str = "1.0.0"; static NAME: &'static str = "factor"; -fn factor(mut num: u64) -> Vec { - let mut ret = Vec::new(); +fn rho_pollard_pseudorandom_function(x: u64, a: u64, b: u64, num: u64) -> u64 { + if num < 1 << 63 { + (sm_mul(a, sm_mul(x, x, num), num) + b) % num + } else { + big_add(big_mul(a, big_mul(x, x, num), num), b, num) + } +} +fn gcd(mut a: u64, mut b: u64) -> u64 { + while b > 0 { + a %= b; + swap(&mut a, &mut b); + } + a +} + +fn rho_pollard_find_divisor(num: u64) -> u64 { + let range = Range::new(1, num); + let mut rng = rand::weak_rng(); + let mut x = range.ind_sample(&mut rng); + let mut y = x; + let mut a = range.ind_sample(&mut rng); + let mut b = range.ind_sample(&mut rng); + + loop { + x = rho_pollard_pseudorandom_function(x, a, b, num); + y = rho_pollard_pseudorandom_function(y, a, b, num); + y = rho_pollard_pseudorandom_function(y, a, b, num); + let d = gcd(num, max(x, y) - min(x, y)); + if d == num { + // Failure, retry with diffrent function + x = range.ind_sample(&mut rng); + y = x; + a = range.ind_sample(&mut rng); + b = range.ind_sample(&mut rng); + } else if d > 1 { + return d; + } + } +} + +fn rho_pollard_factor(num: u64, factors: &mut Vec) { + if is_prime(num) { + factors.push(num); + return; + } + let divisor = rho_pollard_find_divisor(num); + rho_pollard_factor(divisor, factors); + rho_pollard_factor(num / divisor, factors); +} + +fn table_division(mut num: u64, factors: &mut Vec) { if num < 2 { - return ret; + return; } while num % 2 == 0 { num /= 2; - ret.push(2); + factors.push(2); } - let mut i = 3; - while i * i <= num { - while num % i == 0 { - num /= i; - ret.push(i); + if is_prime(num) { + factors.push(num); + return; + } + for &(prime, inv, ceil) in P_INVS_U64 { + if num == 1 { + break; + } + + // inv = prime^-1 mod 2^64 + // ceil = floor((2^64-1) / prime) + // if (num * inv) mod 2^64 <= ceil, then prime divides num + // See http://math.stackexchange.com/questions/1251327/ + // for a nice explanation. + loop { + let Wrapping(x) = Wrapping(num) * Wrapping(inv); // x = num * inv mod 2^64 + if x <= ceil { + num = x; + factors.push(prime); + if is_prime(num) { + factors.push(num); + return; + } + } else { + break; + } } - i += 2; } - if num > 1 { - ret.push(num); - } - ret + + // do we still have more factoring to do? + // Decide whether to use Pollard Rho or slow divisibility based on + // number's size: + //if num >= 1 << 63 { + // number is too big to use rho pollard without overflowing + //trial_division_slow(num, factors); + //} else if num > 1 { + // number is still greater than 1, but not so big that we have to worry + rho_pollard_factor(num, factors); + //} } fn print_factors(num: u64) { print!("{}:", num); - for fac in factor(num).iter() { + + let mut factors = Vec::new(); + // we always start with table division, and go from there + table_division(num, &mut factors); + factors.sort(); + + for fac in factors.iter() { print!(" {}", fac); } println!(""); } fn print_factors_str(num_str: &str) { - let num = match num_str.parse::() { - Ok(x) => x, - Err(e)=> { crash!(1, "{} not a number: {}", num_str, e); } - }; - print_factors(num); + if let Err(e) = num_str.parse::().and_then(|x| Ok(print_factors(x))) { + show_warning!("{}: {}", num_str, e); + } } pub fn uumain(args: Vec) -> i32 { - let program = args[0].as_slice(); let opts = [ getopts::optflag("h", "help", "show this help message"), getopts::optflag("v", "version", "print the version and exit"), ]; - let matches = match getopts::getopts(args.tail(), &opts) { + let matches = match getopts::getopts(&args[1..], &opts) { Ok(m) => m, Err(f) => crash!(1, "Invalid options\n{}", f) }; @@ -83,22 +174,28 @@ pub fn uumain(args: Vec) -> i32 { \t{program} [NUMBER]...\n\ \t{program} [OPTION]\n\ \n\ - {usage}", program = program, version = VERSION, usage = getopts::usage("Print the prime factors of the given number(s). \ + {usage}", + program = &args[0][..], + version = VERSION, + usage = getopts::usage("Print the prime factors of the given number(s). \ If none are specified, read from standard input.", &opts)); return 1; } + if matches.opt_present("version") { - println!("{} {}", program, VERSION); + println!("{} {}", &args[0][..], VERSION); return 0; } if matches.free.is_empty() { - for line in BufferedReader::new(stdin_raw()).lines() { - print_factors_str(line.unwrap().as_slice().trim()); + for line in BufReader::new(stdin()).lines() { + for number in line.unwrap().split_whitespace() { + print_factors_str(number); + } } } else { for num_str in matches.free.iter() { - print_factors_str(num_str.as_slice()); + print_factors_str(num_str); } } 0 diff --git a/src/factor/gen_table.rs b/src/factor/gen_table.rs new file mode 100644 index 000000000..02826d0af --- /dev/null +++ b/src/factor/gen_table.rs @@ -0,0 +1,126 @@ +/* +* This file is part of the uutils coreutils package. +* +* (c) kwantam +* +* For the full copyright and license information, please view the LICENSE file +* that was distributed with this source code. +*/ + +//! Generate a table of the multiplicative inverses of p_i mod 2^64 +//! for the first 1027 odd primes (all 13 bit and smaller primes). +//! You can supply a commandline argument to override the default +//! value of 1027 for the number of entries in the table. +//! +//! 2 has no multiplicative inverse mode 2^64 because 2 | 2^64, +//! and in any case divisibility by two is trivial by checking the LSB. + +use sieve::Sieve; +use std::env::args; +use std::num::Wrapping; +use std::u64::MAX as MAX_U64; + +#[cfg(test)] +use numeric::is_prime; + +#[cfg(test)] +mod numeric; + +mod sieve; + +// extended Euclid algorithm +// precondition: a does not divide 2^64 +fn inv_mod_u64(a: u64) -> Option { + let mut t = 0u64; + let mut newt = 1u64; + let mut r = 0u64; + let mut newr = a; + + while newr != 0 { + let quot = if r == 0 { + // special case when we're just starting out + // This works because we know that + // a does not divide 2^64, so floor(2^64 / a) == floor((2^64-1) / a); + MAX_U64 + } else { + r + } / newr; + + let (tp, Wrapping(newtp)) = + (newt, Wrapping(t) - (Wrapping(quot) * Wrapping(newt))); + t = tp; + newt = newtp; + + let (rp, Wrapping(newrp)) = + (newr, Wrapping(r) - (Wrapping(quot) * Wrapping(newr))); + r = rp; + newr = newrp; + } + + if r > 1 { // not invertible + return None; + } + + Some(t) +} + +#[cfg_attr(test, allow(dead_code))] +fn main() { + // By default, we print the multiplicative inverses mod 2^64 of the first 1k primes + let n = args().skip(1).next().unwrap_or("1027".to_string()).parse::().ok().unwrap_or(1027); + + print!("{}", PREAMBLE); + let mut cols = 3; + + // we want a total of n + 1 values + let mut primes = Sieve::new().take(n + 1); + + // in each iteration of the for loop, we use the value yielded + // by the previous iteration. This leaves one value left at the + // end, which we call NEXT_PRIME. + let mut x = primes.next().unwrap(); + for next in primes { + // format the table + let outstr = format!("({}, {}, {}),", x, inv_mod_u64(x).unwrap(), MAX_U64 / x); + if cols + outstr.len() > MAX_WIDTH { + print!("\n {}", outstr); + cols = 4 + outstr.len(); + } else { + print!(" {}", outstr); + cols += 1 + outstr.len(); + } + + x = next; + } + + print!("\n];\n\n#[allow(dead_code)]\npub const NEXT_PRIME: u64 = {};\n", x); +} + +#[test] +fn test_generator_and_inverter() { + let num = 10000; + + let invs = Sieve::new().map(|x| inv_mod_u64(x).unwrap()); + assert!(Sieve::new().zip(invs).take(num).all(|(x, y)| { + let Wrapping(z) = Wrapping(x) * Wrapping(y); + is_prime(x) && z == 1 + })); +} + +const MAX_WIDTH: usize = 102; +const PREAMBLE: &'static str = +r##"/* +* This file is part of the uutils coreutils package. +* +* (c) kwantam +* +* For the full copyright and license information, please view the LICENSE file +* that was distributed with this source code. +*/ + +// *** NOTE: this file was automatically generated. +// Please do not edit by hand. Instead, modify and +// re-run src/factor/gen_tables.rs. + +pub const P_INVS_U64: &'static [(u64, u64, u64)] = &[ + "##; diff --git a/src/factor/numeric.rs b/src/factor/numeric.rs new file mode 100644 index 000000000..16a0652a1 --- /dev/null +++ b/src/factor/numeric.rs @@ -0,0 +1,132 @@ +/* +* This file is part of the uutils coreutils package. +* +* (c) Wiktor Kuropatwa +* (c) kwantam +* 20150507 added big_ routines to prevent overflow when num > 2^63 +* +* For the full copyright and license information, please view the LICENSE file +* that was distributed with this source code. +*/ + +use std::u64::MAX as MAX_U64; +use std::num::Wrapping; + +pub fn big_add(a: u64, b: u64, m: u64) -> u64 { + let Wrapping(msb_mod_m) = Wrapping(MAX_U64) - Wrapping(m) + Wrapping(1); + let msb_mod_m = msb_mod_m % m; + + let Wrapping(res) = Wrapping(a) + Wrapping(b); + let res = if b <= MAX_U64 - a { + res + } else { + (res + msb_mod_m) % m + }; + + res +} + +// computes (a + b) % m using the russian peasant algorithm +// CAUTION: Will overflow if m >= 2^63 +pub fn sm_mul(mut a: u64, mut b: u64, m: u64) -> u64 { + let mut result = 0; + while b > 0 { + if b & 1 != 0 { + result = (result + a) % m; + } + a = (a << 1) % m; + b >>= 1; + } + result +} + +// computes (a + b) % m using the russian peasant algorithm +// Only necessary when m >= 2^63; otherwise, just wastes time. +pub fn big_mul(mut a: u64, mut b: u64, m: u64) -> u64 { + // precompute 2^64 mod m, since we expect to wrap + let Wrapping(msb_mod_m) = Wrapping(MAX_U64) - Wrapping(m) + Wrapping(1); + let msb_mod_m = msb_mod_m % m; + + let mut result = 0; + while b > 0 { + if b & 1 != 0 { + let Wrapping(next_res) = Wrapping(result) + Wrapping(a); + let next_res = next_res % m; + result = if result <= MAX_U64 - a { + next_res + } else { + (next_res + msb_mod_m) % m + }; + } + let Wrapping(next_a) = Wrapping(a) << 1; + let next_a = next_a % m; + a = if a < 1 << 63 { + next_a + } else { + (next_a + msb_mod_m) % m + }; + b >>= 1; + } + result +} + +// computes a.pow(b) % m +fn pow(mut a: u64, mut b: u64, m: u64, mul: fn(u64, u64, u64) -> u64) -> u64 { + let mut result = 1; + while b > 0 { + if b & 1 != 0 { + result = mul(result, a, m); + } + a = mul(a, a, m); + b >>= 1; + } + result +} + +fn witness(mut a: u64, exponent: u64, m: u64) -> bool { + if a == 0 { + return false; + } + + let mul = if m < 1 << 63 { + sm_mul as fn(u64, u64, u64) -> u64 + } else { + big_mul as fn(u64, u64, u64) -> u64 + }; + + if pow(a, m-1, m, mul) != 1 { + return true; + } + a = pow(a, exponent, m, mul); + if a == 1 { + return false; + } + loop { + if a == 1 { + return true; + } + if a == m-1 { + return false; + } + a = mul(a, a, m); + } +} + +// uses deterministic (i.e., fixed witness set) Miller-Rabin test +pub fn is_prime(num: u64) -> bool { + if num < 2 { + return false; + } + if num % 2 == 0 { + return num == 2; + } + let mut exponent = num - 1; + while exponent & 1 == 0 { + exponent >>= 1; + } + + // These witnesses detect all composites up to at least 2^64. + // Discovered by Jim Sinclair, according to http://miller-rabin.appspot.com + let witnesses = [2, 325, 9375, 28178, 450775, 9780504, 1795265022]; + ! witnesses.iter().any(|&wit| witness(wit % num, exponent, num)) +} diff --git a/src/factor/prime_table.rs b/src/factor/prime_table.rs new file mode 100644 index 000000000..43f01eb4b --- /dev/null +++ b/src/factor/prime_table.rs @@ -0,0 +1,532 @@ +/* +* This file is part of the uutils coreutils package. +* +* (c) kwantam +* +* For the full copyright and license information, please view the LICENSE file +* that was distributed with this source code. +*/ + +// *** NOTE: this file was automatically generated. +// Please do not edit by hand. Instead, modify and +// re-run src/factor/gen_tables.rs. + +pub const P_INVS_U64: &'static [(u64, u64, u64)] = &[ + (3, 12297829382473034411, 6148914691236517205), (5, 14757395258967641293, 3689348814741910323), + (7, 7905747460161236407, 2635249153387078802), (11, 3353953467947191203, 1676976733973595601), + (13, 5675921253449092805, 1418980313362273201), (17, 17361641481138401521, 1085102592571150095), + (19, 9708812670373448219, 970881267037344821), (23, 15238614669586151335, 802032351030850070), + (29, 3816567739388183093, 636094623231363848), (31, 17256631552825064415, 595056260442243600), + (37, 1495681951922396077, 498560650640798692), (41, 10348173504763894809, 449920587163647600), + (43, 9437869060967677571, 428994048225803525), (47, 5887258746928580303, 392483916461905353), + (53, 2436362424829563421, 348051774975651917), (59, 14694863923124558067, 312656679215416129), + (61, 5745707170499696405, 302405640552615600), (67, 17345445920055250027, 275324538413575397), + (71, 1818693077689674103, 259813296812810586), (73, 9097024474706080249, 252695124297391118), + (79, 11208148297950107311, 233503089540627235), (83, 11779246215742243803, 222249928598910260), + (89, 17617676924329347049, 207266787345051141), (97, 11790702397628785569, 190172619316593315), + (101, 4200743699953660269, 182641030432767837), (103, 15760325033848937303, 179094602657374287), + (107, 8619973866219416643, 172399477324388332), (109, 12015769075535579493, 169236184162472950), + (113, 10447713457676206225, 163245522776190722), (127, 9150747060186627967, 145249953336295682), + (131, 281629680514649643, 140814840257324821), (137, 16292379802327414201, 134647766961383588), + (139, 4246732448623781667, 132710389019493177), (149, 16094474695182830269, 123803651501406386), + (151, 8062815290495565607, 122163868037811600), (157, 6579730370240349621, 117495185182863386), + (163, 2263404180823257867, 113170209041162893), (167, 10162278172342986519, 110459545351554201), + (173, 9809829218388894501, 106628578460748853), (179, 17107036403551874683, 103054436165975148), + (181, 3770881385233444253, 101915713114417412), (191, 2124755861893246783, 96579811904238490), + (193, 8124213711219232577, 95578984837873324), (197, 14513935692512591373, 93638294790403815), + (199, 2780916192016515319, 92697206400550510), (211, 13900627050804827995, 87425327363552377), + (223, 7527595115280579359, 82720825442643729), (227, 1950316554048586955, 81263189752024456), + (229, 2094390156840385773, 80553467570784068), (233, 7204522363551799129, 79170575423646144), + (239, 7255204782128442895, 77183029597111094), (241, 17298606475760824337, 76542506529915151), + (251, 2939720171109091891, 73493004277727297), (257, 18374966859414961921, 71777214294589695), + (263, 15430736487513693367, 70139711306880424), (269, 10354863773718001093, 68575256779589411), + (271, 15383631589145234927, 68069166323651481), (277, 17181443938689762877, 66594743948409933), + (281, 14245350405676059433, 65646776063023315), (283, 5149444458738708755, 65182841249857072), + (293, 2707201348701401773, 62958170900032599), (307, 17305088903023944187, 60087114246610917), + (311, 9134400602415662215, 59314289626075728), (313, 6365010734698503433, 58935284580541698), + (317, 17050145153302519317, 58191621683626345), (331, 3455281367280943203, 55730344633563600), + (337, 9196002980365592497, 54738112978366622), (347, 9941040754419844819, 53160645745560667), + (349, 15751088062938241781, 52856000211202153), (353, 8779186981255537313, 52257065364616293), + (359, 5600822016808749655, 51383688227603207), (367, 9751139919072624015, 50263607830271257), + (373, 3511310534137743069, 49455077945602015), (379, 17181268226964305331, 48672147951740241), + (383, 14834457375202459263, 48163822646761231), (389, 12661389891209383757, 47420935922132523), + (397, 185861401246443845, 46465350311610961), (401, 3220129888178724721, 46001855545410353), + (409, 2074694932495450793, 45102063749901104), (419, 1849076971589024267, 44025642180691053), + (421, 14897608040525528621, 43816494236839790), (431, 8046375605237577039, 42799870240625409), + (433, 7540585914657253201, 42602180308798040), (439, 15379290047785184263, 42019918163347497), + (443, 15615189678648040307, 41640505809728107), (449, 205420312624827969, 41084062524965593), + (457, 686202733595322489, 40364866682077793), (461, 3041111821262312197, 40014629227135686), + (463, 8127723090792113455, 39841779856824085), (467, 15247201739725667931, 39500522641776341), + (479, 8010277176057592351, 38510947961815347), (487, 2386334448960373207, 37878324586672590), + (491, 1051952818867347139, 37569743530976683), (499, 12494988971771199291, 36967422993405915), + (503, 17969989256695189447, 36673447462643243), (509, 5436172123882971989, 36241147492553146), + (521, 1805727346946616377, 35406418567580713), (523, 7195288319381928355, 35271021173440825), + (541, 13911777416032342069, 34097493666745936), (547, 13219604528142859659, 33723480939139948), + (557, 5133295029488295333, 33118032448311582), (563, 18151858289227516155, 32765087164670606), + (569, 6386658317259721737, 32419585366800617), (571, 1873749835858413299, 32306031652731263), + (577, 8184343991108570561, 31970093715267853), (587, 8107768264083584867, 31425458387920871), + (593, 13407330009728190129, 31107494222107169), (599, 16999336775772408167, 30795899956109435), + (601, 10926856722530117097, 30693417759916059), (607, 7810235958720518559, 30390023185682951), + (613, 10111102787547160429, 30092567820080834), (617, 5112468778937331161, 29897478239399597), + (619, 10400506755613301315, 29800878955912038), (631, 14909412801254946631, 29234142747558718), + (641, 18417966001831689601, 28778071877862015), (643, 12450835035754191915, 28688559990217032), + (647, 16650538700226241335, 28511196404496988), (653, 18023005695293558853, 28249225227732850), + (659, 13744083976011213723, 27992024391061535), (661, 3544230707051608253, 27907328401981167), + (673, 7016889276180750689, 27409723735081057), (677, 7711120491668837677, 27247775588935822), + (683, 18338710433453565955, 27008410063996415), (691, 16604739238563445883, 26695722248494285), + (701, 4578792394900801685, 26314898821268975), (709, 17796294705807240205, 26017974716092456), + (719, 7799457855921701935, 25656111368163493), (727, 3501582781529460967, 25373788271952615), + (733, 8027982755134170485, 25166090141486427), (739, 12755461734324196043, 24961764646426998), + (743, 8416482154761154775, 24827380987496031), (751, 73688724661955599, 24562908220651866), + (757, 11233750354002778461, 24368222026036395), (761, 8193166224591101769, 24240136759145271), + (769, 8635666926574042369, 23987963684927895), (773, 11955781087876436429, 23863834506739394), + (787, 1757948926973591323, 23439319026314550), (797, 3332912354597459765, 23145224684704581), + (809, 12062209660064712985, 22801908620160137), (811, 2229076349227541379, 22745677032934095), + (821, 4044353146489304861, 22468628591607249), (823, 5536264624794968711, 22414026821032261), + (827, 9502192231439261171, 22305615566758829), (829, 9813044796750195733, 22251802260204525), + (839, 17941052639030982263, 21986584116459537), (853, 13018686907823153661, 21625725760503577), + (857, 12247604875076703465, 21524788884141833), (859, 858986918449804499, 21474672961245112), + (863, 13637338028999645343, 21375137976488472), (877, 4964004106494246501, 21033915705484095), + (881, 14447506709261737361, 20938415520669184), (883, 17047047751015848379, 20890989890950794), + (887, 15763959422628906567, 20796780240935232), (907, 11979197639928253475, 20338196332645591), + (911, 16462352285319281519, 20248895799900715), (919, 16098246732442938407, 20072626848432591), + (929, 13264181960428396641, 19856559821000593), (937, 11792529028977610905, 19687026759561954), + (941, 1725094026021722149, 19603341204792297), (947, 18271431828024877947, 19479138409408185), + (953, 18137040080866579081, 19356499552685783), (967, 9614435380713147895, 19076260676018150), + (971, 10828675717831559651, 18997676697950104), (977, 12064963626510136625, 18881007240234955), + (983, 9326583728009813991, 18765762028188760), (991, 13160290676198438943, 18614272526447579), + (997, 11785933776281829869, 18502250826188115), (1009, 6965519813759503633, 18282204235589248), + (1013, 7775675932353384541, 18210013893099261), (1019, 10372899268140896051, 18102791043875909), + (1021, 7497942008412795221, 18067330140753723), (1031, 13544311604071901623, 17892089305246897), + (1033, 15464550210873641529, 17857448280454551), (1039, 1881958490676816623, 17754325383743553), + (1049, 8370495880920635433, 17585075380085368), (1051, 15691141010367591955, 17551611868420125), + (1061, 10466484384894580653, 17386186685871396), (1063, 5917535022704569239, 17353475139896097), + (1069, 13511506650808773541, 17256074905247475), (1087, 4836542834413267903, 16970325734783396), + (1091, 12613447368457676907, 16908106392034419), (1093, 12235946434985750157, 16877167496532069), + (1097, 14007418243755748857, 16815628143764404), (1103, 13546566364192871087, 16724156005176384), + (1109, 14687533829653321981, 16633673646266502), (1117, 17043007953507839989, 16514542590608372), + (1123, 10923494932339137867, 16426308168931034), (1129, 8610659102608444377, 16339011579902171), + (1151, 2852754513571068799, 16026710750399262), (1153, 16894849732729650049, 15998910731751562), + (1163, 14877941479913636643, 15861344861315177), (1171, 10554499171123313051, 15752983837497482), + (1181, 9918444103984390581, 15619597014148646), (1187, 6884505159775342347, 15540643701524474), + (1193, 17503532515875282841, 15462484554660143), (1201, 10275496907003905105, 15359487155461741), + (1213, 12439766407497455253, 15207538395473661), (1217, 6745111842892974913, 15157554703130280), + (1223, 5399782811437464823, 15083192210719175), (1229, 11572367518982965253, 15009555796346258), + (1231, 1168843247562424879, 14985169840543908), (1237, 12988774525627339901, 14912485104049758), + (1249, 2171073962238033697, 14769210627469616), (1259, 2754557494723904451, 14651901567680342), + (1277, 8710561218830743637, 14445375155606540), (1279, 10802667170608642815, 14422786609624356), + (1283, 17756608675784330667, 14377820790108769), (1289, 715544766241642809, 14310895324832856), + (1291, 10173572254439349923, 14288725076459761), (1297, 9401154844041645041, 14222624574949538), + (1301, 4069343235322552893, 14178896290322483), (1303, 17455744775812645543, 14157132827098658), + (1307, 11545093077501463827, 14113805718216948), (1319, 7286393982109686423, 13985401117293064), + (1321, 10375420777264342809, 13964227156479600), (1327, 17848997280062595535, 13901088224347815), + (1361, 8864195903163884465, 13553816365694012), (1367, 11915490136858474087, 13494326315808011), + (1373, 7241656996161287925, 13435356208091443), (1381, 10365440551193781357, 13357526483497140), + (1399, 11511084757933122631, 13185664098434275), (1409, 11062809611273648769, 13092082380205501), + (1423, 11991031811792927087, 12963277634370731), (1427, 10910337770294927515, 12926940486131430), + (1429, 4001742941112638909, 12908848197137544), (1433, 6539390083352723113, 12872815124710084), + (1439, 3589359513994909279, 12819141121410390), (1447, 15973580044476895767, 12748268191920906), + (1451, 6496406768894266627, 12713124792356686), (1453, 16301183338364118565, 12695625652931556), + (1459, 12921571242858918267, 12643416088903051), (1471, 15612641993044453951, 12540274693208396), + (1481, 7535638193514030201, 12455600319857901), (1483, 10846635760131307491, 12438802477214802), + (1487, 7517637463798243631, 12405342349502052), (1489, 9155234298503263025, 12388679700275051), + (1493, 17211195240909179773, 12355488328003718), (1499, 11419998999601376851, 12306033404742862), + (1511, 5310611298519956951, 12208301835678061), (1523, 3355054568888736571, 12112110356999048), + (1531, 13325995392242171187, 12048820426982071), (1543, 7651274275550300087, 11955116055547343), + (1549, 15826806245293734085, 11908808310980988), (1553, 14028077753413380849, 11878135269613362), + (1559, 9773579605442007463, 11832420829832938), (1567, 5579934072072959455, 11772012810280505), + (1571, 4004035473669609867, 11742039512227594), (1579, 17874299197451307139, 11682548495066213), + (1583, 11163601277709254863, 11653028473600474), (1597, 8663154699613126933, 11550872932817502), + (1601, 13918592655241185729, 11522013787451312), (1607, 1503748272343466871, 11478994445369976), + (1609, 4574425659049167865, 11464725962529242), (1613, 2904818967589724805, 11436295147991042), + (1619, 3999263230310100443, 11393912337065813), (1621, 9707015851248764669, 11379854456329149), + (1627, 10045368930120874451, 11337888182980670), (1637, 13127951646836669293, 11268628023035767), + (1657, 2237655738573095881, 11132615614791521), (1663, 5291098570751326591, 11092449833860223), + (1667, 12747839935760889899, 11065833277570216), (1669, 12312566146262696525, 11052572842246585), + (1693, 14633182097455361973, 10895891360726256), (1697, 3782832609104846177, 10870208646853006), + (1699, 15080946155610692875, 10857412639028576), (1709, 5137887758388383013, 10793881845353745), + (1721, 4062356771607158665, 10718619450150814), (1723, 2141235527998787187, 10706177639993935), + (1733, 18372233278258907149, 10644399350092066), (1741, 3401151549489239557, 10595487693112895), + (1747, 8806287668845887835, 10559097924275644), (1753, 5387754116223211881, 10522957258248460), + (1759, 4184338195230307615, 10487063145940620), (1777, 7816768873102584337, 10380835156842741), + (1783, 6114428349726497479, 10345902453005917), (1787, 17001559870956704819, 10322744305377477), + (1789, 18085851931406681685, 10311204065796283), (1801, 15916846357881534265, 10242500873797641), + (1811, 13751024019606788891, 10185943718227251), (1823, 16463440816196072671, 10118894170987137), + (1831, 11374316799136037015, 10074682727312698), (1847, 10307005892836089479, 9987408810887683), + (1861, 10526836220461872013, 9912275160510237), (1867, 12903828473628641891, 9880419964493600), + (1871, 5176130752911552431, 9859296672212480), (1873, 10567728986166763953, 9848768859428484), + (1877, 8451891264459357693, 9827780540069020), (1879, 13538084128603231335, 9817319890212640), + (1889, 13896091485912489121, 9765348900852065), (1901, 9383483176894863973, 9703705456975040), + (1907, 2843913349591299515, 9673174658473807), (1913, 12053544219622027977, 9642835375697622), + (1931, 10661090826649331747, 9552948769399042), (1933, 6680145293117788997, 9543064704453984), + (1949, 13790100623599187637, 9464722459573910), (1951, 7043989920509285471, 9455020027529242), + (1973, 17128451669050125981, 9349591522407274), (1979, 736378363730699635, 9321245110515185), + (1987, 11864589293508206827, 9283716192103448), (1993, 11727057070441546361, 9255767222132238), + (1997, 13994400236189269253, 9237227878672784), (1999, 2768395808960913199, 9227986029869710), + (2003, 16319336244939253851, 9209557700304319), (2011, 15043590393278798931, 9172920971511462), + (2017, 493864243916864545, 9145634146608602), (2027, 11384744369122175171, 9100515083231155), + (2029, 5309462069515218405, 9091544639580853), (2039, 9698337247188150727, 9046956387302379), + (2053, 11797649765601871053, 8985262578523892), (2063, 3818109413220542191, 8941708227682768), + (2069, 3798121302755084093, 8915777705997849), (2081, 15698790847928695777, 8864365244454373), + (2083, 13345772116697212811, 8855854092035310), (2087, 12993154666196952983, 8838880725304049), + (2089, 7205621428505023513, 8830418417285568), (2099, 9913257415504704251, 8788348772610553), + (2111, 6859637185154901951, 8738391318668664), (2113, 34920480972474305, 8730120243118576), + (2129, 5588609641870672049, 8664511072667708), (2131, 16317274790681607131, 8656379199300587), + (2137, 13327923654566002665, 8632074905806996), (2141, 15749952436590873589, 8615947722423891), + (2143, 11310789413371138975, 8607906707283971), (2153, 15473673849103321049, 8567925719326312), + (2161, 6700922766248032401, 8536207345538894), (2179, 4893170295825663531, 8465692553331597), + (2203, 10433337773872946579, 8373465308084226), (2207, 10364278500860826463, 8358289113597440), + (2213, 8552354007964753709, 8335627688074808), (2221, 17059708386942556965, 8305602914772423), + (2237, 16393440866577822357, 8246197619002928), (2239, 15110017253766555455, 8238831654180237), + (2243, 14104398611864414187, 8224139132282457), (2251, 6883725020842302691, 8194910739097979), + (2267, 13865572078341894995, 8137072815928342), (2269, 4089339915855400821, 8129900429135985), + (2273, 15021963607759076129, 8115593521209657), (2281, 16036779262676914009, 8087130238364555), + (2287, 14583171528319575567, 8065913455928968), (2293, 13072812524979512157, 8044807707679699), + (2297, 4946971854333950281, 8030798464827841), (2309, 9770622781354171341, 7989061963494825), + (2311, 191571552474698935, 7982148019779122), (2333, 13362622153694445877, 7906877014020382), + (2339, 9984428387052711563, 7886594302569282), (2341, 12907204952044530349, 7879856503079688), + (2347, 10532014085543587203, 7859712004137005), (2351, 17214868778272546255, 7846339461382199), + (2357, 1017427547552923933, 7826365750407107), (2371, 18298921156206185323, 7780153552808752), + (2377, 18058718325419489529, 7760514965801241), (2381, 17276874961937127301, 7747477561406783), + (2383, 10241310285152218543, 7740975272223899), (2389, 13551291690816351229, 7721533726960883), + (2393, 2227793162265800425, 7708626859051212), (2399, 3252593890445660831, 7689347258736786), + (2411, 9357265865676806979, 7651075932687495), (2417, 5975920814941902737, 7632082777703579), + (2423, 2047946411815051335, 7613183687044800), (2437, 499583548980234061, 7569447711821728), + (2441, 15590181492856536249, 7557043864690516), (2447, 5435268687022716271, 7538514129019023), + (2459, 7749282890663670931, 7501725934814783), (2467, 14722999222186504715, 7477399300247082), + (2473, 12524093530027633305, 7459257611690073), (2477, 11342103845078581797, 7447211979697033), + (2503, 16596910768675153911, 7369853804917919), (2521, 18227227087509120617, 7317232873347699), + (2531, 6646950057377760203, 7288322431335263), (2539, 3465575786986788547, 7265358043997460), + (2543, 3358569605240866063, 7253930032917637), (2549, 10949362017858984541, 7236855266265026), + (2551, 16769109959597197255, 7231181526346355), (2557, 13101011825520745301, 7214213560308780), + (2579, 13311124746480603163, 7152673157700485), (2591, 17656474451099840991, 7119546149637032), + (2593, 8330558160552983009, 7114054791249345), (2609, 14154994877564784337, 7070427011770621), + (2617, 2283815468048106505, 7048813172987983), (2621, 15624483725156506901, 7038055732052480), + (2633, 11910165182417864697, 7005979519069332), (2647, 13603341304072929639, 6968924848398017), + (2657, 5963776123190253985, 6942696301734870), (2659, 7978095406079723339, 6937474266156281), + (2663, 4419460277516595543, 6927053726515040), (2671, 3549841427887199375, 6906306279936185), + (2677, 15855793094361478621, 6890827072734236), (2683, 3417082297664423091, 6875417097916344), + (2687, 14849388697965671807, 6865182014778396), (2689, 8472193726675826049, 6860075892045203), + (2693, 575390457553509965, 6849886399446547), (2699, 12705630690265304355, 6834658789814580), + (2707, 16695427772659180443, 6814460315371094), (2711, 10390327628386014503, 6804405781523257), + (2713, 8540033378761222569, 6799389632771674), (2719, 7639218031260373343, 6784385462931059), + (2729, 2142769465506019737, 6759525127779242), (2731, 13509149815971843, 6754574907985921), + (2741, 5155128041029374877, 6729932168445659), (2749, 7414933503619154069, 6710347062098781), + (2753, 8831387101034939713, 6700597193501471), (2767, 16100067559815167023, 6666694641745410), + (2777, 11511777990543267177, 6642687819124793), (2789, 14842055826964587245, 6614106874761402), + (2791, 10931893478292941015, 6609367278290774), (2797, 5111271597112943333, 6595189157565088), + (2801, 3839504389493990929, 6585770822459675), (2803, 14017682795933408827, 6581071735180004), + (2819, 9318255963448883115, 6543719075455676), (2833, 8647114765226362353, 6511381600321055), + (2837, 12601265426453687357, 6502200942442563), (2843, 10822781960938280723, 6488478393847890), + (2851, 1067594799074737291, 6470271509543862), (2857, 17813989114233340185, 6456683259961341), + (2861, 1972982763563482277, 6447656090076739), (2879, 12129102650757964991, 6407344242344408), + (2887, 9181839706934750839, 6389589218465379), (2897, 7144372402727689649, 6367533335764429), + (2903, 2923011461903683687, 6354372743268877), (2909, 16893133795930644725, 6341266439913905), + (2917, 9106380344923467373, 6323875239530185), (2927, 5123745449923425167, 6302269926105074), + (2939, 12345949504248617907, 6276537622902195), (2953, 12487315070553807545, 6246780925739773), + (2957, 386776507463642949, 6238330765542628), (2963, 273930725360519835, 6225698303648178), + (2969, 15172431467833858217, 6213116899194864), (2971, 13150523038746829459, 6208934390343167), + (2999, 8051613201895899655, 6150965012907486), (3001, 12760893267917703817, 6146865735991186), + (3011, 3394053874737659115, 6126451037432597), (3019, 6091886002480431587, 6110216652437744), + (3023, 14938018356745280303, 6102131681676993), (3037, 15847071217750484085, 6074001999904363), + (3041, 16426761904506894369, 6066012520128099), (3049, 3817610859465636953, 6050096449232388), + (3061, 17295705812331399261, 6026378331822787), (3067, 4559058365788014387, 6014588873071259), + (3079, 17218558774875365815, 5991147799191150), (3083, 1352242672934920099, 5983374659004071), + (3089, 13579765627586766065, 5971752694629184), (3109, 5684136642847780781, 5933336787941316), + (3119, 3761503440487103183, 5914313585671545), (3121, 4604297863960186065, 5910523573761471), + (3137, 12819222850075493313, 5880377454163070), (3163, 17274503934975558611, 5832040491213895), + (3167, 14584984894401236895, 5824674478594743), (3169, 10111074299789678497, 5820998445474771), + (3181, 3635997653007195493, 5799039318990742), (3187, 11414176125935122619, 5788121767715579), + (3191, 11781405334446902599, 5780866209247744), (3203, 8730959730172863019, 5759208265285529), + (3209, 1965966492118624697, 5748440035434575), (3217, 17322851677549442161, 5734144878367905), + (3221, 10663718554873388733, 5727023928503431), (3229, 5541449907555981749, 5712834956243280), + (3251, 15479150363912536699, 5674175353340372), (3253, 9611814080829292957, 5670686773350615), + (3257, 10279656276875295113, 5663722466597958), (3259, 3792365305119791219, 5660246724059389), + (3271, 2227595203031266551, 5639481526661434), (3299, 7162861218072729803, 5591616875934995), + (3301, 14054396045252808941, 5588229043838095), (3307, 9131333549640924099, 5578090134172830), + (3313, 11926630185899746321, 5567987948599321), (3319, 17407412605862704327, 5557922287951055), + (3323, 9281659973289909811, 5551232041441333), (3329, 4327698144057422593, 5541226816974932), + (3331, 1030049353860695467, 5537899751939222), (3343, 7432774234904805871, 5518020961325022), + (3347, 16142967849386099995, 5511426373979549), (3359, 15481206175584169695, 5491736848380336), + (3361, 18139389813629892321, 5488468929993915), (3371, 2670427501622741379, 5472187503325289), + (3373, 306260796954561189, 5468942802760021), (3389, 6221489665461793301, 5443123066895707), + (3391, 9770083266405884607, 5439912731851828), (3407, 3021216082515388847, 5414365739274890), + (3413, 12685176777320925181, 5404847369970568), (3433, 445988860506231513, 5373359765135319), + (3449, 8824913807370472649, 5348432610527559), (3457, 1371366279127380609, 5336055560806928), + (3461, 4130663581948830541, 5329888492837200), (3463, 3861937468506908727, 5326810301388839), + (3467, 10822231740964876835, 5320664572745760), (3469, 13655589155746938181, 5317597023265941), + (3491, 1976248147684724235, 5284085956376268), (3499, 13986628187353941251, 5272004593800957), + (3511, 2553437089097932807, 5253985780036898), (3517, 14135335592450168213, 5245022483283921), + (3527, 8849416210013201399, 5230151424357684), (3529, 17944934090406599801, 5227187326072414), + (3533, 13136713300156589829, 5221269197200552), (3539, 10956500718546899547, 5212417087795860), + (3541, 16279603284479624061, 5209473051033479), (3547, 10453328330464110163, 5200660860927417), + (3557, 9894964209344341997, 5186039942004372), (3559, 14139566685327242711, 5183125617788578), + (3571, 16742060359253054267, 5165708225625749), (3581, 13120317552565827413, 5151282902460081), + (3583, 10631461488197104127, 5148407500337580), (3593, 16916788678784573497, 5134078506459658), + (3607, 1493332206687881639, 5114151392766717), (3613, 8536660971835696181, 5105658475978287), + (3617, 17268641258938496481, 5100012185156082), (3623, 12876570732103631255, 5091566125782376), + (3631, 2667182770227902671, 5080348133767433), (3637, 15180397308939424797, 5071967026040569), + (3643, 4501552424245893875, 5063613525585932), (3659, 720930418841340771, 5041471460428956), + (3671, 13738326967453531495, 5024991575513361), (3673, 8708590858647525865, 5022255397143901), + (3677, 10826237071271474677, 5016791970005317), (3691, 11394900159322074691, 4997763227772839), + (3697, 419130782307709585, 4989652170329876), (3701, 3982423268007006685, 4984259409270346), + (3709, 10165851951108741845, 4973508782342828), (3719, 3625859079828363063, 4960135540120879), + (3727, 11992610917788635247, 4949488616503770), (3733, 1319389410040302781, 4941533370937463), + (3739, 17015999013165082515, 4933603657049893), (3761, 13002477675991497297, 4904744502448697), + (3767, 783509172230827783, 4896932326442673), (3769, 9925708936450774921, 4894333795094070), + (3779, 10304598237523382763, 4881382395795065), (3793, 9454381882228148785, 4863365165755220), + (3797, 10522951715474029181, 4858241789230853), (3803, 6330002896710745427, 4850576932345398), + (3821, 16868077412599103205, 4827726792386692), (3823, 14620359545733701647, 4825201170209142), + (3833, 3157073861819323209, 4812612594236773), (3847, 15996448721054084791, 4795098537486236), + (3851, 15850500166165906595, 4790117910597131), (3853, 15722581764355610565, 4787631475138736), + (3863, 16379066055610603687, 4775237917087639), (3877, 7550937024755496109, 4757994344521421), + (3881, 4515435936620477721, 4753090459600502), (3889, 6147333586918894033, 4743312952869517), + (3907, 8753586770580370795, 4721459962556834), (3911, 10055857418856753783, 4716631059501291), + (3917, 18117085639918469509, 4709406197015458), (3919, 5671938404904314799, 4707002825646734), + (3923, 15126988448922668251, 4702203434542327), (3929, 10653006440123943145, 4695022670834703), + (3931, 4368842211300837587, 4692633954136238), (3943, 9408166962269822039, 4678352542153069), + (3947, 15553778636256748867, 4673611369067532), (3967, 9128046033953075327, 4650048922034169), + (3989, 3838254595432170429, 4624403127026711), (4001, 9935699444849808481, 4610533385081117), + (4003, 16838471857440594955, 4608229846042855), (4007, 10680420826305505303, 4603629666510993), + (4013, 14433784298890603557, 4596746592003376), (4019, 8147044222651021179, 4589884069099166), + (4021, 13845380157785482909, 4587601112586309), (4027, 1575783452037766515, 4580765848946995), + (4049, 715272615355001137, 4555876530923574), (4051, 9325828650446102619, 4553627270725636), + (4057, 2259805719653351529, 4546892796083202), (4073, 17463944303516825689, 4529031199044819), + (4079, 10862730881355808527, 4522369226209745), (4091, 1848732600885093171, 4509103904597788), + (4093, 7918624318961075541, 4506900579943696), (4099, 5944900932268923563, 4500303506638095), + (4111, 12196120260847132399, 4487167130554500), (4127, 250307164557241311, 4469770795665023), + (4129, 15189859493972505569, 4467605733521325), (4133, 14023631715363031981, 4463281895405166), + (4139, 13931993712108252803, 4456811808096050), (4153, 1159306574341004809, 4441787641153275), + (4157, 4406451013998937877, 4437513609263784), (4159, 7069995204013711295, 4435379676294674), + (4177, 13182554718703138993, 4416266237421487), (4201, 10204768680623898585, 4391036437445739), + (4211, 6965168149417759931, 4380608899004880), (4217, 12773178253552736713, 4374376114230389), + (4219, 7913867450441879219, 4372302458807668), (4229, 14778332684258207821, 4361963602201360), + (4231, 248514396644160823, 4359901695511593), (4241, 13549070452630335601, 4349621333107651), + (4243, 12334059141436247451, 4347571075585564), (4253, 17570599633810814389, 4337348712369986), + (4259, 15835007357004489483, 4331238336160965), (4261, 15078622297284761389, 4329205368155257), + (4271, 15401800366857471567, 4319069087733446), (4273, 14306695497372678225, 4317047524855968), + (4283, 11396237408133428339, 4306968030284742), (4289, 6829897316169449281, 4300942894313255), + (4297, 10826783466114845049, 4292935553574482), (4327, 3465958616114135767, 4263171729537682), + (4337, 4249088616471257105, 4253341958429686), (4339, 3804986389944698939, 4251381441278993), + (4349, 8788607431760448597, 4241605903359289), (4357, 1752800561513829325, 4233817781434370), + (4363, 4879106729557832355, 4227995432892402), (4373, 14042810661188908605, 4218327023487205), + (4391, 17963625064719208087, 4201034860785595), (4397, 15606524438071305893, 4195302268298738), + (4409, 3782231037113502985, 4183883890612282), (4421, 1969432979595319693, 4172527499142626), + (4423, 1259533508989438071, 4170640758243172), (4441, 1013511721230608105, 4153736562420525), + (4447, 10581885345633700511, 4148132240546334), (4451, 14928144721074321483, 4144404420065053), + (4457, 15160516836885368537, 4138825235294940), (4463, 8303721452852899215, 4133261051693827), + (4481, 14552385695283031681, 4116657905313446), (4483, 8295479824358343979, 4114821341447591), + (4493, 15778063092647631173, 4105663047787569), (4507, 8402743639522012307, 4092909712382860), + (4513, 662169851526910561, 4087468219301917), (4517, 3695882972483317293, 4083848588379356), + (4519, 2249204687898641943, 4082041175859604), (4523, 3597176270840553731, 4078431146077725), + (4547, 4819602366300186347, 4056904348737530), (4549, 1184095245003998477, 4055120702068487), + (4561, 12804733991967647537, 4044451671499572), (4567, 8667990536934683111, 4039138181237037), + (4583, 4512066355362951639, 4025036891492374), (4591, 9422264180537769231, 4018023104706937), + (4597, 13996572401370223197, 4012778784796508), (4603, 5570491910157783347, 4007548136804160), + (4621, 14482749945773264069, 3991937691778738), (4637, 16867413170698403893, 3978163483655283), + (4639, 13106373888110946783, 3976448388383175), (4643, 1326989558608440715, 3973022630564193), + (4649, 5773287293449644569, 3967895047044429), (4651, 16011504155142003843, 3966188792455289), + (4657, 2150865800305837777, 3961078821926036), (4663, 636913102266188679, 3955982001653345), + (4673, 5542313006524333505, 3947516386413342), (4679, 13912921529412482935, 3942454386345277), + (4691, 2355489170784911835, 3932369233363792), (4703, 18325151671777806751, 3922335546185318), + (4721, 2961794536723541649, 3907380655308102), (4723, 13908290418479719099, 3905726037202953), + (4729, 3237639581556127689, 3900770580188105), (4733, 18244075429755844309, 3897473922186678), + (4751, 1615206384900689007, 3882707656011271), (4759, 17136594988415618343, 3876180725721696), + (4783, 3089241480878392399, 3856730937426207), (4787, 11117371350042209403, 3853508266912377), + (4789, 7965727029532543901, 3851898950450939), (4793, 16872632175911261065, 3848684346695086), + (4799, 7976035414241991999, 3843872488791321), (4801, 15891633719821434177, 3842271208854311), + (4813, 13560062441883314693, 3832691475942146), (4817, 4702636853335131697, 3829508838220791), + (4831, 8923626764698659103, 3818411110269002), (4861, 4770120818895886933, 3794845520203569), + (4871, 11845907506171931319, 3787054829338852), (4877, 9005884281218462661, 3782395750196750), + (4889, 14832102874565810473, 3773111898897433), (4903, 17190123123144797335, 3762338175343575), + (4909, 5264593287281947813, 3757739676860776), (4919, 7211443149775049351, 3750100441900701), + (4931, 13205639136117363051, 3740974259523332), (4933, 8869993298771347341, 3739457545856385), + (4937, 15565958235988250361, 3736427805085993), (4943, 8564693030379004847, 3731892387964707), + (4951, 3968043312159295591, 3725862264938305), (4957, 9638302834558753013, 3721352445775580), + (4967, 16541533743568017495, 3713860292673555), (4969, 10357499691215465689, 3712365480722389), + (4973, 5515847262740016741, 3709379463846682), (4987, 7294361201795716019, 3698966126671255), + (4993, 964270018673781889, 3694521144343991), (4999, 13125638861809336887, 3690086832108331), + (5003, 9487002298951564323, 3687136532822216), (5009, 2938810495272553841, 3682719918887912), + (5011, 17154625301035025051, 3681250064599790), (5021, 14901412858587122357, 3673918357639823), + (5023, 8751461502617929823, 3672455519352887), (5039, 7526593731999769423, 3660794616731405), + (5051, 3031240859469199731, 3652097421047228), (5059, 14629044717082965227, 3646322212632842), + (5077, 14050336681708653949, 3633394538843717), (5081, 10953321564727753833, 3630534161328390), + (5087, 4587208817228736543, 3626252029429831), (5099, 15849222550876945603, 3617717998374103), + (5101, 7395332607476187621, 3616299563558037), (5107, 10818092520219327803, 3612050924948022), + (5113, 14341053724427042377, 3607812257717494), (5119, 4551325994353421311, 3603583526803975), + (5147, 12293050742728533523, 3583979808375665), (5153, 2233799398795800545, 3579806728839423), + (5167, 11445763789493482191, 3570107233154548), (5171, 5586463202364950267, 3567345595379917), + (5179, 3344563175364601075, 3561835117534186), (5189, 16850562133240176269, 3554970914185691), + (5197, 4678239116634440837, 3549498571042823), (5209, 4228337958151123945, 3541321572990891), + (5227, 12210777596142155843, 3529126472873455), (5231, 818131260772436623, 3526427848157054), + (5233, 5062014999015271569, 3525080082879715), (5237, 16544654747797167069, 3522387640578489), + (5261, 7296649765707959877, 3506318964780374), (5273, 10047230984201371561, 3498339479178750), + (5279, 6384201822820108127, 3494363340350360), (5281, 2997028292982919009, 3493039968511560), + (5297, 8566922866023314513, 3482488969928176), (5303, 12933244289280051463, 3478548759892429), + (5309, 6038885138464343701, 3474617455963373), (5323, 4168971091616116963, 3465478879148891), + (5333, 15983949815228171389, 3458980700114298), (5347, 6623854240045322443, 3449924083356938), + (5351, 13155069217954709207, 3447345182902177), (5381, 15004905930240978893, 3428125640904952), + (5387, 14803280978401037987, 3424307420402738), (5393, 17827633990761020401, 3420497695848238), + (5399, 7250229843380564647, 3416696438916382), (5407, 17075264303479989983, 3411641219476521), + (5413, 8267467416002100909, 3407859610882976), (5417, 6194319267136362265, 3405343192488379), + (5419, 9225074080042975619, 3404086376399621), (5431, 9948538647007047815, 3396564918746004), + (5437, 11023261264572803605, 3392816640373285), (5441, 6736570570568071873, 3390322380758969), + (5443, 1633534933589565291, 3389076625704492), (5449, 8693565568230157561, 3385344847441650), + (5471, 7279568717810075295, 3371731689583175), (5477, 14122183293968258157, 3368037990452720), + (5479, 17918155130549778007, 3366808555157793), (5483, 9891195983349641027, 3364352375288993), + (5501, 10026497869549456341, 3353343769080085), (5503, 305043378285947519, 3352125036109313), + (5507, 2599359615253061931, 3349690225841574), (5519, 8001722288903907695, 3342406971137806), + (5521, 12486050100244990833, 3341196173466682), (5527, 15569759562846943783, 3337569038123674), + (5531, 2498031334516082835, 3335155319781151), (5557, 15827618453022699677, 3319550850046707), + (5563, 1369495830027331443, 3315970532753829), (5569, 14359245027748411969, 3312397930276450), + (5573, 15080453256741560589, 3310020468995074), (5581, 13835884374224723717, 3305275770240019), + (5591, 16546310414890610151, 3299363991005106), (5623, 13912972010777557959, 3280587599806073), + (5639, 843990064021469111, 3271279317912670), (5641, 4133431042221037625, 3270119495428036), + (5647, 7993480210442229999, 3266644957271038), (5651, 5957407172981761051, 3264332697524252), + (5653, 3899497464723671357, 3263177794747842), (5657, 3759783616225404457, 3260870439050654), + (5659, 6816070305376687123, 3259717984398224), (5669, 14714442882574456237, 3253967908574625), + (5683, 2054687488766170363, 3245951798998689), (5689, 17999275154361350153, 3242528401073923), + (5693, 14694534406160691477, 3240250144688134), (5701, 11150233306087197837, 3235703222892396), + (5711, 16615312820024852655, 3230037484452731), (5717, 10486604554758797053, 3226647555310399), + (5737, 2205763715280591321, 3215399001866751), (5741, 2609084861148259173, 3213158695995393), + (5743, 346900289040681103, 3212039713339639), (5749, 2717758258902763997, 3208687436721090), + (5779, 4197520065223751579, 3192030467850761), (5783, 10344594679412082983, 3189822596180105), + (5791, 8043175407721743711, 3185416003058116), (5801, 10566890287353359769, 3179924853251086), + (5807, 10819633255563067471, 3176639241210530), (5813, 13007604327909074845, 3173360411785575), + (5821, 1191543681792611477, 3168999153703753), (5827, 819925641855289835, 3165736068939342), + (5839, 14295515830370906159, 3159230017761526), (5843, 14490938781161533787, 3157067272584212), + (5849, 649688712460962153, 3153828701266806), (5851, 1588986329370981715, 3152750653513852), + (5857, 16739703730880359713, 3149520927729136), (5861, 13656444725443737325, 3147371450897381), + (5867, 5499123126797001155, 3144152731158948), (5869, 2618186712114509541, 3143081287052232), + (5879, 15525512787330304711, 3137735001481468), (5881, 9798950601303968585, 3136667926153639), + (5897, 6043600059421206329, 3128157380652798), (5903, 9878054890224613359, 3124977820381086), + (5923, 2229928880090501259, 3114425810182264), (5927, 13031300394233489559, 3112323953721874), + (5939, 8684474899830258683, 3106035371899234), (5953, 167331459764877505, 3098730736386620), + (5981, 1761091935477036277, 3084224055126158), (5987, 4159529731001819723, 3081133134075422), + (6007, 5008596568040665671, 3070874658516655), (6011, 1224463630911680435, 3068831155167118), + (6029, 6296798690279359301, 3059668945713974), (6037, 9414347936243022781, 3055614390211951), + (6043, 12027167243159959187, 3052580518568517), (6047, 9465891658792911967, 3050561282240706), + (6053, 5250906994713622573, 3047537431638782), (6067, 12578569347772608379, 3040505039345566), + (6073, 2019938219828231817, 3037501082448468), (6079, 12930017519012403263, 3034503055388970), + (6089, 13023904216271532665, 3029519473429060), (6091, 3534288349042693603, 3028524720687826), + (6101, 4934451127404358013, 3023560739831101), (6113, 14047046239672495137, 3017625400574112), + (6121, 12365134934558126169, 3013681436645899), (6131, 13226535140764506427, 3008765955587922), + (6133, 12392073305671507037, 3007784782929977), (6143, 9690321199065720831, 3002888502964276), + (6151, 17867940365983012279, 2998982941588286), (6163, 5827650610337903131, 2993143610856652), + (6173, 16486422655865154101, 2988294844274996), (6197, 10207178542641609245, 2976721651397378), + (6199, 14244969169357577607, 2975761263705364), (6203, 16347211377266065651, 2973842346237232), + (6211, 13388813763368645739, 2970011926213097), (6217, 2222392039763302905, 2967145580458348), + (6221, 5610229832415764613, 2965237754976619), (6229, 9361078506501186813, 2961429454761526), + (6247, 17153375432076002135, 2952896442085729), (6257, 17739181571281823889, 2948177093448865), + (6263, 3572712847103574343, 2945352718139797), (6269, 15030462390893027541, 2942533749195972), + (6271, 15458083257430026111, 2941595291613706), (6277, 13198076730130571341, 2938783507043102), + (6287, 11343265880222860911, 2934109125768975), (6299, 12282210612023790995, 2928519459233140), + (6301, 3940536029711642037, 2927589918062141), (6311, 14059394548335120151, 2922951049549921), + (6317, 17115144374863334181, 2920174778171529), (6323, 9411544580387001979, 2917403775693429), + (6329, 17248827844558876041, 2914638027130597), (6337, 14927395235913299777, 2910958509343467), + (6343, 6293355537680509175, 2908204961959569), (6353, 3205604510841389105, 2903627274312852), + (6359, 12865436384164469479, 2900887572528628), (6361, 17086655570240005993, 2899975487141888), + (6367, 14680328603971461919, 2897242669029299), (6373, 10177114728254006509, 2894514996659273), + (6379, 9323138876569931715, 2891792455511765), (6389, 11153509525237125981, 2887266250384966), + (6397, 15969684020666483797, 2883655475021033), (6421, 14505156646653095485, 2872877133423072), + (6427, 10054293525782567187, 2870195125830022), (6449, 12242528242437103569, 2860403794961940), + (6451, 8564253371688126971, 2859516985538606), (6469, 15991550589791801741, 2851560376211091), + (6473, 5639750737196230905, 2849798250225483), (6481, 5610018912094048177, 2846280523639801), + (6491, 9128168535627034323, 2841895559037059), (6521, 8557184607111086281, 2828821357722673), + (6529, 14697497728815605377, 2825355195850750), (6547, 518436063779220635, 2817587303147938), + (6551, 13597821268805285415, 2815866901802709), (6553, 17436156385252092585, 2815007488739440), + (6563, 17465803393879499275, 2810718280315336), (6569, 10626043473118730905, 2808151023551461), + (6571, 18101446627192084739, 2807296313150137), (6577, 7505471665082371921, 2804735300852904), + (6581, 1345454665762131101, 2803030553671106), (6599, 7161775771608406007, 2795384766435755), + (6607, 3696608014770916655, 2792000011156281), (6619, 15353242650259241555, 2786938219324603), + (6637, 8357595213145189349, 2779379851395141), (6653, 1186713732684155733, 2772695637112513), + (6659, 12391092692852203691, 2770197337995127), (6661, 4536220806596043469, 2769365571792456), + (6673, 10526779774117484273, 2764385444883793), (6679, 13467034601498394023, 2761902092185888), + (6689, 17961376013166438881, 2757773071267685), (6691, 8973868175149393291, 2756948748125773), + (6701, 16605097784303240613, 2752834513312871), (6703, 14324228390818770127, 2752013139446449), + (6709, 9246743228481923101, 2749551956134975), (6719, 4530008590805292479, 2745459752003207), + (6733, 3843870776090078853, 2739751087733484), (6737, 5292794462591741617, 2738124398650668), + (6761, 3486901187132200409, 2728404684766979), (6763, 8150062293692760643, 2727597822521004), + (6779, 5891311538513228979, 2721160063978396), (6781, 6999479796734209749, 2720357480269805), + (6791, 11036536765054028599, 2716351652732962), (6793, 12073343758532705209, 2715551902503982), + (6803, 4238168600206971803, 2711560204866904), (6823, 627237963520535831, 2703611911726447), + (6827, 1680661317393780739, 2702027841469100), (6829, 6950281520230586661, 2701236502227200), + (6833, 3018214528670756433, 2699655213480104), (6841, 9284043245984795529, 2696498183556432), + (6857, 14225810509227958137, 2690206223378963), (6863, 14941782064075680815, 2687854301866465), + (6869, 9963229074605100669, 2685506489111886), (6871, 15958004187764455655, 2684724796057277), + (6883, 2355758832019569355, 2680044177496665), (6899, 17246194995713379899, 2673828681505950), + (6907, 17672231871396569139, 2670731732113732), (6911, 16193951135175206143, 2669185946130741), + (6917, 370695016082930125, 2666870619301655), (6947, 6718045560167722123, 2655353976350878), + (6949, 5802933162344089773, 2654589735747525), (6959, 7962928466363485135, 2650775121958550), + (6961, 12534563923092397521, 2650013514395855), (6967, 977012855346465415, 2647731315302074), + (6971, 3191331710356293107, 2646212031804554), (6977, 14766384642635494593, 2643936372898029), + (6983, 2826581148341575287, 2641664624618294), (6991, 16045580133346843567, 2638641692706272), + (6997, 9506782782592059901, 2636379030114270), (7001, 5401489123140205801, 2634872742995222), + (7013, 5523764801766727277, 2630364191317489), (7019, 1952689962496964931, 2628115696496588), + (7027, 4502087104939786683, 2625123676349729), (7039, 9670192588718318719, 2620648398026644), + (7043, 12207904888195402539, 2619160027503840), (7057, 13242341714242962801, 2613964017813454), + (7069, 10281535104033899189, 2609526676150735), (7079, 16080641005630970903, 2605840383346454), + (7103, 17083300368416363583, 2597035629129881), (7109, 12639483806870055693, 2594843729597629), + (7121, 11885081001289063729, 2590471011614878), (7127, 16831651004817344487, 2588290174506742), + (7129, 16953719619995087977, 2587564044565794), (7151, 7261583634106053391, 2579603422417780), + (7159, 5158595004269663687, 2576720781353478), (7177, 17238722656035942969, 2570258335475763), + (7187, 10628630472969424411, 2566682075095248), (7193, 9324671409983029289, 2564541091854518), + (7207, 6974799167595189143, 2559559327557867), (7211, 12552790621230449283, 2558139519305165), + (7213, 5431981756905460645, 2557430205699369), (7219, 9740821223019921147, 2555304623037754), + (7229, 13549897777202617109, 2551769826215182), (7237, 779978400795235981, 2548949022206653), + (7243, 1319261829377543523, 2546837508450856), (7247, 6600304592676813487, 2545431775039264), + (7253, 4702609925863637245, 2543326082132848), (7283, 11559925848195852475, 2532849659990327), + (7297, 1266523061659378561, 2527990143032691), (7307, 7389300657417251619, 2524530460340707), + (7309, 9509827838245668421, 2523839659831652), (7321, 7339894206626953129, 2519702782913475), + (7331, 7936302115465819915, 2516265730965700), (7333, 4512949525192272685, 2515579445480642), + (7349, 8313459841083961757, 2510102609022935), (7351, 7613579311608594695, 2509419680820235), + (7369, 10356110765766917497, 2503290008645616), (7393, 13329163646930396961, 2495163543042006), + (7411, 12017390418009676859, 2489103234881871), (7417, 16529197939041887561, 2487089668829655), + (7433, 16411720511158518073, 2481736051891504), (7451, 4867306247337669907, 2475740715838082), + (7457, 13959363927577175777, 2473748702388299), (7459, 7204097799532903051, 2473085410069654), + (7477, 16714817587184995613, 2467131747185977), (7481, 8879391178910318857, 2465812601752379), + (7487, 8327767459481539263, 2463836526473828), (7489, 2943498353329271489, 2463178538350854), + (7499, 7741285984793166947, 2459893862342919), (7507, 6275873766385266395, 2457272422233855), + (7517, 15651634122937278197, 2454003468632373), (7523, 10828236319221238859, 2452046267939592), + (7529, 4687026353168597721, 2450092186706010), (7537, 14956621073960338321, 2447491584676867), + (7541, 1223096676416228061, 2446193352832456), (7547, 11989039311189260723, 2444248585359686), + (7549, 8528167547654833109, 2443601016520009), (7559, 8011729169729919031, 2440368312436770), + (7561, 7380161463162464441, 2439722797739657), (7573, 10532645104281011645, 2435856869630206), + (7577, 8104686686205503145, 2434570948094173), (7583, 11637771811766648415, 2432644609482995), + (7589, 3417594171516092973, 2430721316867775), (7591, 14242704125413210647, 2430080894968983), + (7603, 2938183226787092859, 2426245439130547), (7607, 6697766153751252999, 2424969642922249), + (7621, 10459044894698723597, 2420514902730553), (7639, 12602900552518673895, 2414811372392924), + (7643, 8312257829367486035, 2413547569502754), (7649, 8303325904795657761, 2411654343536351), + (7669, 1820861294014621277, 2405364985488271), (7673, 17468270877045953609, 2404111048313508), + (7681, 13079152223072805377, 2401607092007492), (7687, 12399418060212989879, 2399732545038318), + (7691, 16966879154521046435, 2398484471942471), (7699, 12504683377151597595, 2395992216354013), + (7703, 16902131594475141543, 2394748029820790), (7717, 12155201971596873133, 2390403534237339), + (7723, 5099546626617880707, 2388546429329218), (7727, 11158286760776296655, 2387309961655176), + (7741, 15213023403508820245, 2382992387767672), (7753, 6999912429363278841, 2379304020857674), + (7757, 9407673012194790021, 2378077101161473), (7759, 4426838183431780527, 2377464115699130), + (7789, 8521168978971237221, 2368307109219354), (7793, 10912291823405752977, 2367091501823373), + (7817, 15223224513176451001, 2359823982820717), (7823, 5647443698905071727, 2358014070524038), + (7829, 13225389511525317821, 2356206932393607), (7841, 3761808924099167585, 2352600953157703), + (7853, 14765851680547337509, 2349005994360060), (7867, 16228538926419703411, 2344825737092862), + (7873, 17809437533883691329, 2343038749359780), (7877, 3187256402731839501, 2341848936614136), + (7879, 15749618908978823927, 2341254483273201), (7883, 13069271299209418467, 2340066481505715), + (7901, 7641588830939294069, 2334735359284843), (7907, 12420698804657854155, 2332963712369995), + (7919, 12818844884155027471, 2329428472497733), (7927, 7937661667140567751, 2327077592242910), + (7933, 17988656517612138069, 2325317543641693), (7937, 12066964247284867329, 2324145656256715), + (7949, 10178314191381317573, 2320637070538376), (7951, 5681810619609444335, 2320053335896057), + (7963, 6180574304741565203, 2316557085735219), (7993, 7117447607071219465, 2307862388803897), + (8009, 15818733711853814521, 2303251850881452), (8011, 6594866437037093475, 2302676828574404), + (8017, 12876135691215997361, 2300953483062186), (8039, 16092426444697734231, 2294656558491050), + (8053, 7540876877021214941, 2290667338098789), (8059, 6493784953110063027, 2288961915089905), + (8069, 14763796409470353741, 2286125179540160), (8081, 12739918163021037937, 2282730364275405), + (8087, 10456272391972868135, 2281036734723575), (8089, 11422888004105716905, 2280472749871374), + (8093, 18241602968231501493, 2279345616422779), (8101, 4561020661602299949, 2277094688767997), + (8111, 16802434375116035919, 2274287273296702), (8117, 16051417197561976477, 2272606144352538), + (8123, 11545395404498259315, 2270927498917832), (8147, 11443457045357563995, 2264237642532165), + (8161, 12755174219819017249, 2260353397097114), (8167, 10672323466178233303, 2258692797074758), + (8171, 17536936478347301059, 2257587085266130), (8179, 16031233265182478651, 2255378906187743), + (8191, 18442239924259250175, 2252074725150720), +]; + +#[allow(dead_code)] +pub const NEXT_PRIME: u64 = 8209; diff --git a/src/factor/sieve.rs b/src/factor/sieve.rs new file mode 100644 index 000000000..d0d5893fe --- /dev/null +++ b/src/factor/sieve.rs @@ -0,0 +1,53 @@ +/* +* This file is part of the uutils coreutils package. +* +* (c) kwantam +* +* For the full copyright and license information, please view the LICENSE file +* that was distributed with this source code. +*/ + +use std::iter::repeat; + +// A lazy Sieve of Eratosthenes +// Not particularly efficient, but fine for generating a few thousand primes. +pub struct Sieve { + inner: Box>, + filts: Vec, +} + +impl Iterator for Sieve { + type Item = u64; + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } + + #[inline] + fn next(&mut self) -> Option { + while let Some(n) = self.inner.next() { + if self.filts.iter().all(|&x| n % x != 0) { + self.filts.push(n); + return Some(n); + } + } + None + } +} + +impl Sieve { + #[inline] + pub fn new() -> Sieve { + fn next(s: &mut u64, t: u64) -> Option { + let ret = Some(*s); + *s = *s + t; + ret + } + let next = next; + + let odds_by_3 = Box::new(repeat(2).scan(3, next)) as Box>; + + Sieve { inner: odds_by_3, filts: Vec::new() } + } +} diff --git a/src/shuf/deps.mk b/src/shuf/deps.mk new file mode 100644 index 000000000..ea0f8a6b8 --- /dev/null +++ b/src/shuf/deps.mk @@ -0,0 +1 @@ +DEPLIBS += rand diff --git a/src/shuf/shuf.rs b/src/shuf/shuf.rs index c2265f97a..2af249287 100644 --- a/src/shuf/shuf.rs +++ b/src/shuf/shuf.rs @@ -1,5 +1,5 @@ #![crate_name = "shuf"] -#![feature(collections, core, old_io, old_path, rand, rustc_private)] +#![feature(rustc_private)] /* * This file is part of the uutils coreutils package. @@ -12,13 +12,13 @@ extern crate getopts; extern crate libc; +extern crate rand; -use std::cmp; -use std::old_io as io; -use std::old_io::IoResult; -use std::iter::{range_inclusive, RangeInclusive}; -use std::rand::{self, Rng}; -use std::usize; +use rand::read::ReadRng; +use rand::{Rng, ThreadRng}; +use std::fs::File; +use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write}; +use std::usize::MAX as MAX_USIZE; #[path = "../common/util.rs"] #[macro_use] @@ -27,15 +27,13 @@ mod util; enum Mode { Default, Echo, - InputRange(RangeInclusive) + InputRange((usize, usize)) } static NAME: &'static str = "shuf"; static VERSION: &'static str = "0.0.1"; pub fn uumain(args: Vec) -> i32 { - let program = args[0].clone(); - let opts = [ getopts::optflag("e", "echo", "treat each ARG as an input line"), getopts::optopt("i", "input-range", "treat each number LO through HI as an input line", "LO-HI"), @@ -47,7 +45,7 @@ pub fn uumain(args: Vec) -> i32 { getopts::optflag("h", "help", "display this help and exit"), getopts::optflag("V", "version", "output version information and exit") ]; - let mut matches = match getopts::getopts(args.tail(), &opts) { + let mut matches = match getopts::getopts(&args[1..], &opts) { Ok(m) => m, Err(f) => { crash!(1, "{}", f) @@ -62,7 +60,7 @@ Usage: {prog} -i LO-HI [OPTION]...\n {usage} With no FILE, or when FILE is -, read standard input.", - name = NAME, version = VERSION, prog = program, + name = NAME, version = VERSION, prog = &args[0][..], usage = getopts::usage("Write a random permutation of the input lines to standard output.", &opts)); } else if matches.opt_present("version") { println!("{} v{}", NAME, VERSION); @@ -76,10 +74,9 @@ With no FILE, or when FILE is -, read standard input.", } match parse_range(range) { Ok(m) => Mode::InputRange(m), - Err((msg, code)) => { - show_error!("{}", msg); - return code; - } + Err(msg) => { + crash!(1, "{}", msg); + }, } } None => { @@ -88,13 +85,19 @@ With no FILE, or when FILE is -, read standard input.", } else { if matches.free.len() == 0 { matches.free.push("-".to_string()); + } else if matches.free.len() > 1 { + show_error!("extra operand '{}'", &matches.free[1][..]); } Mode::Default } } }; let repeat = matches.opt_present("repeat"); - let zero = matches.opt_present("zero-terminated"); + let sep = if matches.opt_present("zero-terminated") { + 0x00 as u8 + } else { + 0x0a as u8 + }; let count = match matches.opt_str("head-count") { Some(cnt) => match cnt.parse::() { Ok(val) => val, @@ -103,102 +106,166 @@ With no FILE, or when FILE is -, read standard input.", return 1; } }, - None => usize::MAX + None => MAX_USIZE, }; let output = matches.opt_str("output"); let random = matches.opt_str("random-source"); - match shuf(matches.free, mode, repeat, zero, count, output, random) { - Err(f) => { - show_error!("{}", f); - return 1; + + match mode { + Mode::Echo => { + // XXX: this doesn't correctly handle non-UTF-8 cmdline args + let mut evec = matches.free.iter().map(|a| a.as_bytes()).collect::>(); + find_seps(&mut evec, sep); + shuf_bytes(&mut evec, repeat, count, sep, output, random); }, - _ => {} + Mode::InputRange((b, e)) => { + let rvec = (b..e).map(|x| format!("{}", x)).collect::>(); + let mut rvec = rvec.iter().map(|a| a.as_bytes()).collect::>(); + shuf_bytes(&mut rvec, repeat, count, sep, output, random); + }, + Mode::Default => { + let fdata = read_input_file(&matches.free[0][..]); + let mut fdata = vec!(&fdata[..]); + find_seps(&mut fdata, sep); + shuf_bytes(&mut fdata, repeat, count, sep, output, random); + } } } 0 } -fn shuf(input: Vec, mode: Mode, repeat: bool, zero: bool, count: usize, output: Option, random: Option) -> IoResult<()> { - match mode { - Mode::Echo => shuf_lines(input, repeat, zero, count, output, random), - Mode::InputRange(range) => shuf_lines(range.map(|num| num.to_string()).collect(), repeat, zero, count, output, random), - Mode::Default => { - let lines: Vec = input.into_iter().flat_map(|filename| { - let slice = filename.as_slice(); - let mut file_buf; - let mut stdin_buf; - let mut file = io::BufferedReader::new( - if slice == "-" { - stdin_buf = io::stdio::stdin_raw(); - &mut stdin_buf as &mut Reader - } else { - file_buf = crash_if_err!(1, io::File::open(&Path::new(slice))); - &mut file_buf as &mut Reader - } - ); - let mut lines = vec!(); - for line in file.lines() { - let mut line = crash_if_err!(1, line); - line.pop(); - lines.push(line); +fn read_input_file(filename: &str) -> Vec { + let mut file = BufReader::new( + if filename == "-" { + Box::new(stdin()) as Box + } else { + match File::open(filename) { + Ok(f) => Box::new(f) as Box, + Err(e) => crash!(1, "failed to open '{}': {}", filename, e), + } + }); + + let mut data = Vec::new(); + match file.read_to_end(&mut data) { + Err(e) => crash!(1, "failed reading '{}': {}", filename, e), + Ok(_) => (), + }; + + data +} + +fn find_seps(data: &mut Vec<&[u8]>, sep: u8) { + // need to use for loop so we don't borrow the vector as we modify it in place + // basic idea: + // * We don't care about the order of the result. This lets us slice the slices + // without making a new vector. + // * Starting from the end of the vector, we examine each element. + // * If that element contains the separator, we remove it from the vector, + // and then sub-slice it into slices that do not contain the separator. + // * We maintain the invariant throughout that each element in the vector past + // the ith element does not have any separators remaining. + for i in (0..data.len()).rev() { + if data[i].contains(&sep) { + let this = data.swap_remove(i); + let mut p = 0; + let mut i = 1; + loop { + if i == this.len() { + break; } - lines.into_iter() - }).collect(); - shuf_lines(lines, repeat, zero, count, output, random) + + if this[i] == sep { + data.push(&this[p..i]); + p = i + 1; + } + i += 1; + } + if p < this.len() { + data.push(&this[p..i]); + } } } } +fn shuf_bytes(input: &mut Vec<&[u8]>, repeat: bool, count: usize, sep: u8, output: Option, random: Option) { + let mut output = BufWriter::new( + match output { + None => Box::new(stdout()) as Box, + Some(s) => match File::create(&s[..]) { + Ok(f) => Box::new(f) as Box, + Err(e) => crash!(1, "failed to open '{}' for writing: {}", &s[..], e), + }, + }); + + let mut rng = match random { + Some(r) => WrappedRng::RngFile(rand::read::ReadRng::new(match File::open(&r[..]) { + Ok(f) => f, + Err(e) => crash!(1, "failed to open random source '{}': {}", &r[..], e), + })), + None => WrappedRng::RngDefault(rand::thread_rng()), + }; + + // we're generating a random usize. To keep things fair, we take this number mod ceil(log2(length+1)) + let mut len_mod = 1; + let mut len = input.len(); + while len > 0 { + len >>= 1; + len_mod <<= 1; + } + drop(len); + + let mut count = count; + while count > 0 && input.len() > 0 { + let mut r = input.len(); + while r >= input.len() { + r = rng.next_usize() % len_mod; + } + + // write the randomly chosen value and the separator + output.write_all(input[r]).unwrap_or_else(|e| crash!(1, "write failed: {}", e)); + output.write_all(&[sep]).unwrap_or_else(|e| crash!(1, "write failed: {}", e)); + + // if we do not allow repeats, remove the chosen value from the input vector + if !repeat { + // shrink the mask if we will drop below a power of 2 + if input.len() % 2 == 0 && len_mod > 2 { + len_mod >>= 1; + } + input.swap_remove(r); + } + + count -= 1; + } +} + +fn parse_range(input_range: String) -> Result<(usize, usize), String> { + let split: Vec<&str> = input_range.split('-').collect(); + if split.len() != 2 { + Err("invalid range format".to_string()) + } else { + let begin = match split[0].parse::() { + Ok(m) => m, + Err(e)=> return Err(format!("{} is not a valid number: {}", split[0], e)), + }; + let end = match split[1].parse::() { + Ok(m) => m, + Err(e)=> return Err(format!("{} is not a valid number: {}", split[1], e)), + }; + Ok((begin, end + 1)) + } +} + enum WrappedRng { - RngFile(rand::reader::ReaderRng), + RngFile(rand::read::ReadRng), RngDefault(rand::ThreadRng), } impl WrappedRng { - fn next_u32(&mut self) -> u32 { + fn next_usize(&mut self) -> usize { match self { - &mut WrappedRng::RngFile(ref mut r) => r.next_u32(), - &mut WrappedRng::RngDefault(ref mut r) => r.next_u32(), + &mut WrappedRng::RngFile(ref mut r) => r.next_u32() as usize, + &mut WrappedRng::RngDefault(ref mut r) => r.next_u32() as usize, } } } - -fn shuf_lines(mut lines: Vec, repeat: bool, zero: bool, count: usize, outname: Option, random: Option) -> IoResult<()> { - let mut output = match outname { - Some(name) => Box::new(io::BufferedWriter::new(try!(io::File::create(&Path::new(name))))) as Box, - None => Box::new(io::stdout()) as Box - }; - let mut rng = match random { - Some(name) => WrappedRng::RngFile(rand::reader::ReaderRng::new(try!(io::File::open(&Path::new(name))))), - None => WrappedRng::RngDefault(rand::thread_rng()), - }; - let mut len = lines.len(); - let max = if repeat { count } else { cmp::min(count, len) }; - for _ in range(0, max) { - let idx = rng.next_u32() as usize % len; - try!(write!(output, "{}{}", lines[idx], if zero { '\0' } else { '\n' })); - if !repeat { - lines.remove(idx); - len -= 1; - } - } - Ok(()) -} - -fn parse_range(input_range: String) -> Result, (String, i32)> { - let split: Vec<&str> = input_range.as_slice().split('-').collect(); - if split.len() != 2 { - Err(("invalid range format".to_string(), 1)) - } else { - let begin = match split[0].parse::() { - Ok(m) => m, - Err(e)=> return Err((format!("{} is not a valid number: {}", split[0], e), 1)) - }; - let end = match split[1].parse::() { - Ok(m) => m, - Err(e)=> return Err((format!("{} is not a valid number: {}", split[1], e), 1)) - }; - Ok(range_inclusive(begin, end)) - } -} diff --git a/src/sleep/sleep.rs b/src/sleep/sleep.rs index 886981bfe..5afc30951 100644 --- a/src/sleep/sleep.rs +++ b/src/sleep/sleep.rs @@ -1,5 +1,5 @@ #![crate_name = "sleep"] -#![feature(collections, core, old_io, rustc_private, std_misc)] +#![feature(rustc_private)] /* * This file is part of the uutils coreutils package. @@ -13,9 +13,9 @@ extern crate getopts; extern crate libc; -use std::f64; -use std::old_io::{print, timer}; -use std::time::duration::{self, Duration}; +use std::io::Write; +use std::thread::sleep_ms; +use std::u32::MAX as U32_MAX; #[path = "../common/util.rs"] #[macro_use] @@ -27,13 +27,11 @@ mod time; static NAME: &'static str = "sleep"; pub fn uumain(args: Vec) -> i32 { - let program = args[0].clone(); - let opts = [ getopts::optflag("h", "help", "display this help and exit"), getopts::optflag("V", "version", "output version information and exit") ]; - let matches = match getopts::getopts(args.tail(), &opts) { + let matches = match getopts::getopts(&args[1..], &opts) { Ok(m) => m, Err(f) => { show_error!("{}", f); @@ -45,20 +43,20 @@ pub fn uumain(args: Vec) -> i32 { println!("sleep 1.0.0"); println!(""); println!("Usage:"); - println!(" {0} NUMBER[SUFFIX]", program); + println!(" {0} NUMBER[SUFFIX]", &args[0][..]); println!("or"); - println!(" {0} OPTION", program); + println!(" {0} OPTION", &args[0][..]); println!(""); - print(getopts::usage("Pause for NUMBER seconds. SUFFIX may be 's' for seconds (the default), + println!("{}", getopts::usage("Pause for NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days. Unlike most implementations that require NUMBER be an integer, here NUMBER may be an arbitrary floating point number. Given two or more arguments, pause for the amount of time -specified by the sum of their values.", &opts).as_slice()); +specified by the sum of their values.", &opts)); } else if matches.opt_present("version") { println!("sleep 1.0.0"); } else if matches.free.is_empty() { show_error!("missing an argument"); - show_error!("for help, try '{0} --help'", program); + show_error!("for help, try '{0} --help'", &args[0][..]); return 1; } else { sleep(matches.free); @@ -68,19 +66,18 @@ specified by the sum of their values.", &opts).as_slice()); } fn sleep(args: Vec) { - let sleep_time = args.iter().fold(0.0, |result, arg| { - let num = match time::from_str(arg.as_slice()) { - Ok(m) => m, - Err(f) => { - crash!(1, "{}", f) - } - }; - result + num - }); - let sleep_dur = if sleep_time == f64::INFINITY { - duration::MAX + let sleep_time = args.iter().fold(0.0, |result, arg| + match time::from_str(&arg[..]) { + Ok(m) => m + result, + Err(f) => crash!(1, "{}", f), + }); + + let sleep_dur = if sleep_time > (U32_MAX as f64) { + U32_MAX } else { - Duration::seconds(sleep_time as i64) + (1000.0 * sleep_time) as u32 }; - timer::sleep(sleep_dur); + sleep_ms(sleep_dur); } + + diff --git a/src/tac/tac.rs b/src/tac/tac.rs index cefb42c9a..3ad69a7a2 100644 --- a/src/tac/tac.rs +++ b/src/tac/tac.rs @@ -1,5 +1,5 @@ #![crate_name = "tac"] -#![feature(collections, core, old_io, old_path, rustc_private)] +#![feature(rustc_private)] /* * This file is part of the uutils coreutils package. @@ -13,7 +13,8 @@ extern crate getopts; extern crate libc; -use std::old_io as io; +use std::fs::File; +use std::io::{stdin, stdout, BufReader, Read, Stdout, Write}; #[path = "../common/util.rs"] #[macro_use] @@ -23,8 +24,6 @@ static NAME: &'static str = "tac"; static VERSION: &'static str = "1.0.0"; pub fn uumain(args: Vec) -> i32 { - let program = args[0].clone(); - let opts = [ getopts::optflag("b", "before", "attach the separator before instead of after"), getopts::optflag("r", "regex", "interpret the sequence as a regular expression (NOT IMPLEMENTED)"), @@ -32,7 +31,7 @@ pub fn uumain(args: Vec) -> i32 { getopts::optflag("h", "help", "display this help and exit"), getopts::optflag("V", "version", "output version information and exit") ]; - let matches = match getopts::getopts(args.tail(), &opts) { + let matches = match getopts::getopts(&args[1..], &opts) { Ok(m) => m, Err(f) => crash!(1, "{}", f) }; @@ -40,7 +39,7 @@ pub fn uumain(args: Vec) -> i32 { println!("tac {}", VERSION); println!(""); println!("Usage:"); - println!(" {0} [OPTION]... [FILE]...", program); + println!(" {0} [OPTION]... [FILE]...", &args[0][..]); println!(""); print!("{}", getopts::usage("Write each file to standard output, last line first.", &opts)); } else if matches.opt_present("version") { @@ -63,41 +62,86 @@ pub fn uumain(args: Vec) -> i32 { } else { matches.free }; - tac(files, before, regex, separator.as_slice()); + tac(files, before, regex, &separator[..]); } 0 } fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { - for filename in filenames.into_iter() { - let mut file = io::BufferedReader::new( - if filename.as_slice() == "-" { - Box::new(io::stdio::stdin_raw()) as Box + let mut out = stdout(); + let sbytes = separator.as_bytes(); + let slen = sbytes.len(); + + for filename in filenames.iter() { + let mut file = BufReader::new( + if filename == "-" { + Box::new(stdin()) as Box } else { - let r = crash_if_err!(1, io::File::open(&Path::new(filename))); - Box::new(r) as Box + match File::open(filename) { + Ok(f) => Box::new(f) as Box, + Err(e) => { + show_warning!("failed to open '{}' for reading: {}", filename, e); + continue; + }, + } + }); + + let mut data = Vec::new(); + match file.read_to_end(&mut data) { + Err(e) => { + show_warning!("failed to read '{}': {}", filename, e); + continue; + }, + Ok(_) => (), + }; + + // find offsets in string of all separators + let mut offsets = Vec::new(); + let mut i = 0; + loop { + if i + slen > data.len() { + break; + } + + if &data[i..i+slen] == sbytes { + offsets.push(i); + i += slen; + } else { + i += 1; } - ); - let mut data = crash_if_err!(1, file.read_to_string()); - if data.as_slice().ends_with("\n") { - // removes blank line that is inserted otherwise - let mut buf = data.to_string(); - let len = buf.len(); - buf.truncate(len - 1); - data = buf.to_string(); } - let split_vec: Vec<&str> = data.as_slice().split_str(separator).collect(); - let rev: String = split_vec.iter().rev().fold(String::new(), |mut a, &b| { - if before { - a.push_str(separator); - a.push_str(b); + drop(i); + + // if there isn't a separator at the end of the file, fake it + if offsets.len() == 0 || *offsets.last().unwrap() < data.len() - slen { + offsets.push(data.len()); + } + + let mut prev = *offsets.last().unwrap(); + let mut start = true; + for off in offsets.iter().rev().skip(1) { + // correctly handle case of no final separator in file + if start && prev == data.len() { + show_line(&mut out, &[], &data[*off+slen..prev], before); + start = false; } else { - a.push_str(b); - a.push_str(separator); + show_line(&mut out, sbytes, &data[*off+slen..prev], before); } - a - }); - print!("{}", rev); + prev = *off; + } + show_line(&mut out, sbytes, &data[0..prev], before); + } +} + +fn show_line(out: &mut Stdout, sep: &[u8], dat: &[u8], before: bool) { + if before { + out.write_all(sep).unwrap_or_else(|e| crash!(1, "failed to write to stdout: {}", e)); + } + + out.write_all(dat).unwrap_or_else(|e| crash!(1, "failed to write to stdout: {}", e)); + + if !before { + out.write_all(sep).unwrap_or_else(|e| crash!(1, "failed to write to stdout: {}", e)); } } diff --git a/src/test/test.rs b/src/test/test.rs index 5251a997e..f9ef059e7 100644 --- a/src/test/test.rs +++ b/src/test/test.rs @@ -1,5 +1,5 @@ #![crate_name = "test"] -#![feature(core, os, std_misc)] +#![feature(convert)] /* * This file is part of the uutils coreutils package. @@ -13,16 +13,16 @@ extern crate libc; use std::collections::HashMap; -use std::ffi::CString; -use std::os::{args_as_bytes}; +use std::ffi::{CString, OsString}; +use std::env::{args_os}; use std::str::{from_utf8}; static NAME: &'static str = "test"; // TODO: decide how to handle non-UTF8 input for all the utils pub fn uumain(_: Vec) -> i32 { - let args = args_as_bytes(); - let args: Vec<&[u8]> = args.iter().map(|a| a.as_slice()).collect(); + let args = args_os().collect::>(); + let args = args.iter().map(|a| a.to_bytes().unwrap()).collect::>(); if args.len() == 0 { return 2; } @@ -30,7 +30,7 @@ pub fn uumain(_: Vec) -> i32 { if !args[0].ends_with(NAME.as_bytes()) { &args[1..] } else { - args.as_slice() + &args[..] }; let args = match args[0] { b"[" => match args[args.len() - 1] { @@ -83,6 +83,7 @@ fn two(args: &[&[u8]], error: &mut bool) -> bool { fn three(args: &[&[u8]], error: &mut bool) -> bool { match args[1] { b"=" => args[0] == args[2], + b"==" => args[0] == args[2], b"!=" => args[0] != args[2], b"-eq" => integers(args[0], args[2], IntegerCondition::Equal), b"-ne" => integers(args[0], args[2], IntegerCondition::Unequal), @@ -191,6 +192,7 @@ fn dispatch_four(args: &mut &[&[u8]], error: &mut bool) -> (bool, usize) { } } +#[derive(Clone, Copy)] enum Precedence { Unknown = 0, Paren, // FIXME: this is useless (parentheses have not been implemented) @@ -201,8 +203,6 @@ enum Precedence { UnOp } -impl Copy for Precedence {} - fn parse_expr(mut args: &[&[u8]], error: &mut bool) -> bool { if args.len() == 0 { false diff --git a/src/touch/touch.rs b/src/touch/touch.rs index 8119f6114..48687828a 100644 --- a/src/touch/touch.rs +++ b/src/touch/touch.rs @@ -1,5 +1,5 @@ #![crate_name = "touch"] -#![feature(collections, core, old_io, old_path, rustc_private)] +#![feature(rustc_private, path_ext, fs_time)] /* * This file is part of the uutils coreutils package. @@ -10,11 +10,19 @@ * that was distributed with this source code. */ +extern crate libc; extern crate getopts; extern crate time; -use std::old_io::File; -use std::old_io::fs::PathExtensions; +use libc::types::os::arch::c95::c_char; +use libc::types::os::arch::posix01::stat as stat_t; +use libc::funcs::posix88::stat_::stat as c_stat; +use libc::funcs::posix01::stat_::lstat as c_lstat; + +use std::fs::{set_file_times, File, PathExt}; +use std::io::{Error, Write}; +use std::mem::uninitialized; +use std::path::Path; #[path = "../common/util.rs"] #[macro_use] @@ -40,7 +48,7 @@ pub fn uumain(args: Vec) -> i32 { getopts::optflag("V", "version", "output version information and exit"), ]; - let matches = match getopts::getopts(args.tail(), &opts) { + let matches = match getopts::getopts(&args[1..], &opts) { Ok(m) => m, Err(e) => panic!("Invalid options\n{}", e) }; @@ -71,14 +79,12 @@ pub fn uumain(args: Vec) -> i32 { let (mut atime, mut mtime) = if matches.opt_present("reference") { - let path = Path::new(matches.opt_str("reference").unwrap().to_string()); - let stat = stat(&path, !matches.opt_present("no-dereference")); - (stat.accessed, stat.modified) + stat(&matches.opt_str("reference").unwrap()[..], !matches.opt_present("no-dereference")) } else if matches.opts_present(&["date".to_string(), "t".to_string()]) { let timestamp = if matches.opt_present("date") { - parse_date(matches.opt_str("date").unwrap().as_slice()) + parse_date(matches.opt_str("date").unwrap().as_ref()) } else { - parse_timestamp(matches.opt_str("t").unwrap().as_slice()) + parse_timestamp(matches.opt_str("t").unwrap().as_ref()) }; (timestamp, timestamp) } else { @@ -88,17 +94,20 @@ pub fn uumain(args: Vec) -> i32 { }; for filename in matches.free.iter() { - let path = Path::new(filename.to_string()); + let path = &filename[..]; - if !path.exists() { + if ! Path::new(path).exists() { // no-dereference included here for compatibility if matches.opts_present(&["no-create".to_string(), "no-dereference".to_string()]) { continue; } - match File::create(&path) { - Ok(fd) => fd, - Err(e) => panic!("Unable to create file: {}\n{}", filename, e.desc) + match File::create(path) { + Err(e) => { + show_warning!("cannot touch '{}': {}", path, e); + continue; + }, + _ => (), }; // Minor optimization: if no reference time was specified, we're done. @@ -110,44 +119,62 @@ pub fn uumain(args: Vec) -> i32 { // If changing "only" atime or mtime, grab the existing value of the other. // Note that "-a" and "-m" may be passed together; this is not an xor. if matches.opts_present(&["a".to_string(), "m".to_string(), "time".to_string()]) { - let stat = stat(&path, !matches.opt_present("no-dereference")); + let st = stat(path, !matches.opt_present("no-dereference")); let time = matches.opt_strs("time"); if !(matches.opt_present("a") || time.contains(&"access".to_string()) || time.contains(&"atime".to_string()) || time.contains(&"use".to_string())) { - atime = stat.accessed; + atime = st.0; } if !(matches.opt_present("m") || time.contains(&"modify".to_string()) || time.contains(&"mtime".to_string())) { - mtime = stat.modified; + mtime = st.1; } } - match std::old_io::fs::change_file_times(&path, atime, mtime) { - Ok(t) => t, - Err(e) => panic!("Unable to modify times\n{}", e.desc) - } + // this follows symlinks and thus does not work correctly for the -h flag + // need to use lutimes() c function on supported platforms + match set_file_times(path, atime, mtime) { + Err(e) => show_warning!("cannot touch '{}': {}", path, e), + _ => (), + }; } 0 } -fn stat(path: &Path, follow: bool) -> std::old_io::FileStat { - if follow { - match std::old_io::fs::stat(path) { - Ok(stat) => stat, - Err(e) => panic!("Unable to open file\n{}", e.desc) - } +fn stat(path: &str, follow: bool) -> (u64, u64) { + let stat_fn = if follow { + c_stat } else { - match std::old_io::fs::lstat(path) { - Ok(stat) => stat, - Err(e) => panic!("Unable to open file\n{}", e.desc) - } + c_lstat + }; + let mut st: stat_t = unsafe { uninitialized() }; + let result = unsafe { stat_fn(path.as_ptr() as *const c_char, &mut st as *mut stat_t) }; + + if result < 0 { + crash!(1, "failed to get attributes of '{}': {}", path, Error::last_os_error()); } + + // set_file_times expects milliseconds + let atime = if st.st_atime_nsec == 0 { + st.st_atime * 1000 + } else { + st.st_atime_nsec / 1000 + } as u64; + + // set_file_times expects milliseconds + let mtime = if st.st_mtime_nsec == 0 { + st.st_mtime * 1000 + } else { + st.st_mtime_nsec / 1000 + } as u64; + + (atime, mtime) } fn parse_date(str: &str) -> u64 { diff --git a/src/unexpand/unexpand.rs b/src/unexpand/unexpand.rs index 3761c3477..ca7571461 100644 --- a/src/unexpand/unexpand.rs +++ b/src/unexpand/unexpand.rs @@ -142,14 +142,22 @@ fn next_tabstop(tabstops: &[usize], col: usize) -> Option { } } -fn write_tabs(mut output: &mut BufWriter, tabstops: &[usize], mut scol: usize, col: usize) { - while let Some(nts) = next_tabstop(tabstops, scol) { - if col < scol + nts { - break; - } +fn write_tabs(mut output: &mut BufWriter, tabstops: &[usize], + mut scol: usize, col: usize, prevtab: bool, init: bool, amode: bool) { + // This conditional establishes the following: + // We never turn a single space before a non-blank into + // a tab, unless it's at the start of the line. + let ai = init || amode; + if (ai && !prevtab && col > scol + 1) || + (col > scol && (init || ai && prevtab)) { + while let Some(nts) = next_tabstop(tabstops, scol) { + if col < scol + nts { + break; + } - safe_unwrap!(output.write_all("\t".as_bytes())); - scol += nts; + safe_unwrap!(output.write_all("\t".as_bytes())); + scol += nts; + } } while col > scol { @@ -194,15 +202,9 @@ fn unexpand(options: Options) { while byte < buf.len() { // when we have a finite number of columns, never convert past the last column if lastcol > 0 && col >= lastcol { - if (pctype != Tab && col > scol + 1) || - (col > scol && (init || pctype == Tab)) { - write_tabs(&mut output, ts, scol, col); - } else if col > scol { - safe_unwrap!(output.write_all(" ".as_bytes())); - } - scol = col; - + write_tabs(&mut output, ts, scol, col, pctype == Tab, init, true); safe_unwrap!(output.write_all(&buf[byte..])); + scol = col; break; } @@ -253,15 +255,8 @@ fn unexpand(options: Options) { } }, Other | Backspace => { // always - // never turn a single space before a non-blank into a tab - // unless it's at the start of the line - if (tabs_buffered && pctype != Tab && col > scol + 1) || - (col > scol && (init || (tabs_buffered && pctype == Tab))) { - write_tabs(&mut output, ts, scol, col); - } else if col > scol { - safe_unwrap!(output.write_all(" ".as_bytes())); - } - init = false; + write_tabs(&mut output, ts, scol, col, pctype == Tab, init, options.aflag); + init = false; // no longer at the start of a line col = if ctype == Other { // use computed width col + cwidth } else if col > 0 { // Backspace case, but only if col > 0 @@ -279,12 +274,7 @@ fn unexpand(options: Options) { } // write out anything remaining - if col > scol + 1 || (init && col > scol) { - write_tabs(&mut output, ts, scol, col); - } else if col > scol { - safe_unwrap!(output.write_all(" ".as_bytes())); - } - + write_tabs(&mut output, ts, scol, col, pctype == Tab, init, true); buf.truncate(0); // clear out the buffer } } diff --git a/test/factor.rs b/test/factor.rs new file mode 100644 index 000000000..872ea0d27 --- /dev/null +++ b/test/factor.rs @@ -0,0 +1,536 @@ +/* +* This file is part of the uutils coreutils package. +* +* (c) kwantam +* +* For the full copyright and license information, please view the LICENSE file +* that was distributed with this source code. +*/ + +extern crate libc; +extern crate rand; + +use rand::{weak_rng, Rng}; +use rand::distributions::{IndependentSample, Range}; +use sieve::Sieve; +use std::io::Write; +use std::process::{Command, Stdio}; + +#[path="../src/factor/sieve.rs"] +mod sieve; + +const NUM_PRIMES: usize = 10000; +const LOG_PRIMES: f64 = 14.0; // ceil(log2(NUM_PRIMES)) + +const NUM_TESTS: usize = 1000; +const PROGNAME: &'static str = "./factor"; + +#[test] +fn test_random() { + let mut primes = Sieve::new().take(NUM_PRIMES - 1).collect::>(); + primes.push(2); + let primes = primes; + + let mut rng = weak_rng(); + let mut rand_gt = move |min: u64| { + let mut product = 1u64; + let mut factors = Vec::new(); + while product < min { + // log distribution---higher probability for lower numbers + let mut factor; + loop { + let next = rng.gen_range(0f64, LOG_PRIMES).exp2().floor() as usize; + if next < NUM_PRIMES { + factor = primes[next]; + break; + } + } + let factor = factor; + + match product.checked_mul(factor) { + Some(p) => { + product = p; + factors.push(factor); + }, + None => break, + }; + } + + factors.sort(); + (product, factors) + }; + + // build an input and expected output string from factor + let mut instring = String::new(); + let mut outstring = String::new(); + for _ in 0..NUM_TESTS { + let (product, factors) = rand_gt(1 << 63); + instring.push_str(&(format!("{} ", product))[..]); + + outstring.push_str(&(format!("{}:", product))[..]); + for factor in factors { + outstring.push_str(&(format!(" {}", factor))[..]); + } + outstring.push_str("\n"); + } + + run(instring.as_bytes(), outstring.as_bytes()); +} + +#[test] +fn test_random_big() { + let mut rng = weak_rng(); + let bitrange_1 = Range::new(14usize, 51); + let mut rand_64 = move || { + // first, choose a random number of bits for the first factor + let f_bit_1 = bitrange_1.ind_sample(&mut rng); + // how many more bits do we need? + let rem = 64 - f_bit_1; + + // we will have a number of additional factors equal to nfacts + 1 + // where nfacts is in [0, floor(rem/14) ) NOTE half-open interval + // Each prime factor is at least 14 bits, hence floor(rem/14) + let nfacts = Range::new(0usize, rem / 14).ind_sample(&mut rng); + // we have to distribute extrabits among the (nfacts + 1) values + let extrabits = rem - (nfacts + 1) * 14; + // (remember, a Range is a half-open interval) + let extrarange = Range::new(0usize, extrabits + 1); + + // to generate an even split of this range, generate n-1 random elements + // in the range, add the desired total value to the end, sort this list, + // and then compute the sequential differences. + let mut f_bits = Vec::new(); + for _ in 0..nfacts { + f_bits.push(extrarange.ind_sample(&mut rng)); + } + f_bits.push(extrabits); + f_bits.sort(); + + // compute sequential differences here. We leave off the +14 bits + // so we can just index PRIMES_BY_BITS + let mut f_bits = f_bits.iter().scan(0, |st,&x| { + let ret = x - *st; // + 14 would give actual number of bits + *st = x; + Some(ret) + }).collect::>(); + // finally, add f_bit_1 in there + f_bits.push(f_bit_1 - 14); // index of f_bit_1 in PRIMES_BY_BITS + let f_bits = f_bits; + + let mut nbits = 0; + let mut product = 1u64; + let mut factors = Vec::new(); + for bit in f_bits { + assert!(bit < 37); + nbits += 14 + bit; + let elm = Range::new(0, PRIMES_BY_BITS[bit].len()).ind_sample(&mut rng); + let factor = PRIMES_BY_BITS[bit][elm]; + factors.push(factor); + product *= factor; + } + assert_eq!(nbits, 64); + + factors.sort(); + (product, factors) + }; + + let mut instring = String::new(); + let mut outstring = String::new(); + for _ in 0..NUM_TESTS { + let (product, factors) = rand_64(); + instring.push_str(&(format!("{} ", product))[..]); + + outstring.push_str(&(format!("{}:", product))[..]); + for factor in factors { + outstring.push_str(&(format!(" {}", factor))[..]); + } + outstring.push_str("\n"); + } + + run(instring.as_bytes(), outstring.as_bytes()); +} + +#[test] +fn test_big_primes() { + let mut instring = String::new(); + let mut outstring = String::new(); + for prime in PRIMES64 { + instring.push_str(&(format!("{} ", prime))[..]); + outstring.push_str(&(format!("{0}: {0}\n", prime))[..]); + } + + run(instring.as_bytes(), outstring.as_bytes()); +} + +fn run(instring: &[u8], outstring: &[u8]) { + // now run factor + let mut process = Command::new(PROGNAME) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap_or_else(|e| panic!("{}", e)); + + process.stdin.take().unwrap_or_else(|| panic!("Could not take child process stdin")) + .write_all(instring).unwrap_or_else(|e| panic!("{}", e)); + + let output = process.wait_with_output().unwrap_or_else(|e| panic!("{}", e)); + assert_eq!(&output.stdout[..], outstring); +} + +const PRIMES_BY_BITS: &'static [&'static [u64]] = &[PRIMES14, PRIMES15, PRIMES16, PRIMES17, + PRIMES18, PRIMES19, PRIMES20, PRIMES21, PRIMES22, PRIMES23, PRIMES24, PRIMES25, PRIMES26, + PRIMES27, PRIMES28, PRIMES29, PRIMES30, PRIMES31, PRIMES32, PRIMES33, PRIMES34, PRIMES35, + PRIMES36, PRIMES37, PRIMES38, PRIMES39, PRIMES40, PRIMES41, PRIMES42, PRIMES43, PRIMES44, + PRIMES45, PRIMES46, PRIMES47, PRIMES48, PRIMES49, PRIMES50, +]; + +const PRIMES64: &'static [u64] = &[18446744073709551557, 18446744073709551533, + 18446744073709551521, 18446744073709551437, 18446744073709551427, 18446744073709551359, + 18446744073709551337, 18446744073709551293, 18446744073709551263, 18446744073709551253, + 18446744073709551191, 18446744073709551163, 18446744073709551113, 18446744073709550873, + 18446744073709550791, 18446744073709550773, 18446744073709550771, 18446744073709550719, + 18446744073709550717, 18446744073709550681, 18446744073709550671, 18446744073709550593, + 18446744073709550591, 18446744073709550539, 18446744073709550537, 18446744073709550381, + 18446744073709550341, 18446744073709550293, 18446744073709550237, 18446744073709550147, + 18446744073709550141, 18446744073709550129, 18446744073709550111, 18446744073709550099, + 18446744073709550047, 18446744073709550033, 18446744073709550009, 18446744073709549951, + 18446744073709549861, 18446744073709549817, 18446744073709549811, 18446744073709549777, + 18446744073709549757, 18446744073709549733, 18446744073709549667, 18446744073709549621, + 18446744073709549613, 18446744073709549583, 18446744073709549571, +]; + +const PRIMES14: &'static [u64] = &[16381, 16369, 16363, 16361, 16349, 16339, 16333, 16319, + 16301, 16273, 16267, 16253, 16249, 16231, 16229, 16223, 16217, 16193, 16189, 16187, 16183, + 16141, 16139, 16127, 16111, 16103, 16097, 16091, 16087, 16073, 16069, 16067, 16063, 16061, + 16057, 16033, 16007, 16001, 15991, 15973, 15971, 15959, 15937, 15923, 15919, 15913, 15907, + 15901, 15889, 15887, 15881, 15877, 15859, 15823, 15817, 15809, 15803, 15797, 15791, 15787, + 15773, 15767, 15761, 15749, 15739, 15737, 15733, 15731, 15727, 15683, 15679, 15671, 15667, + 15661, 15649, 15647, 15643, 15641, 15629, 15619, 15607, 15601, 15583, 15581, 15569, 15559, + 15551, 15541, 15527, 15511, 15497, 15493, 15473, 15467, 15461, 15451, 15443, 15439, 15427, + 15413, 15401, 15391, 15383, 15377, 15373, +]; + +const PRIMES15: &'static [u64] = &[32749, 32719, 32717, 32713, 32707, 32693, 32687, 32653, + 32647, 32633, 32621, 32611, 32609, 32603, 32587, 32579, 32573, 32569, 32563, 32561, 32537, + 32533, 32531, 32507, 32503, 32497, 32491, 32479, 32467, 32443, 32441, 32429, 32423, 32413, + 32411, 32401, 32381, 32377, 32371, 32369, 32363, 32359, 32353, 32341, 32327, 32323, 32321, + 32309, 32303, 32299, 32297, 32261, 32257, 32251, 32237, 32233, 32213, 32203, 32191, 32189, + 32183, 32173, 32159, 32143, 32141, 32119, 32117, 32099, 32089, 32083, 32077, 32069, 32063, + 32059, 32057, 32051, 32029, 32027, 32009, 32003, 31991, 31981, 31973, 31963, 31957, 31907, + 31891, 31883, 31873, 31859, 31849, 31847, 31817, 31799, 31793, 31771, 31769, 31751, +]; + +const PRIMES16: &'static [u64] = &[65521, 65519, 65497, 65479, 65449, 65447, 65437, 65423, + 65419, 65413, 65407, 65393, 65381, 65371, 65357, 65353, 65327, 65323, 65309, 65293, 65287, + 65269, 65267, 65257, 65239, 65213, 65203, 65183, 65179, 65173, 65171, 65167, 65147, 65141, + 65129, 65123, 65119, 65111, 65101, 65099, 65089, 65071, 65063, 65053, 65033, 65029, 65027, + 65011, 65003, 64997, 64969, 64951, 64937, 64927, 64921, 64919, 64901, 64891, 64879, 64877, + 64871, 64853, 64849, 64817, 64811, 64793, 64783, 64781, 64763, 64747, 64717, 64709, 64693, + 64679, 64667, 64663, 64661, 64633, 64627, 64621, 64613, 64609, 64601, 64591, 64579, 64577, + 64567, 64553, +]; + +const PRIMES17: &'static [u64] = &[131071, 131063, 131059, 131041, 131023, 131011, 131009, + 130987, 130981, 130973, 130969, 130957, 130927, 130873, 130859, 130843, 130841, 130829, + 130817, 130811, 130807, 130787, 130783, 130769, 130729, 130699, 130693, 130687, 130681, + 130657, 130651, 130649, 130643, 130639, 130633, 130631, 130621, 130619, 130589, 130579, + 130553, 130547, 130531, 130523, 130517, 130513, 130489, 130483, 130477, 130469, 130457, + 130447, 130439, 130423, 130411, 130409, 130399, 130379, 130369, 130367, 130363, 130349, + 130343, 130337, 130307, 130303, 130279, 130267, 130261, 130259, 130253, 130241, 130223, + 130211, 130201, 130199, 130183, 130171, 130147, 130127, 130121, 130099, 130087, 130079, + 130073, 130069, 130057, 130051, +]; + +const PRIMES18: &'static [u64] = &[262139, 262133, 262127, 262121, 262111, 262109, 262103, + 262079, 262069, 262051, 262049, 262027, 262007, 261983, 261977, 261973, 261971, 261959, + 261917, 261887, 261881, 261847, 261823, 261799, 261791, 261787, 261773, 261761, 261757, + 261739, 261721, 261713, 261707, 261697, 261673, 261643, 261641, 261637, 261631, 261619, + 261601, 261593, 261587, 261581, 261577, 261563, 261557, 261529, 261523, 261509, 261467, + 261463, 261451, 261439, 261433, 261431, 261427, 261407, 261389, 261379, 261353, 261347, + 261337, 261329, 261323, 261301, 261281, 261271, 261251, 261241, 261229, 261223, 261169, + 261167, 261127, +]; + +const PRIMES19: &'static [u64] = &[524287, 524269, 524261, 524257, 524243, 524231, 524221, + 524219, 524203, 524201, 524197, 524189, 524171, 524149, 524123, 524119, 524113, 524099, + 524087, 524081, 524071, 524063, 524057, 524053, 524047, 523997, 523987, 523969, 523949, + 523937, 523927, 523907, 523903, 523877, 523867, 523847, 523829, 523801, 523793, 523777, + 523771, 523763, 523759, 523741, 523729, 523717, 523681, 523673, 523669, 523667, 523657, + 523639, 523637, 523631, 523603, 523597, 523577, 523573, 523571, 523553, 523543, 523541, + 523519, 523511, 523493, 523489, 523487, 523463, 523459, 523433, 523427, 523417, 523403, + 523387, 523357, 523351, 523349, 523333, 523307, 523297, +]; + +const PRIMES20: &'static [u64] = &[1048573, 1048571, 1048559, 1048549, 1048517, 1048507, + 1048447, 1048433, 1048423, 1048391, 1048387, 1048367, 1048361, 1048357, 1048343, 1048309, + 1048291, 1048273, 1048261, 1048219, 1048217, 1048213, 1048193, 1048189, 1048139, 1048129, + 1048127, 1048123, 1048063, 1048051, 1048049, 1048043, 1048027, 1048013, 1048009, 1048007, + 1047997, 1047989, 1047979, 1047971, 1047961, 1047941, 1047929, 1047923, 1047887, 1047883, + 1047881, 1047859, 1047841, 1047833, 1047821, 1047779, 1047773, 1047763, 1047751, 1047737, + 1047721, 1047713, 1047703, 1047701, 1047691, 1047689, 1047671, 1047667, 1047653, 1047649, + 1047647, 1047589, 1047587, 1047559, +]; + +const PRIMES21: &'static [u64] = &[2097143, 2097133, 2097131, 2097097, 2097091, 2097083, + 2097047, 2097041, 2097031, 2097023, 2097013, 2096993, 2096987, 2096971, 2096959, 2096957, + 2096947, 2096923, 2096911, 2096909, 2096893, 2096881, 2096873, 2096867, 2096851, 2096837, + 2096807, 2096791, 2096789, 2096777, 2096761, 2096741, 2096737, 2096713, 2096693, 2096687, + 2096681, 2096639, 2096629, 2096621, 2096599, 2096597, 2096569, 2096539, 2096533, 2096483, + 2096449, 2096431, 2096429, 2096411, 2096407, 2096401, 2096399, 2096377, 2096357, 2096291, + 2096273, 2096261, 2096233, 2096231, 2096221, 2096209, 2096191, 2096183, 2096147, +]; + +const PRIMES22: &'static [u64] = &[4194301, 4194287, 4194277, 4194271, 4194247, 4194217, + 4194199, 4194191, 4194187, 4194181, 4194173, 4194167, 4194143, 4194137, 4194131, 4194107, + 4194103, 4194023, 4194011, 4194007, 4193977, 4193971, 4193963, 4193957, 4193939, 4193929, + 4193909, 4193869, 4193807, 4193803, 4193801, 4193789, 4193759, 4193753, 4193743, 4193701, + 4193663, 4193633, 4193573, 4193569, 4193551, 4193549, 4193531, 4193513, 4193507, 4193459, + 4193447, 4193443, 4193417, 4193411, 4193393, 4193389, 4193381, 4193377, 4193369, 4193359, + 4193353, 4193327, 4193309, 4193303, 4193297, +]; + +const PRIMES23: &'static [u64] = &[8388593, 8388587, 8388581, 8388571, 8388547, 8388539, + 8388473, 8388461, 8388451, 8388449, 8388439, 8388427, 8388421, 8388409, 8388377, 8388371, + 8388319, 8388301, 8388287, 8388283, 8388277, 8388239, 8388209, 8388187, 8388113, 8388109, + 8388091, 8388071, 8388059, 8388019, 8388013, 8387999, 8387993, 8387959, 8387957, 8387947, + 8387933, 8387921, 8387917, 8387891, 8387879, 8387867, 8387861, 8387857, 8387839, 8387831, + 8387809, 8387807, 8387741, 8387737, 8387723, 8387707, 8387671, 8387611, 8387609, 8387591, +]; + +const PRIMES24: &'static [u64] = &[16777213, 16777199, 16777183, 16777153, 16777141, 16777139, + 16777127, 16777121, 16777099, 16777049, 16777027, 16776989, 16776973, 16776971, 16776967, + 16776961, 16776941, 16776937, 16776931, 16776919, 16776901, 16776899, 16776869, 16776857, + 16776839, 16776833, 16776817, 16776763, 16776731, 16776719, 16776713, 16776691, 16776689, + 16776679, 16776659, 16776631, 16776623, 16776619, 16776607, 16776593, 16776581, 16776547, + 16776521, 16776491, 16776481, 16776469, 16776451, 16776401, 16776391, 16776379, 16776371, + 16776367, 16776343, 16776337, 16776317, 16776313, 16776289, 16776217, 16776211, +]; + +const PRIMES25: &'static [u64] = &[33554393, 33554383, 33554371, 33554347, 33554341, 33554317, + 33554291, 33554273, 33554267, 33554249, 33554239, 33554221, 33554201, 33554167, 33554159, + 33554137, 33554123, 33554093, 33554083, 33554077, 33554051, 33554021, 33554011, 33554009, + 33553999, 33553991, 33553969, 33553967, 33553909, 33553901, 33553879, 33553837, 33553799, + 33553787, 33553771, 33553769, 33553759, 33553747, 33553739, 33553727, 33553697, 33553693, + 33553679, 33553661, 33553657, 33553651, 33553649, 33553633, 33553613, 33553607, 33553577, + 33553549, 33553547, 33553537, 33553519, 33553517, 33553511, 33553489, 33553463, 33553451, + 33553417, +]; + +const PRIMES26: &'static [u64] = &[67108859, 67108837, 67108819, 67108777, 67108763, + 67108757, 67108753, 67108747, 67108739, 67108729, 67108721, 67108709, 67108693, 67108669, + 67108667, 67108661, 67108649, 67108633, 67108597, 67108579, 67108529, 67108511, 67108507, + 67108493, 67108471, 67108463, 67108453, 67108439, 67108387, 67108373, 67108369, 67108351, + 67108331, 67108313, 67108303, 67108289, 67108271, 67108219, 67108207, 67108201, 67108199, + 67108187, 67108183, 67108177, 67108127, 67108109, 67108081, 67108049, 67108039, 67108037, + 67108033, 67108009, 67108007, 67108003, 67107983, 67107977, 67107967, 67107941, 67107919, + 67107913, 67107883, 67107881, 67107871, 67107863, +]; + +const PRIMES27: &'static [u64] = &[134217689, 134217649, 134217617, 134217613, 134217593, + 134217541, 134217529, 134217509, 134217497, 134217493, 134217487, 134217467, 134217439, + 134217437, 134217409, 134217403, 134217401, 134217367, 134217361, 134217353, 134217323, + 134217301, 134217277, 134217257, 134217247, 134217221, 134217199, 134217173, 134217163, + 134217157, 134217131, 134217103, 134217089, 134217079, 134217049, 134217047, 134217043, + 134217001, 134216987, 134216947, 134216939, 134216933, 134216911, 134216899, 134216881, + 134216869, 134216867, 134216861, 134216837, 134216827, 134216807, 134216801, 134216791, + 134216783, 134216777, 134216759, 134216737, 134216729, +]; + +const PRIMES28: &'static [u64] = &[268435399, 268435367, 268435361, 268435337, 268435331, + 268435313, 268435291, 268435273, 268435243, 268435183, 268435171, 268435157, 268435147, + 268435133, 268435129, 268435121, 268435109, 268435091, 268435067, 268435043, 268435039, + 268435033, 268435019, 268435009, 268435007, 268434997, 268434979, 268434977, 268434961, + 268434949, 268434941, 268434937, 268434857, 268434841, 268434827, 268434821, 268434787, + 268434781, 268434779, 268434773, 268434731, 268434721, 268434713, 268434707, 268434703, + 268434697, 268434659, 268434623, 268434619, 268434581, 268434577, 268434563, 268434557, + 268434547, 268434511, 268434499, 268434479, 268434461, +]; + +const PRIMES29: &'static [u64] = &[536870909, 536870879, 536870869, 536870849, 536870839, + 536870837, 536870819, 536870813, 536870791, 536870779, 536870767, 536870743, 536870729, + 536870723, 536870717, 536870701, 536870683, 536870657, 536870641, 536870627, 536870611, + 536870603, 536870599, 536870573, 536870569, 536870563, 536870561, 536870513, 536870501, + 536870497, 536870473, 536870401, 536870363, 536870317, 536870303, 536870297, 536870273, + 536870267, 536870239, 536870233, 536870219, 536870171, 536870167, 536870153, 536870123, + 536870063, 536870057, 536870041, 536870027, 536869999, 536869951, 536869943, 536869937, + 536869919, 536869901, 536869891, +]; + +const PRIMES30: &'static [u64] = &[1073741789, 1073741783, 1073741741, 1073741723, 1073741719, + 1073741717, 1073741689, 1073741671, 1073741663, 1073741651, 1073741621, 1073741567, 1073741561, + 1073741527, 1073741503, 1073741477, 1073741467, 1073741441, 1073741419, 1073741399, 1073741387, + 1073741381, 1073741371, 1073741329, 1073741311, 1073741309, 1073741287, 1073741237, 1073741213, + 1073741197, 1073741189, 1073741173, 1073741101, 1073741077, 1073741047, 1073740963, 1073740951, + 1073740933, 1073740909, 1073740879, 1073740853, 1073740847, 1073740819, 1073740807, +]; + +const PRIMES31: &'static [u64] = &[2147483647, 2147483629, 2147483587, 2147483579, 2147483563, + 2147483549, 2147483543, 2147483497, 2147483489, 2147483477, 2147483423, 2147483399, 2147483353, + 2147483323, 2147483269, 2147483249, 2147483237, 2147483179, 2147483171, 2147483137, 2147483123, + 2147483077, 2147483069, 2147483059, 2147483053, 2147483033, 2147483029, 2147482951, 2147482949, + 2147482943, 2147482937, 2147482921, 2147482877, 2147482873, 2147482867, 2147482859, 2147482819, + 2147482817, 2147482811, 2147482801, 2147482763, 2147482739, 2147482697, 2147482693, 2147482681, + 2147482663, 2147482661, +]; + +const PRIMES32: &'static [u64] = &[4294967291, 4294967279, 4294967231, 4294967197, 4294967189, + 4294967161, 4294967143, 4294967111, 4294967087, 4294967029, 4294966997, 4294966981, 4294966943, + 4294966927, 4294966909, 4294966877, 4294966829, 4294966813, 4294966769, 4294966667, 4294966661, + 4294966657, 4294966651, 4294966639, 4294966619, 4294966591, 4294966583, 4294966553, 4294966477, + 4294966447, 4294966441, 4294966427, 4294966373, 4294966367, 4294966337, 4294966297, +]; + +const PRIMES33: &'static [u64] = &[8589934583, 8589934567, 8589934543, 8589934513, 8589934487, + 8589934307, 8589934291, 8589934289, 8589934271, 8589934237, 8589934211, 8589934207, 8589934201, + 8589934187, 8589934151, 8589934141, 8589934139, 8589934117, 8589934103, 8589934099, 8589934091, + 8589934069, 8589934049, 8589934027, 8589934007, 8589933973, 8589933971, 8589933967, 8589933931, + 8589933917, 8589933907, 8589933853, 8589933827, 8589933823, 8589933787, 8589933773, 8589933733, + 8589933731, 8589933721, 8589933683, 8589933647, 8589933641, 8589933637, 8589933631, 8589933629, + 8589933619, 8589933601, 8589933581, +]; + +const PRIMES34: &'static [u64] = &[17179869143, 17179869107, 17179869071, 17179869053, + 17179869041, 17179869019, 17179868999, 17179868977, 17179868957, 17179868903, 17179868899, + 17179868887, 17179868879, 17179868873, 17179868869, 17179868861, 17179868843, 17179868833, + 17179868809, 17179868807, 17179868777, 17179868759, 17179868729, 17179868711, 17179868683, + 17179868681, 17179868597, 17179868549, 17179868543, 17179868521, 17179868513, 17179868479, + 17179868443, 17179868437, 17179868429, 17179868383, 17179868369, 17179868357, 17179868353, + 17179868351, 17179868333, 17179868317, 17179868309, 17179868297, 17179868287, 17179868249, + 17179868243, 17179868183, +]; + +const PRIMES35: &'static [u64] = &[34359738337, 34359738319, 34359738307, 34359738299, + 34359738289, 34359738247, 34359738227, 34359738121, 34359738059, 34359738043, 34359738011, + 34359737917, 34359737869, 34359737849, 34359737837, 34359737821, 34359737813, 34359737791, + 34359737777, 34359737771, 34359737717, 34359737591, 34359737567, 34359737549, 34359737519, + 34359737497, 34359737479, 34359737407, 34359737393, 34359737371, +]; + +const PRIMES36: &'static [u64] = &[68719476731, 68719476719, 68719476713, 68719476671, + 68719476619, 68719476599, 68719476577, 68719476563, 68719476547, 68719476503, 68719476493, + 68719476479, 68719476433, 68719476407, 68719476391, 68719476389, 68719476377, 68719476361, + 68719476323, 68719476307, 68719476281, 68719476271, 68719476257, 68719476247, 68719476209, + 68719476197, 68719476181, 68719476169, 68719476157, 68719476149, 68719476109, 68719476053, + 68719476047, 68719476019, 68719475977, 68719475947, 68719475933, 68719475911, 68719475893, + 68719475879, 68719475837, 68719475827, 68719475809, 68719475791, 68719475779, 68719475771, + 68719475767, 68719475731, 68719475729, +]; + +const PRIMES37: &'static [u64] = &[137438953447, 137438953441, 137438953427, 137438953403, + 137438953349, 137438953331, 137438953273, 137438953271, 137438953121, 137438953097, + 137438953037, 137438953009, 137438952953, 137438952901, 137438952887, 137438952869, + 137438952853, 137438952731, 137438952683, 137438952611, 137438952529, 137438952503, + 137438952491, +]; + +const PRIMES38: &'static [u64] = &[274877906899, 274877906857, 274877906837, 274877906813, + 274877906791, 274877906759, 274877906753, 274877906717, 274877906713, 274877906687, + 274877906647, 274877906629, 274877906627, 274877906573, 274877906543, 274877906491, + 274877906477, 274877906473, 274877906431, 274877906419, 274877906341, 274877906333, + 274877906327, 274877906321, 274877906309, 274877906267, 274877906243, 274877906213, + 274877906209, 274877906203, 274877906179, 274877906167, 274877906119, 274877906063, + 274877906053, 274877906021, 274877905931, +]; + +const PRIMES39: &'static [u64] = &[549755813881, 549755813869, 549755813821, 549755813797, + 549755813753, 549755813723, 549755813669, 549755813657, 549755813647, 549755813587, + 549755813561, 549755813513, 549755813507, 549755813461, 549755813417, 549755813401, + 549755813371, 549755813359, 549755813357, 549755813351, 549755813339, 549755813317, + 549755813311, 549755813281, 549755813239, 549755813231, 549755813213, 549755813207, + 549755813197, 549755813183, 549755813161, 549755813149, 549755813147, 549755813143, + 549755813141, 549755813059, 549755813027, 549755813003, 549755812951, 549755812937, + 549755812933, 549755812889, 549755812867, +]; + +const PRIMES40: &'static [u64] = &[1099511627689, 1099511627609, 1099511627581, 1099511627573, + 1099511627563, 1099511627491, 1099511627483, 1099511627477, 1099511627387, 1099511627339, + 1099511627321, 1099511627309, 1099511627297, 1099511627293, 1099511627261, 1099511627213, + 1099511627191, 1099511627177, 1099511627173, 1099511627143, 1099511627089, 1099511626987, + 1099511626949, 1099511626937, 1099511626793, 1099511626781, 1099511626771, +]; + +const PRIMES41: &'static [u64] = &[2199023255531, 2199023255521, 2199023255497, 2199023255489, + 2199023255479, 2199023255477, 2199023255461, 2199023255441, 2199023255419, 2199023255413, + 2199023255357, 2199023255327, 2199023255291, 2199023255279, 2199023255267, 2199023255243, + 2199023255203, 2199023255171, 2199023255137, 2199023255101, 2199023255087, 2199023255081, + 2199023255069, 2199023255027, 2199023255021, 2199023254979, 2199023254933, 2199023254913, + 2199023254907, 2199023254903, 2199023254843, 2199023254787, 2199023254699, 2199023254693, + 2199023254657, 2199023254567, +]; + +const PRIMES42: &'static [u64] = &[4398046511093, 4398046511087, 4398046511071, 4398046511051, + 4398046511039, 4398046510961, 4398046510943, 4398046510939, 4398046510889, 4398046510877, + 4398046510829, 4398046510787, 4398046510771, 4398046510751, 4398046510733, 4398046510721, + 4398046510643, 4398046510639, 4398046510597, 4398046510577, 4398046510547, 4398046510531, + 4398046510463, 4398046510397, 4398046510391, 4398046510379, 4398046510357, 4398046510331, + 4398046510327, 4398046510313, 4398046510283, 4398046510279, 4398046510217, 4398046510141, + 4398046510133, 4398046510103, 4398046510093, +]; + +const PRIMES43: &'static [u64] = &[8796093022151, 8796093022141, 8796093022091, 8796093022033, + 8796093021953, 8796093021941, 8796093021917, 8796093021899, 8796093021889, 8796093021839, + 8796093021803, 8796093021791, 8796093021769, 8796093021763, 8796093021743, 8796093021671, + 8796093021607, 8796093021587, 8796093021533, 8796093021523, 8796093021517, 8796093021493, + 8796093021467, 8796093021461, 8796093021449, 8796093021409, 8796093021407, 8796093021371, + 8796093021347, 8796093021337, 8796093021281, 8796093021269, +]; + +const PRIMES44: &'static [u64] = &[17592186044399, 17592186044299, 17592186044297, 17592186044287, + 17592186044273, 17592186044267, 17592186044129, 17592186044089, 17592186044057, 17592186044039, + 17592186043987, 17592186043921, 17592186043889, 17592186043877, 17592186043841, 17592186043829, + 17592186043819, 17592186043813, 17592186043807, 17592186043741, 17592186043693, 17592186043667, + 17592186043631, 17592186043591, 17592186043577, 17592186043547, 17592186043483, 17592186043451, + 17592186043433, 17592186043409, +]; + +const PRIMES45: &'static [u64] = &[35184372088777, 35184372088763, 35184372088751, 35184372088739, + 35184372088711, 35184372088699, 35184372088693, 35184372088673, 35184372088639, 35184372088603, + 35184372088571, 35184372088517, 35184372088493, 35184372088471, 35184372088403, 35184372088391, + 35184372088379, 35184372088363, 35184372088321, 35184372088319, 35184372088279, 35184372088259, + 35184372088249, 35184372088241, 35184372088223, 35184372088183, 35184372088097, 35184372088081, + 35184372088079, 35184372088051, 35184372088043, 35184372088039, 35184372087937, 35184372087929, + 35184372087923, 35184372087881, 35184372087877, 35184372087869, +]; + +const PRIMES46: &'static [u64] = &[70368744177643, 70368744177607, 70368744177601, 70368744177587, + 70368744177497, 70368744177467, 70368744177427, 70368744177377, 70368744177359, 70368744177353, + 70368744177331, 70368744177289, 70368744177283, 70368744177271, 70368744177257, 70368744177227, + 70368744177167, 70368744177113, 70368744177029, 70368744176959, 70368744176921, 70368744176909, + 70368744176879, 70368744176867, 70368744176833, 70368744176827, 70368744176807, 70368744176779, + 70368744176777, 70368744176729, 70368744176719, 70368744176711, +]; + +const PRIMES47: &'static [u64] = &[140737488355213, 140737488355201, 140737488355181, + 140737488355049, 140737488355031, 140737488354989, 140737488354893, 140737488354787, + 140737488354709, 140737488354679, 140737488354613, 140737488354557, 140737488354511, + 140737488354431, 140737488354413, 140737488354409, 140737488354373, 140737488354347, + 140737488354329, +]; + +const PRIMES48: &'static [u64] = &[281474976710597, 281474976710591, 281474976710567, + 281474976710563, 281474976710509, 281474976710491, 281474976710467, 281474976710423, + 281474976710413, 281474976710399, 281474976710339, 281474976710327, 281474976710287, + 281474976710197, 281474976710143, 281474976710131, 281474976710129, 281474976710107, + 281474976710089, 281474976710087, 281474976710029, 281474976709987, 281474976709891, + 281474976709859, 281474976709831, 281474976709757, 281474976709741, 281474976709711, + 281474976709649, 281474976709637, +]; + +const PRIMES49: &'static [u64] = &[562949953421231, 562949953421201, 562949953421189, + 562949953421173, 562949953421131, 562949953421111, 562949953421099, 562949953421047, + 562949953421029, 562949953420973, 562949953420871, 562949953420867, 562949953420837, + 562949953420793, 562949953420747, 562949953420741, 562949953420733, 562949953420727, + 562949953420609, 562949953420571, 562949953420559, 562949953420553, 562949953420523, + 562949953420507, 562949953420457, 562949953420403, 562949953420373, 562949953420369, + 562949953420343, 562949953420303, 562949953420297, +]; + +const PRIMES50: &'static [u64] = &[1125899906842597, 1125899906842589, 1125899906842573, + 1125899906842553, 1125899906842511, 1125899906842507, 1125899906842493, 1125899906842463, + 1125899906842429, 1125899906842391, 1125899906842357, 1125899906842283, 1125899906842273, + 1125899906842247, 1125899906842201, 1125899906842177, 1125899906842079, 1125899906842033, + 1125899906842021, 1125899906842013, 1125899906841973, 1125899906841971, 1125899906841959, + 1125899906841949, 1125899906841943, 1125899906841917, 1125899906841901, 1125899906841883, + 1125899906841859, 1125899906841811, 1125899906841803, 1125899906841751, 1125899906841713, + 1125899906841673, 1125899906841653, 1125899906841623, 1125899906841613, +]; diff --git a/test/test.rs b/test/test.rs index 480d0aa3f..b792538ea 100644 --- a/test/test.rs +++ b/test/test.rs @@ -1,6 +1,13 @@ -#![allow(unstable)] +/* + * This file is part of the uutils coreutils package. + * + * (c) mahkoh (ju.orth [at] gmail [dot] com) + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ -use std::old_io::process::Command; +use std::process::Command; static EXE: &'static str = "./test"; @@ -26,6 +33,5 @@ fn test_op_prec_and_or_2() { #[test] fn test_or_as_filename() { let status = Command::new(EXE).arg("x").arg("-a").arg("-z").arg("-o").status(); - assert!(status.unwrap().matches_exit_status(1)); + assert_eq!(status.unwrap().code(), Some(1)); } - diff --git a/test/unexpand.rs b/test/unexpand.rs index 8776a6fe2..59eaa9e06 100644 --- a/test/unexpand.rs +++ b/test/unexpand.rs @@ -105,4 +105,8 @@ fn unexpand_spaces_follow_tabs_1() { // evil assert_eq!(&out[..], b"a\t\t B \t" as &[u8]); } - +#[test] +fn unexpand_spaces_after_fields() { + let out = run(" \t A B C D A\t\n", &["-a"]); + assert_eq!(&out[..], b"\t\tA B C D\t\t A\t\n" as &[u8]); +}