diff --git a/src/bbp.rs b/src/bbp.rs index 0afd676..5733371 100644 --- a/src/bbp.rs +++ b/src/bbp.rs @@ -1,7 +1,7 @@ pub fn get_byte(id: i32) -> u8 { let pid : f64 = 4.0 * series(1, id) - 2.0 * series(4, id) - series(5, id) - series(6, id); - let y : f64 = (pid - (pid as i32) as f64 + 1.0).abs(); // TODO use .trunc() instead + let y : f64 = (pid - (pid as i32) as f64 + 1.0).abs(); let y = 16.0 * (y - y.floor()); ((y as u8) << 4) | (16.0 * (y - y.floor())) as u8 @@ -86,13 +86,17 @@ fn expm(p: f64, ak: f64) -> f64 { } #[cfg(test)] -mod tests { // TODO: use a tests directory instead? - use super::get_byte; +mod tests { + use super::*; #[test] fn test_get_byte() { assert_eq!(36, get_byte(0)); + assert_eq!(67, get_byte(1)); + assert_eq!(63, get_byte(2)); + assert_eq!(163, get_byte(10)); + assert_eq!(41, get_byte(100)); } } diff --git a/src/main.rs b/src/main.rs index d18943a..1a330ed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,8 @@ +#[macro_use] extern crate lazy_static; extern crate getopts; extern crate byteorder; extern crate pbr; -#[macro_use] -extern crate lazy_static; - use std::env; use std::fs; @@ -12,6 +10,7 @@ use std::io::BufReader; use std::io::prelude::*; use std::i32; use std::io::Cursor; +use std::collections::BTreeMap; use getopts::Options; use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian}; @@ -21,6 +20,37 @@ use pbr::{ProgressBar, Units}; mod bbp; +struct Pi { + next: i32, + map: BTreeMap +} + +impl Pi { + fn new() -> Self { + Pi { + next: 0, + map: BTreeMap::new() + } + } + + fn find(&mut self, byte: u8) -> i32 { + if self.map.contains_key(&byte) { + *self.map.get(&byte).unwrap() + } else { + for i in self.next..i32::MAX { + if byte == bbp::get_byte(i) { + self.map.insert(byte, i); + + return i; + } + } + + 0 + } + } +} + + fn print_usage(program: &str, opts: Options) { let brief = format!("Usage: {} [option] INPUT OUTPUT", program); print!("{}", opts.usage(&brief)); @@ -82,20 +112,16 @@ fn compress(input: &str, output: &str) { let input_buf = BufReader::new(input_file); - let mut i : i32 = 0; let mut pb = ProgressBar::new(n_bytes); + let mut pi = Pi::new(); + pb.set_units(Units::Bytes); for b in input_buf.bytes() { let b = b.unwrap(); - for n in 0..i32::MAX { - if b == bbp::get_byte(n) { - i = n; - break; - } - } + let i = pi.find(b); let mut index : Vec = vec![];