10
10
11
11
// ignore-pretty
12
12
13
+ use std:: ascii:: OwnedStrAsciiExt ;
13
14
use std:: str;
14
15
use std:: slice;
15
16
@@ -39,16 +40,16 @@ impl Code {
39
40
Code ( ( self . hash ( ) << 2 ) + ( pack_symbol ( c) as u64 ) )
40
41
}
41
42
42
- fn rotate ( & self , c : u8 , frame : i32 ) -> Code {
43
- Code ( self . push_char ( c) . hash ( ) & ( ( 1u64 << ( 2 * ( frame as u64 ) ) ) - 1 ) )
43
+ fn rotate ( & self , c : u8 , frame : uint ) -> Code {
44
+ Code ( self . push_char ( c) . hash ( ) & ( ( 1u64 << ( 2 * frame) ) - 1 ) )
44
45
}
45
46
46
47
fn pack ( string : & str ) -> Code {
47
48
string. bytes ( ) . fold ( Code ( 0u64 ) , |a, b| a. push_char ( b) )
48
49
}
49
50
50
51
// FIXME: Inefficient.
51
- fn unpack ( & self , frame : i32 ) -> ~str {
52
+ fn unpack ( & self , frame : uint ) -> ~str {
52
53
let mut key = self . hash ( ) ;
53
54
let mut result = Vec :: new ( ) ;
54
55
for _ in range ( 0 , frame) {
@@ -86,12 +87,12 @@ impl TableCallback for PrintCallback {
86
87
87
88
struct Entry {
88
89
code : Code ,
89
- count : i32 ,
90
+ count : uint ,
90
91
next : Option < ~Entry > ,
91
92
}
92
93
93
94
struct Table {
94
- count : i32 ,
95
+ count : uint ,
95
96
items : Vec < Option < ~Entry > > }
96
97
97
98
struct Items < ' a > {
@@ -190,10 +191,10 @@ impl<'a> Iterator<&'a Entry> for Items<'a> {
190
191
191
192
fn pack_symbol ( c : u8 ) -> u8 {
192
193
match c as char {
193
- 'a' | ' A' => 0 ,
194
- 'c' | ' C' => 1 ,
195
- 'g' | ' G' => 2 ,
196
- 't' | ' T' => 3 ,
194
+ 'A' => 0 ,
195
+ 'C' => 1 ,
196
+ 'G' => 2 ,
197
+ 'T' => 3 ,
197
198
_ => fail ! ( "{}" , c as char ) ,
198
199
}
199
200
}
@@ -202,67 +203,67 @@ fn unpack_symbol(c: u8) -> u8 {
202
203
TABLE [ c]
203
204
}
204
205
205
- fn next_char < ' a > ( mut buf : & ' a [ u8 ] ) -> & ' a [ u8 ] {
206
- loop {
207
- buf = buf. slice ( 1 , buf. len ( ) ) ;
208
- if buf. len ( ) == 0 {
209
- break ;
210
- }
211
- if buf[ 0 ] != ( ' ' as u8 ) && buf[ 0 ] != ( '\t' as u8 ) &&
212
- buf[ 0 ] != ( '\n' as u8 ) && buf[ 0 ] != 0 {
213
- break ;
214
- }
215
- }
216
- buf
217
- }
218
-
219
206
fn generate_frequencies ( frequencies : & mut Table ,
220
207
mut input : & [ u8 ] ,
221
- frame : i32 ) {
208
+ frame : uint ) {
209
+ if input. len ( ) < frame { return ; }
222
210
let mut code = Code ( 0 ) ;
223
211
224
212
// Pull first frame.
225
213
for _ in range ( 0 , frame) {
226
214
code = code. push_char ( input[ 0 ] ) ;
227
- input = next_char ( input) ;
215
+ input = input. slice_from ( 1 ) ;
228
216
}
229
217
frequencies. lookup ( code, BumpCallback ) ;
230
218
231
219
while input. len ( ) != 0 && input[ 0 ] != ( '>' as u8 ) {
232
220
code = code. rotate ( input[ 0 ] , frame) ;
233
221
frequencies. lookup ( code, BumpCallback ) ;
234
- input = next_char ( input) ;
222
+ input = input. slice_from ( 1 ) ;
235
223
}
236
224
}
237
225
238
- fn print_frequencies ( frequencies : & Table , frame : i32 ) {
226
+ fn print_frequencies ( frequencies : & Table , frame : uint ) {
239
227
let mut vector = Vec :: new ( ) ;
240
228
for entry in frequencies. iter ( ) {
241
- vector. push ( ( entry. code , entry. count ) ) ;
229
+ vector. push ( ( entry. count , entry. code ) ) ;
242
230
}
243
231
vector. as_mut_slice ( ) . sort ( ) ;
244
232
245
233
let mut total_count = 0 ;
246
- for & ( _ , count ) in vector. iter ( ) {
234
+ for & ( count , _ ) in vector. iter ( ) {
247
235
total_count += count;
248
236
}
249
237
250
- for & ( key , count ) in vector. iter ( ) {
238
+ for & ( count , key ) in vector. iter ( ) . rev ( ) {
251
239
println ! ( "{} {:.3f}" ,
252
240
key. unpack( frame) ,
253
241
( count as f32 * 100.0 ) / ( total_count as f32 ) ) ;
254
242
}
243
+ println ! ( "" ) ;
255
244
}
256
245
257
246
fn print_occurrences ( frequencies : & mut Table , occurrence : & ' static str ) {
258
247
frequencies. lookup ( Code :: pack ( occurrence) , PrintCallback ( occurrence) )
259
248
}
260
249
250
+ fn get_sequence < R : Buffer > ( r : & mut R , key : & str ) -> ~[ u8 ] {
251
+ let mut res = ~"";
252
+ for l in r. lines ( ) . map ( |l| l. ok ( ) . unwrap ( ) )
253
+ . skip_while ( |l| key != l. slice_to ( key. len ( ) ) ) . skip ( 1 )
254
+ {
255
+ res. push_str ( l. trim ( ) ) ;
256
+ }
257
+ res. into_ascii_upper ( ) . into_bytes ( )
258
+ }
259
+
261
260
fn main ( ) {
262
- let input = include_str ! ( "shootout-k-nucleotide.data" ) ;
263
- let pos = input. find_str ( ">THREE" ) . unwrap ( ) ;
264
- let pos2 = pos + input. slice_from ( pos) . find_str ( "\n " ) . unwrap ( ) ;
265
- let input = input. slice_from ( pos2 + 1 ) . as_bytes ( ) ;
261
+ let input = if std:: os:: getenv ( "RUST_BENCH" ) . is_some ( ) {
262
+ let fd = std:: io:: File :: open ( & Path :: new ( "shootout-k-nucleotide.data" ) ) ;
263
+ get_sequence ( & mut std:: io:: BufferedReader :: new ( fd) , ">THREE" )
264
+ } else {
265
+ get_sequence ( & mut std:: io:: stdin ( ) , ">THREE" )
266
+ } ;
266
267
267
268
let mut frequencies = Table :: new ( ) ;
268
269
generate_frequencies ( & mut frequencies, input, 1 ) ;
@@ -276,7 +277,7 @@ fn main() {
276
277
frequencies = Table :: new ( ) ;
277
278
generate_frequencies ( & mut frequencies,
278
279
input,
279
- occurrence. len ( ) as i32 ) ;
280
+ occurrence. len ( ) ) ;
280
281
print_occurrences ( & mut frequencies, * occurrence) ;
281
282
}
282
283
}
0 commit comments