1 // The Computer Language Benchmarks Game
2 // http://benchmarksgame.alioth.debian.org/
4 // contributed by the Rust Project Developers
6 // Copyright (c) 2013-2014 The Rust Project Developers
8 // All rights reserved.
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions
14 // - Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
17 // - Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in
19 // the documentation and/or other materials provided with the
22 // - Neither the name of "The Computer Language Benchmarks Game" nor
23 // the name of "The Computer Language Shootout Benchmarks" nor the
24 // names of its contributors may be used to endorse or promote
25 // products derived from this software without specific prior
26 // written permission.
28 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 // OF THE POSSIBILITY OF SUCH DAMAGE.
44 use std
::io
::prelude
::*;
45 use std
::iter
::repeat
;
47 const LINE_LEN
: usize = 60;
48 const LOOKUP_SIZE
: usize = 4 * 1024;
49 const LOOKUP_SCALE
: f32 = (LOOKUP_SIZE
- 1) as f32;
51 // Random number generator constants
52 const IM
: u32 = 139968;
54 const IC
: u32 = 29573;
56 const ALU
: &'
static str = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG\
57 GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA\
58 GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA\
59 AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT\
60 CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC\
61 CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG\
62 CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
64 const NULL_AMINO_ACID
: AminoAcid
= AminoAcid { c: ' ' as u8, p: 0.0 }
;
66 static IUB
: [AminoAcid
;15] = [
67 AminoAcid { c: 'a' as u8, p: 0.27 }
,
68 AminoAcid { c: 'c' as u8, p: 0.12 }
,
69 AminoAcid { c: 'g' as u8, p: 0.12 }
,
70 AminoAcid { c: 't' as u8, p: 0.27 }
,
71 AminoAcid { c: 'B' as u8, p: 0.02 }
,
72 AminoAcid { c: 'D' as u8, p: 0.02 }
,
73 AminoAcid { c: 'H' as u8, p: 0.02 }
,
74 AminoAcid { c: 'K' as u8, p: 0.02 }
,
75 AminoAcid { c: 'M' as u8, p: 0.02 }
,
76 AminoAcid { c: 'N' as u8, p: 0.02 }
,
77 AminoAcid { c: 'R' as u8, p: 0.02 }
,
78 AminoAcid { c: 'S' as u8, p: 0.02 }
,
79 AminoAcid { c: 'V' as u8, p: 0.02 }
,
80 AminoAcid { c: 'W' as u8, p: 0.02 }
,
81 AminoAcid { c: 'Y' as u8, p: 0.02 }
,
84 static HOMO_SAPIENS
: [AminoAcid
;4] = [
85 AminoAcid { c: 'a' as u8, p: 0.3029549426680 }
,
86 AminoAcid { c: 'c' as u8, p: 0.1979883004921 }
,
87 AminoAcid { c: 'g' as u8, p: 0.1975473066391 }
,
88 AminoAcid { c: 't' as u8, p: 0.3015094502008 }
,
92 fn sum_and_scale(a
: &'
static [AminoAcid
]) -> Vec
<AminoAcid
> {
93 let mut result
= Vec
::new();
98 a_i
.p
= p
* LOOKUP_SCALE
;
101 let result_len
= result
.len();
102 result
[result_len
- 1].p
= LOOKUP_SCALE
;
106 #[derive(Copy, Clone)]
112 struct RepeatFasta
<'a
, W
:'a
> {
117 impl<'a
, W
: Write
> RepeatFasta
<'a
, W
> {
118 fn new(alu
: &'
static str, w
: &'a
mut W
) -> RepeatFasta
<'a
, W
> {
119 RepeatFasta { alu: alu, out: w }
122 fn make(&mut self, n
: usize) -> io
::Result
<()> {
123 let alu_len
= self.alu
.len();
124 let mut buf
= repeat(0).take(alu_len
+ LINE_LEN
).collect
::<Vec
<_
>>();
125 let alu
: &[u8] = self.alu
.as_bytes();
127 for (slot
, val
) in buf
.iter_mut().zip(alu
) {
130 let buf_len
= buf
.len();
131 for (slot
, val
) in buf
[alu_len
..buf_len
].iter_mut().zip(&alu
[..LINE_LEN
]) {
139 bytes
= min(LINE_LEN
, n
);
140 try
!(self.out
.write_all(&buf
[pos
..pos
+ bytes
]));
141 try
!(self.out
.write_all(&[b'
\n'
]));
152 fn make_lookup(a
: &[AminoAcid
]) -> [AminoAcid
;LOOKUP_SIZE
] {
153 let mut lookup
= [ NULL_AMINO_ACID
;LOOKUP_SIZE
];
155 for (i
, slot
) in lookup
.iter_mut().enumerate() {
156 while a
[j
].p
< (i
as f32) {
164 struct RandomFasta
<'a
, W
:'a
> {
166 lookup
: [AminoAcid
;LOOKUP_SIZE
],
170 impl<'a
, W
: Write
> RandomFasta
<'a
, W
> {
171 fn new(w
: &'a
mut W
, a
: &[AminoAcid
]) -> RandomFasta
<'a
, W
> {
175 lookup
: make_lookup(a
),
179 fn rng(&mut self, max
: f32) -> f32 {
180 self.seed
= (self.seed
* IA
+ IC
) % IM
;
181 max
* (self.seed
as f32) / (IM
as f32)
184 fn nextc(&mut self) -> u8 {
185 let r
= self.rng(1.0);
186 for a
in &self.lookup
[..] {
194 fn make(&mut self, n
: usize) -> io
::Result
<()> {
195 let lines
= n
/ LINE_LEN
;
196 let chars_left
= n
% LINE_LEN
;
197 let mut buf
= [0;LINE_LEN
+ 1];
200 for i
in 0..LINE_LEN
{
201 buf
[i
] = self.nextc();
203 buf
[LINE_LEN
] = '
\n'
as u8;
204 try
!(self.out
.write(&buf
));
206 for i
in 0..chars_left
{
207 buf
[i
] = self.nextc();
209 self.out
.write_all(&buf
[..chars_left
])
214 let mut args
= env
::args();
215 let n
= if args
.len() > 1 {
216 args
.nth(1).unwrap().parse
::<usize>().unwrap()
221 let mut out
= io
::stdout();
223 out
.write_all(b
">ONE Homo sapiens alu\n").unwrap();
225 let mut repeat
= RepeatFasta
::new(ALU
, &mut out
);
226 repeat
.make(n
* 2).unwrap();
229 out
.write_all(b
">TWO IUB ambiguity codes\n").unwrap();
230 let iub
= sum_and_scale(&IUB
);
231 let mut random
= RandomFasta
::new(&mut out
, &iub
);
232 random
.make(n
* 3).unwrap();
234 random
.out
.write_all(b
">THREE Homo sapiens frequency\n").unwrap();
235 let homo_sapiens
= sum_and_scale(&HOMO_SAPIENS
);
236 random
.lookup
= make_lookup(&homo_sapiens
);
237 random
.make(n
* 5).unwrap();
239 random
.out
.write_all(b
"\n").unwrap();