199 строки
4.4 KiB
C++
199 строки
4.4 KiB
C++
/* The Computer Language Benchmarks Game
|
|
http://shootout.alioth.debian.org/
|
|
contributed by Andrew Moon
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
// limit output, so we do not benchmark speed of printing
|
|
void puts_limited(char *x)
|
|
{
|
|
static int left = 550;
|
|
int len = strlen(x);
|
|
if (len <= left) {
|
|
puts(x);
|
|
left -= len;
|
|
return;
|
|
}
|
|
if (left > 0) {
|
|
x[left] = '\0';
|
|
puts(x);
|
|
x[left] = 'z';
|
|
left = 0;
|
|
}
|
|
}
|
|
|
|
struct Random {
|
|
enum { IM = 139968, IA = 3877, IC = 29573 };
|
|
Random() : last(42) {}
|
|
float get( float max = 1.0f ) {
|
|
last = ( last * IA + IC ) % IM;
|
|
return max * last / IM;
|
|
}
|
|
protected:
|
|
unsigned int last;
|
|
} rng;
|
|
|
|
struct IUB {
|
|
int c;
|
|
double p;
|
|
unsigned int pi;
|
|
};
|
|
|
|
struct Cumulative {
|
|
enum { slots = 512, };
|
|
|
|
Cumulative( IUB *start ) {
|
|
double p = 0;
|
|
for ( IUB *iter = start; iter->c; ++iter ) {
|
|
p += iter->p;
|
|
iter->p = p < 1.0 ? p : 1.0;
|
|
iter->pi = (unsigned int )( iter->p * slots );
|
|
}
|
|
|
|
for ( unsigned int i = 0; i <= slots; i++ ) {
|
|
while ( i > start->pi && start->pi != 0) {
|
|
++start;
|
|
}
|
|
|
|
table[i] = start;
|
|
}
|
|
}
|
|
|
|
const char operator[] ( float pct ) const {
|
|
IUB *iter = table[(unsigned int )( pct * slots )];
|
|
while ( iter->p < pct )
|
|
++iter;
|
|
return iter->c;
|
|
}
|
|
|
|
protected:
|
|
IUB *table[slots + 1];
|
|
};
|
|
|
|
static const size_t lineLength = 60;
|
|
|
|
struct LineBuffer {
|
|
LineBuffer() : lastN(0) {}
|
|
LineBuffer &genrand( Cumulative &table, size_t N ) {
|
|
//assert(N <= lineLength);
|
|
for ( size_t i = 0; i < N; i++ )
|
|
buffer[i] = table[rng.get()];
|
|
buffer[N] = '\n';
|
|
buffer[N+1] = '\0';
|
|
lastN = N + 1;
|
|
return *this;
|
|
}
|
|
void writeline() { puts_limited(buffer); }
|
|
protected:
|
|
char buffer[lineLength + 2];
|
|
size_t lastN;
|
|
};
|
|
|
|
struct RotatingString {
|
|
RotatingString( const char *in ) : pos(0) {
|
|
size = strlen( in );
|
|
buffer = new char[size + lineLength];
|
|
memcpy( buffer, in, size );
|
|
memcpy( buffer + size, in, lineLength );
|
|
}
|
|
~RotatingString() { delete[] buffer; }
|
|
void write( size_t bytes ) {
|
|
char* temp = new char[bytes+2];
|
|
memcpy(temp, buffer + pos, bytes);
|
|
temp[bytes] = '\n';
|
|
temp[bytes] = '\0';
|
|
puts_limited(temp);
|
|
delete temp;
|
|
pos += bytes;
|
|
if ( pos > size )
|
|
pos -= size;
|
|
}
|
|
protected:
|
|
char *buffer;
|
|
size_t size, pos;
|
|
};
|
|
|
|
template< class Output >
|
|
void makeFasta( const char *id, const char *desc, size_t N, Output &output ) {
|
|
while ( N ) {
|
|
const size_t bytes = N < lineLength ? N : lineLength;
|
|
output.writeline( bytes );
|
|
N -= bytes;
|
|
}
|
|
}
|
|
|
|
struct Repeater {
|
|
Repeater( const char *alu ) : rot(alu) {}
|
|
void writeline( size_t bytes ) { rot.write( bytes ); }
|
|
void run( const char *id, const char *desc, size_t N ) {
|
|
makeFasta( id, desc, N, *this );
|
|
}
|
|
protected:
|
|
RotatingString rot;
|
|
};
|
|
|
|
struct Randomized {
|
|
Randomized( IUB *start ) : table(start) {}
|
|
void writeline( size_t bytes ) { line.genrand(table, bytes).writeline(); }
|
|
void run( const char *id, const char *desc, size_t N ) {
|
|
makeFasta( id, desc, N, *this );
|
|
}
|
|
protected:
|
|
Cumulative table;
|
|
LineBuffer line;
|
|
};
|
|
|
|
IUB iub[] = {
|
|
{ 'a', 0.27, 0 },
|
|
{ 'c', 0.12, 0 },
|
|
{ 'g', 0.12, 0 },
|
|
{ 't', 0.27, 0 },
|
|
|
|
{ 'B', 0.02, 0 },
|
|
{ 'D', 0.02, 0 },
|
|
{ 'H', 0.02, 0 },
|
|
{ 'K', 0.02, 0 },
|
|
{ 'M', 0.02, 0 },
|
|
{ 'N', 0.02, 0 },
|
|
{ 'R', 0.02, 0 },
|
|
{ 'S', 0.02, 0 },
|
|
{ 'V', 0.02, 0 },
|
|
{ 'W', 0.02, 0 },
|
|
{ 'Y', 0.02, 0 },
|
|
{ 0, 0, 0 },
|
|
};
|
|
|
|
IUB homosapiens[] = {
|
|
{ 'a', 0.3029549426680, 0 },
|
|
{ 'c', 0.1979883004921, 0 },
|
|
{ 'g', 0.1975473066391, 0 },
|
|
{ 't', 0.3015094502008, 0 },
|
|
{ 0, 0, 0 },
|
|
};
|
|
|
|
static const char alu[] =
|
|
"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG"
|
|
"GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA"
|
|
"GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA"
|
|
"AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT"
|
|
"CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC"
|
|
"CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG"
|
|
"CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
|
|
|
|
int main( int argc, const char *argv[] ) {
|
|
const size_t n = ( argc > 1 ) ? atoi( argv[1] ) : 512;
|
|
|
|
Repeater(alu)
|
|
.run( "ONE", "Homo sapiens alu", n*2 );
|
|
Randomized(iub)
|
|
.run( "TWO", "IUB ambiguity codes", n*3 );
|
|
Randomized(homosapiens)
|
|
.run( "THREE", "Homo sapiens frequency", n*5 );
|
|
|
|
return 0;
|
|
}
|
|
|