#!/usr/bin/perl

use strict;
use warnings;

my $random_state;

sub srand{
    use integer;
    my @state = (shift || time || 5489);
    # initialise with a lesser RNG
    for (1 .. 624){ 
        push @state, (1812433253 * ($state[$_ - 1] ^ ($state[$_ - 1] >> 30)) + $_); 
    }
    $random_state = {
	state => \@state,
	offset => 624
    }
}

sub twist{
    use integer;
    my ($u, $v) = @_;
    my $t = (($u & 0x80000000) | ($v & 0x7fffffff)) >> 1;
    my $s = ($v & 1) ? 0x9908b0df : 0;
    return $t ^ $s;
}

sub temper{ 
    use integer;
    my $y = shift;
    $y ^= ($y >> 11);
    $y ^= ($y << 7) & 0x9d2c5680;
    $y ^= ($y << 15) & 0xefc60000;
    $y ^= ($y >> 18);
    return $y;
}    

sub rand{
    use integer;
    my $scale = shift || 1.0;
    ::srand() unless defined $random_state;
    if ($random_state->{offset} > 623){
	my $state = $random_state->{state};
	for (0 .. 623){	
	    $$state[$_] = ($$state[($_ + 397) % 624] ^ 
			   twist($$state[$_], $$state[($_ + 1) % 624]));
	}
	$random_state->{offset} = 0;
    }   
    my $y = temper($random_state->{state}->[$random_state->{offset}]);
    #$y >>= 1; #for 31 bit perl int
    $random_state->{offset}++;
    { 
	no integer;
	return  $y * $scale / 2**31;
    }
}


my $sum = 0;

#&srand(2);

for (1..1000000){
    $sum += &rand();
}

#for (1..20){
#    $sum += &rand();
#    print &rand()."\n";
#
#}

print $sum."\n";

