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