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.
41 #![feature(slicing_syntax)]
44 use std::io::{stdout, IoResult};
46 use std::slice::bytes::copy_memory;
47 use std::str::from_str;
49 const LINE_LEN: uint = 60;
50 const LOOKUP_SIZE: uint = 4 * 1024;
51 const LOOKUP_SCALE: f32 = (LOOKUP_SIZE - 1) as f32;
53 // Random number generator constants
54 const IM: u32 = 139968;
56 const IC: u32 = 29573;
58 const ALU: &'static str = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG\
59 GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA\
60 GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA\
61 AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT\
62 CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC\
63 CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG\
64 CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
66 const NULL_AMINO_ACID: AminoAcid = AminoAcid { c: ' ' as u8, p: 0.0 };
68 static IUB: [AminoAcid;15] = [
69 AminoAcid { c: 'a' as u8, p: 0.27 },
70 AminoAcid { c: 'c' as u8, p: 0.12 },
71 AminoAcid { c: 'g' as u8, p: 0.12 },
72 AminoAcid { c: 't' as u8, p: 0.27 },
73 AminoAcid { c: 'B' as u8, p: 0.02 },
74 AminoAcid { c: 'D' as u8, p: 0.02 },
75 AminoAcid { c: 'H' as u8, p: 0.02 },
76 AminoAcid { c: 'K' as u8, p: 0.02 },
77 AminoAcid { c: 'M' as u8, p: 0.02 },
78 AminoAcid { c: 'N' as u8, p: 0.02 },
79 AminoAcid { c: 'R' as u8, p: 0.02 },
80 AminoAcid { c: 'S' as u8, p: 0.02 },
81 AminoAcid { c: 'V' as u8, p: 0.02 },
82 AminoAcid { c: 'W' as u8, p: 0.02 },
83 AminoAcid { c: 'Y' as u8, p: 0.02 },
86 static HOMO_SAPIENS: [AminoAcid;4] = [
87 AminoAcid { c: 'a' as u8, p: 0.3029549426680 },
88 AminoAcid { c: 'c' as u8, p: 0.1979883004921 },
89 AminoAcid { c: 'g' as u8, p: 0.1975473066391 },
90 AminoAcid { c: 't' as u8, p: 0.3015094502008 },
94 fn sum_and_scale(a: &'static [AminoAcid]) -> Vec<AminoAcid> {
95 let mut result = Vec::new();
100 a_i.p = p * LOOKUP_SCALE;
103 let result_len = result.len();
104 result[result_len - 1].p = LOOKUP_SCALE;
113 impl Copy for AminoAcid {}
115 struct RepeatFasta<'a, W:'a> {
120 impl<'a, W: Writer> RepeatFasta<'a, W> {
121 fn new(alu: &'static str, w: &'a mut W) -> RepeatFasta<'a, W> {
122 RepeatFasta { alu: alu, out: w }
125 fn make(&mut self, n: uint) -> IoResult<()> {
126 let alu_len = self.alu.len();
127 let mut buf = Vec::from_elem(alu_len + LINE_LEN, 0u8);
128 let alu: &[u8] = self.alu.as_bytes();
130 copy_memory(buf.as_mut_slice(), alu);
131 let buf_len = buf.len();
132 copy_memory(buf.slice_mut(alu_len, buf_len),
139 bytes = min(LINE_LEN, n);
140 try!(self.out.write(buf.slice(pos, pos + bytes)));
141 try!(self.out.write_u8('\n' as u8));
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: Writer> 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.iter() {
194 fn make(&mut self, n: uint) -> IoResult<()> {
195 let lines = n / LINE_LEN;
196 let chars_left = n % LINE_LEN;
197 let mut buf = [0;LINE_LEN + 1];
199 for _ in range(0, lines) {
200 for i in range(0u, LINE_LEN) {
201 buf[i] = self.nextc();
203 buf[LINE_LEN] = '\n' as u8;
204 try!(self.out.write(&buf));
206 for i in range(0u, chars_left) {
207 buf[i] = self.nextc();
209 self.out.write(buf[..chars_left])
214 let args = os::args();
215 let args = args.as_slice();
216 let n = if args.len() > 1 {
217 from_str::<uint>(args[1].as_slice()).unwrap()
222 let mut out = stdout();
224 out.write_line(">ONE Homo sapiens alu").unwrap();
226 let mut repeat = RepeatFasta::new(ALU, &mut out);
227 repeat.make(n * 2).unwrap();
230 out.write_line(">TWO IUB ambiguity codes").unwrap();
231 let iub = sum_and_scale(&IUB);
232 let mut random = RandomFasta::new(&mut out, iub.as_slice());
233 random.make(n * 3).unwrap();
235 random.out.write_line(">THREE Homo sapiens frequency").unwrap();
236 let homo_sapiens = sum_and_scale(&HOMO_SAPIENS);
237 random.lookup = make_lookup(homo_sapiens.as_slice());
238 random.make(n * 5).unwrap();
240 random.out.write_str("\n").unwrap();