auto merge of #13206 : TeXitoi/rust/fix-shootout-k-nucleotide, r=alexcrichton

Correct printing (sort, new lines), reading on stdin.
This commit is contained in:
bors 2014-03-30 23:31:37 -07:00
commit 6281299230
1 changed files with 37 additions and 35 deletions

View File

@ -8,8 +8,10 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// ignore-android see #10393 #13206
// ignore-pretty // ignore-pretty
use std::ascii::OwnedStrAsciiExt;
use std::str; use std::str;
use std::slice; use std::slice;
@ -39,8 +41,8 @@ impl Code {
Code((self.hash() << 2) + (pack_symbol(c) as u64)) Code((self.hash() << 2) + (pack_symbol(c) as u64))
} }
fn rotate(&self, c: u8, frame: i32) -> Code { fn rotate(&self, c: u8, frame: uint) -> Code {
Code(self.push_char(c).hash() & ((1u64 << (2 * (frame as u64))) - 1)) Code(self.push_char(c).hash() & ((1u64 << (2 * frame)) - 1))
} }
fn pack(string: &str) -> Code { fn pack(string: &str) -> Code {
@ -48,7 +50,7 @@ impl Code {
} }
// FIXME: Inefficient. // FIXME: Inefficient.
fn unpack(&self, frame: i32) -> ~str { fn unpack(&self, frame: uint) -> ~str {
let mut key = self.hash(); let mut key = self.hash();
let mut result = Vec::new(); let mut result = Vec::new();
for _ in range(0, frame) { for _ in range(0, frame) {
@ -86,12 +88,12 @@ impl TableCallback for PrintCallback {
struct Entry { struct Entry {
code: Code, code: Code,
count: i32, count: uint,
next: Option<~Entry>, next: Option<~Entry>,
} }
struct Table { struct Table {
count: i32, count: uint,
items: Vec<Option<~Entry>> } items: Vec<Option<~Entry>> }
struct Items<'a> { struct Items<'a> {
@ -190,10 +192,10 @@ impl<'a> Iterator<&'a Entry> for Items<'a> {
fn pack_symbol(c: u8) -> u8 { fn pack_symbol(c: u8) -> u8 {
match c as char { match c as char {
'a' | 'A' => 0, 'A' => 0,
'c' | 'C' => 1, 'C' => 1,
'g' | 'G' => 2, 'G' => 2,
't' | 'T' => 3, 'T' => 3,
_ => fail!("{}", c as char), _ => fail!("{}", c as char),
} }
} }
@ -202,67 +204,67 @@ fn unpack_symbol(c: u8) -> u8 {
TABLE[c] TABLE[c]
} }
fn next_char<'a>(mut buf: &'a [u8]) -> &'a [u8] {
loop {
buf = buf.slice(1, buf.len());
if buf.len() == 0 {
break;
}
if buf[0] != (' ' as u8) && buf[0] != ('\t' as u8) &&
buf[0] != ('\n' as u8) && buf[0] != 0 {
break;
}
}
buf
}
fn generate_frequencies(frequencies: &mut Table, fn generate_frequencies(frequencies: &mut Table,
mut input: &[u8], mut input: &[u8],
frame: i32) { frame: uint) {
if input.len() < frame { return; }
let mut code = Code(0); let mut code = Code(0);
// Pull first frame. // Pull first frame.
for _ in range(0, frame) { for _ in range(0, frame) {
code = code.push_char(input[0]); code = code.push_char(input[0]);
input = next_char(input); input = input.slice_from(1);
} }
frequencies.lookup(code, BumpCallback); frequencies.lookup(code, BumpCallback);
while input.len() != 0 && input[0] != ('>' as u8) { while input.len() != 0 && input[0] != ('>' as u8) {
code = code.rotate(input[0], frame); code = code.rotate(input[0], frame);
frequencies.lookup(code, BumpCallback); frequencies.lookup(code, BumpCallback);
input = next_char(input); input = input.slice_from(1);
} }
} }
fn print_frequencies(frequencies: &Table, frame: i32) { fn print_frequencies(frequencies: &Table, frame: uint) {
let mut vector = Vec::new(); let mut vector = Vec::new();
for entry in frequencies.iter() { for entry in frequencies.iter() {
vector.push((entry.code, entry.count)); vector.push((entry.count, entry.code));
} }
vector.as_mut_slice().sort(); vector.as_mut_slice().sort();
let mut total_count = 0; let mut total_count = 0;
for &(_, count) in vector.iter() { for &(count, _) in vector.iter() {
total_count += count; total_count += count;
} }
for &(key, count) in vector.iter() { for &(count, key) in vector.iter().rev() {
println!("{} {:.3f}", println!("{} {:.3f}",
key.unpack(frame), key.unpack(frame),
(count as f32 * 100.0) / (total_count as f32)); (count as f32 * 100.0) / (total_count as f32));
} }
println!("");
} }
fn print_occurrences(frequencies: &mut Table, occurrence: &'static str) { fn print_occurrences(frequencies: &mut Table, occurrence: &'static str) {
frequencies.lookup(Code::pack(occurrence), PrintCallback(occurrence)) frequencies.lookup(Code::pack(occurrence), PrintCallback(occurrence))
} }
fn get_sequence<R: Buffer>(r: &mut R, key: &str) -> ~[u8] {
let mut res = ~"";
for l in r.lines().map(|l| l.ok().unwrap())
.skip_while(|l| key != l.slice_to(key.len())).skip(1)
{
res.push_str(l.trim());
}
res.into_ascii_upper().into_bytes()
}
fn main() { fn main() {
let input = include_str!("shootout-k-nucleotide.data"); let input = if std::os::getenv("RUST_BENCH").is_some() {
let pos = input.find_str(">THREE").unwrap(); let fd = std::io::File::open(&Path::new("shootout-k-nucleotide.data"));
let pos2 = pos + input.slice_from(pos).find_str("\n").unwrap(); get_sequence(&mut std::io::BufferedReader::new(fd), ">THREE")
let input = input.slice_from(pos2 + 1).as_bytes(); } else {
get_sequence(&mut std::io::stdin(), ">THREE")
};
let mut frequencies = Table::new(); let mut frequencies = Table::new();
generate_frequencies(&mut frequencies, input, 1); generate_frequencies(&mut frequencies, input, 1);
@ -276,7 +278,7 @@ fn main() {
frequencies = Table::new(); frequencies = Table::new();
generate_frequencies(&mut frequencies, generate_frequencies(&mut frequencies,
input, input,
occurrence.len() as i32); occurrence.len());
print_occurrences(&mut frequencies, *occurrence); print_occurrences(&mut frequencies, *occurrence);
} }
} }