use strict;
use warnings;
no warnings 'portable';
use feature 'say';
use Math::AnyNum qw(:overload);

package splitmix64 {

    sub new {
        my ($class, %opt) = @_;
        bless {state => $opt{seed}}, $class;
    }

    sub next_int {
        my ($self) = @_;
        my $next = $self->{state} = ($self->{state} + 0x9e3779b97f4a7c15) & (2**64 - 1);
        $next = ($next ^ ($next >> 30)) * 0xbf58476d1ce4e5b9 & (2**64 - 1);
        $next = ($next ^ ($next >> 27)) * 0x94d049bb133111eb & (2**64 - 1);
        ($next ^ ($next >> 31)) & (2**64 - 1);
    }

    sub next_float {
        my ($self) = @_;
        $self->next_int / 2**64;
    }
}

say 'Seed: 1234567, first 5 values:';
my $rng = splitmix64->new(seed => 1234567);
say $rng->next_int for 1 .. 5;

my %h;
say "\nSeed: 987654321, values histogram:";
$rng = splitmix64->new(seed => 987654321);
$h{int 5 * $rng->next_float}++ for 1 .. 100_000;
say "$_ $h{$_}" for sort keys %h;


import Data.Bits
import Data.Word
import System.Random
import Data.List

newtype XorShift = XorShift Word64

instance RandomGen XorShift where
   next (XorShift state) = (out newState, XorShift newState)
     where
       newState = (\z -> z `xor` (z `shiftR` 27)) .
                  (\z -> z `xor` (z `shiftL` 25)) .
                  (\z -> z `xor` (z `shiftR` 12)) $ state
       out x = fromIntegral $ (x * 0x2545f4914f6cdd1d) `shiftR` 32

   split _ = error "XorShift is not splittable"

randoms' :: RandomGen g => g -> [Int]
randoms' = unfoldr (pure . next)

toFloat n = fromIntegral n / (2^32 - 1)


public class XorShiftStar {
    private static final long MAGIC = Long.parseUnsignedLong("2545F4914F6CDD1D", 16);
    private long state;

    public void seed(long num) {
        state = num;
    }

    public int nextInt() {
        long x;
        int answer;

        x = state;
        x = x ^ (x >>> 12);
        x = x ^ (x << 25);
        x = x ^ (x >>> 27);
        state = x;
        answer = (int) ((x * MAGIC) >> 32);

        return answer;
    }

    public float nextFloat() {
        return (float) Integer.toUnsignedLong(nextInt()) / (1L << 32);
    }

    public static void main(String[] args) {
        var rng = new XorShiftStar();
        rng.seed(1234567);
        System.out.println(Integer.toUnsignedString(rng.nextInt()));
        System.out.println(Integer.toUnsignedString(rng.nextInt()));
        System.out.println(Integer.toUnsignedString(rng.nextInt()));
        System.out.println(Integer.toUnsignedString(rng.nextInt()));
        System.out.println(Integer.toUnsignedString(rng.nextInt()));
        System.out.println();

        int[] counts = {0, 0, 0, 0, 0};
        rng.seed(987654321);
        for (int i = 0; i < 100_000; i++) {
            int j = (int) Math.floor(rng.nextFloat() * 5.0);
            counts[j]++;
        }
        for (int i = 0; i < counts.length; i++) {
            System.out.printf("%d: %d\n", i, counts[i]);
        }
    }
}


with javascript_semantics
include mpfr.e
mpz state = mpz_init(),
    shift = mpz_init("0x9e3779b97f4a7c15"),
    mult1 = mpz_init("0xbf58476d1ce4e5b9"),
    mult2 = mpz_init("0x94d049bb133111eb"),
      b64 = mpz_init("0x10000000000000000"),  -- (truncate to 64 bits)
      tmp = mpz_init(),
        z = mpz_init()

procedure seed(integer num)
    mpz_set_si(state,num)
end procedure

procedure next_int()
    mpz_add(state, state, shift)    -- state += shift
    mpz_fdiv_r(state, state, b64)   -- state := remainder(z,b64)
    mpz_set(z, state)               -- z := state
    mpz_tdiv_q_2exp(tmp, z, 30)     -- tmp := trunc(z/2^30)
    mpz_xor(z, z, tmp)              -- z := xor_bits(z,tmp)
    mpz_mul(z, z, mult1)            -- z *= mult1
    mpz_fdiv_r(z, z, b64)           -- z := remainder(z,b64)
    mpz_tdiv_q_2exp(tmp, z, 27)     -- tmp := trunc(z/2^27)
    mpz_xor(z, z, tmp)              -- z := xor_bits(z,tmp)
    mpz_mul(z, z, mult2)            -- z *= mult2
    mpz_fdiv_r(z, z, b64)           -- z := remainder(z,b64)
    mpz_tdiv_q_2exp(tmp, z, 31)     -- tmp := trunc(z/2^31)
    mpz_xor(z, z, tmp)              -- z := xor_bits(z,tmp)
    -- (result left in z)
end procedure

function next_float()
    next_int()
    mpfr f = mpfr_init_set_z(z)
    mpfr_div_z(f, f, b64)
    return mpfr_get_d(f)
end function

seed(1234567)
for i=1 to 5 do
    next_int()
    printf(1,"%s\n",mpz_get_str(z))
end for
seed(987654321)
sequence r = repeat(0,5)
for i=1 to 100000 do
    integer rdx = floor(next_float()*5)+1
    r[rdx] += 1
end for
?r


program splitmix64;

{$IF Defined(FPC)}{$MODE Delphi}{$ENDIF}
{$INLINE ON}
{$Q-}{$R-}

{
  Written in 2015 by Sebastiano Vigna ([email protected])
  http://prng.di.unimi.it/splitmix64.c

  Onject Pascal port written in 2020 by I. Kakoulidis

  To the extent possible under law, the author has dedicated all copyright
  and related and neighboring rights to this software to the public domain
  worldwide. This software is distributed without any warranty.

  See <http://creativecommons.org/publicdomain/zero/1.0/>.
}

{
  This is a fixed-increment version of Java 8's SplittableRandom generator
  See http://dx.doi.org/10.1145/2714064.2660195 and
  http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html

  It is a very fast generator passing BigCrush, and it can be useful if
  for some reason you absolutely want 64 bits of state.
}
uses Math;

type
  TSplitMix64 = record
    state: UInt64;
    procedure Init(seed: UInt64); inline;
    function Next(): UInt64; inline;
    function NextFloat(): double; inline;
  end;

procedure TSplitMix64.Init(seed: UInt64);
begin
  state := seed;
end;

function TSplitMix64.Next(): UInt64;
begin
  state := state + UInt64($9e3779b97f4a7c15);
  Result := state;
  Result := (Result xor (Result shr 30)) * UInt64($bf58476d1ce4e5b9);
  Result := (Result xor (Result shr 27)) * UInt64($94d049bb133111eb);
  Result := Result xor (Result shr 31);
end;

function TSplitMix64.NextFloat(): Double;
begin
  Result := Next() / 18446744073709551616.0;
end;

var
  r: TSplitMix64;
  i, j: Integer;
  vec: array[0..4] of Integer;

begin
  j := 0;
  r.Init(1234567);
  for i := 0 to 4 do
    WriteLn(r.Next());

  r.Init(987654321);
  for i := 0 to 99999 do
  begin
    j := Trunc(r.NextFloat() * 5.0);
    Inc(vec[j]);
  end;

  for i := 0 to 4 do
    Write(i, ': ', vec[i], '  ');
end.


const mask32 = (0x1 << 32) - 1
const CONST = 0x2545F4914F6CDD1D

mutable struct XorShiftStar
     state::UInt64
end

XorShiftStar(_seed=0x0) = XorShiftStar(UInt(_seed))

seed(x::XorShiftStar, num) = begin x.state = UInt64(num) end

"""return random int between 0 and 2**32"""
function next_int(x::XorShiftStar)
    x.state = x.state ⊻ (x.state >> 12)
    x.state = x.state ⊻ (x.state << 25)
    x.state = x.state ⊻ (x.state >> 27)
    return ((x.state * CONST) >> 32) & mask32
end

"""return random float between 0 and 1"""
next_float(x::XorShiftStar) = next_int(x) / (1 << 32)

function testXorShiftStar()
    random_gen = XorShiftStar()
    seed(random_gen, 1234567)
    for i in 1:5
        println(next_int(random_gen))
    end
    seed(random_gen, 987654321)
    hist = fill(0, 5)
    for _ in 1:100_000
        hist[Int(floor(next_float(random_gen) * 5)) + 1] += 1
    end
    foreach(n -> print(n - 1, ": ", hist[n], "  "), 1:5)
end

testXorShiftStar()


import kotlin.math.floor

class XorShiftStar {
    private var state = 0L

    fun seed(num: Long) {
        state = num
    }

    fun nextInt(): Int {
        var x = state
        x = x xor (x ushr 12)
        x = x xor (x shl 25)
        x = x xor (x ushr 27)
        state = x

        return (x * MAGIC shr 32).toInt()
    }

    fun nextFloat(): Float {
        return nextInt().toUInt().toFloat() / (1L shl 32)
    }

    companion object {
        private const val MAGIC = 0x2545F4914F6CDD1D
    }
}

fun main() {
    val rng = XorShiftStar()

    rng.seed(1234567)
    println(rng.nextInt().toUInt())
    println(rng.nextInt().toUInt())
    println(rng.nextInt().toUInt())
    println(rng.nextInt().toUInt())
    println(rng.nextInt().toUInt())
    println()

    rng.seed(987654321)
    val counts = arrayOf(0, 0, 0, 0, 0)
    for (i in 1..100000) {
        val j = floor(rng.nextFloat() * 5.0).toInt()
        counts[j]++
    }
    for (iv in counts.withIndex()) {
        println("${iv.index}: ${iv.value}")
    }
}


function create()
    local g = {
        magic = 0x2545F4914F6CDD1D,
        state = 0,
        seed = function(self, num)
            self.state = num
        end,
        next_int = function(self)
            local x = self.state
            x = x ~ (x >> 12)
            x = x ~ (x << 25)
            x = x ~ (x >> 27)
            self.state = x
            local answer = (x * self.magic) >> 32
            return answer
        end,
        next_float = function(self)
            return self:next_int() / (1 << 32)
        end
    }
    return g
end

local g = create()
g:seed(1234567)
print(g:next_int())
print(g:next_int())
print(g:next_int())
print(g:next_int())
print(g:next_int())
print()

local counts = {[0]=0, [1]=0, [2]=0, [3]=0, [4]=0}
g:seed(987654321)
for i=1,100000 do
    local j = math.floor(g:next_float() * 5.0)
    counts[j] = counts[j] + 1
end
for i,v in pairs(counts) do
    print(i..': '..v)
end


(zero *Split)     # global state

(de mod64 (N)
   (& N `(hex "FFFFFFFFFFFFFFFF")) )
(de mod64+ (A B)
   (mod64 (+ A B)) )
(de mod64* (A B)
   (mod64 (* A B)) )
(de roundf (N)    # rounds down
   (/ N (** 10 *Scl)) )
(de nextSplit ()
   (setq *Split (mod64+ *Split `(hex "9e3779b97f4a7c15")))
   (let Z *Split
      (setq
         Z (mod64* `(hex "bf58476d1ce4e5b9") (x| Z (>> 30 Z)))
         Z (mod64* `(hex "94d049bb133111eb") (x| Z (>> 27 Z))) )
      (x| Z (>> 31 Z)) ) )

(prinl "First 5 numbers:")
(setq *Split 1234567)
(do 5
   (println (nextSplit)) )

(prinl "The counts for 100,000 repetitions are:")
(scl 12)
(off R)
(setq *Split 987654321)
(do 100000
   (accu
      'R
      (roundf (* 5 (*/ (nextSplit) 1.0 18446744073709551616)))
      1 ) )
(mapc println (sort R))


MASK64 = (1 << 64) - 1
C1 = 0x9e3779b97f4a7c15
C2 = 0xbf58476d1ce4e5b9
C3 = 0x94d049bb133111eb

class Splitmix64():

    def __init__(self, seed=0):
        self.state = seed & MASK64

    def seed(self, num):
        self.state =  num & MASK64

    def next_int(self):
        "return random int between 0 and 2**64"
        z = self.state = (self.state + C1) & MASK64
        z = ((z ^ (z >> 30)) * C2) & MASK64
        z = ((z ^ (z >> 27)) * C3) & MASK64
        answer = (z ^ (z >> 31)) & MASK64

        return answer

    def  next_float(self):
        "return random float between 0 and 1"
        return self.next_int() / (1 << 64)

if __name__ == '__main__':
    random_gen = Splitmix64()
    random_gen.seed(1234567)
    for i in range(5):
        print(random_gen.next_int())

    random_gen.seed(987654321)
    hist = {i:0 for i in range(5)}
    for i in range(100_000):
        hist[int(random_gen.next_float() *5)] += 1
    print(hist)


class splitmix64 {
    has $!state;

    submethod BUILD ( Int :$seed where * >= 0 = 1 ) { $!state = $seed }

    method next-int {
        my $next = $!state = ($!state + 0x9e3779b97f4a7c15) +& (2⁶⁴ - 1);
        $next = ($next +^ ($next +> 30)) * 0xbf58476d1ce4e5b9 +& (2⁶⁴ - 1);
        $next = ($next +^ ($next +> 27)) * 0x94d049bb133111eb +& (2⁶⁴ - 1);
        ($next +^ ($next +> 31)) +& (2⁶⁴ - 1);
    }

    method next-rat { self.next-int / 2⁶⁴ }
}

# Test next-int
say 'Seed: 1234567; first five Int values';
my $rng = splitmix64.new( :seed(1234567) );
.say for $rng.next-int xx 5;

# Test next-rat (since these are rational numbers by default)
say "\nSeed: 987654321; first 1e5 Rat values histogram";
$rng = splitmix64.new( :seed(987654321) );
say ( ($rng.next-rat * 5).floor xx 100_000 ).Bag;


import algorithm, sequtils, strutils, tables

const C = 0x2545F4914F6CDD1Du64

type XorShift = object
  state: uint64

func seed(gen: var XorShift; num: uint64) =
  gen.state = num

func nextInt(gen: var XorShift): uint32 =
  var x = gen.state
  x = x xor x shr 12
  x = x xor x shl 25
  x = x xor x shr 27
  gen.state = x
  result = uint32((x * C) shr 32)

func nextFloat(gen: var XorShift): float =
  gen.nextInt().float / float(0xFFFFFFFFu32)

when isMainModule:

  var gen: XorShift

  gen.seed(1234567)

  for _ in 1..5:
    echo gen.nextInt()

  echo ""
  gen.seed(987654321)
  var counts: CountTable[int]
  for _ in 1..100_000:
    counts.inc int(gen.nextFloat() * 5)
  echo sorted(toSeq(counts.pairs)).mapIt($it[0] & ": " & $it[1]).join(", ")


use strict;
use warnings;
no warnings 'portable';
use feature 'say';
use Math::AnyNum qw(:overload);

package Xorshift_star {

    sub new {
        my ($class, %opt) = @_;
        bless {state => $opt{seed}}, $class;
    }

    sub next_int {
        my ($self) = @_;
        my $state = $self->{state};
        $state ^= $state >> 12;
        $state ^= $state << 25 & (2**64 - 1);
        $state ^= $state >> 27;
        $self->{state} = $state;
        ($state * 0x2545F4914F6CDD1D) >> 32 & (2**32 - 1);
    }

    sub next_float {
        my ($self) = @_;
        $self->next_int / 2**32;
    }
}

say 'Seed: 1234567, first 5 values:';
my $rng = Xorshift_star->new(seed => 1234567);
say $rng->next_int for 1 .. 5;

my %h;
say "\nSeed: 987654321, values histogram:";
$rng = Xorshift_star->new(seed => 987654321);
$h{int 5 * $rng->next_float}++ for 1 .. 100_000;
say "$_ $h{$_}" for sort keys %h;


with javascript_semantics
include mpfr.e
mpz cmult = mpz_init("0x2545F4914F6CDD1D"),
    state = mpz_init(),
      b64 = mpz_init("0x10000000000000000"),  -- (truncate to 64 bits)
      b32 = mpz_init("0x100000000"),          -- (truncate to 32 bits)
      tmp = mpz_init(),
        x = mpz_init()

procedure seed(integer num)
    mpz_set_si(state,num)
end procedure

function next_int()
    mpz_set(x,state)            -- x := state
    mpz_tdiv_q_2exp(tmp, x, 12) -- tmp := trunc(x/2^12)
    mpz_xor(x, x, tmp)          -- x := xor_bits(x,tmp)
    mpz_mul_2exp(tmp, x, 25)    -- tmp := x * 2^25.
    mpz_xor(x, x, tmp)          -- x := xor_bits(x,tmp)
    mpz_fdiv_r(x, x, b64)       -- x := remainder(x,b64)
    mpz_tdiv_q_2exp(tmp, x, 27) -- tmp := trunc(x/2^27)
    mpz_xor(x, x, tmp)          -- x := xor_bits(x,tmp)
    mpz_fdiv_r(state, x, b64)   -- state := remainder(x,b64)
    mpz_mul(x,x,cmult)          -- x *= cmult
    mpz_tdiv_q_2exp(x, x, 32)   -- x := trunc(x/2^32)
    mpz_fdiv_r(x, x, b32)       -- x := remainder(x,b32)
    return mpz_get_atom(x)
end function

function next_float()
    return next_int() / #100000000
end function

seed(1234567)
for i=1 to 5 do
    printf(1,"%d\n",next_int())
end for
seed(987654321)
sequence r = repeat(0,5)
for i=1 to 100000 do
    integer idx = floor(next_float()*5)+1
    r[idx] += 1
end for
?r


/*REXX program  generates   pseudo─random numbers   using the  split mix 64 bit  method.*/
numeric digits 200                               /*ensure enough decimal digs for mult. */
parse arg n reps pick seed1 seed2 .              /*obtain optional arguments from the CL*/
if     n=='' |     n==","  then    n=          5 /*Not specified?  Then use the default.*/
if  reps=='' |  reps==","  then reps=     100000 /* "      "         "   "   "     "    */
if  pick=='' |  pick==","  then pick=          5 /* "      "         "   "   "     "    */
if seed1=='' | seed1==","  then seed1=   1234567 /* "      "         "   "   "     "    */
if seed2=='' | seed2==","  then seed2= 987654321 /* "      "         "   "   "     "    */
const.1= x2d( 9e3779b97f4a7c15 )                 /*initialize 1st constant to be used.  */
const.2= x2d('bf58476d1ce4e5b9')                 /*    "      2nd     "     "  "   "    */
const.3= x2d( 94d049bb133111eb )                 /*    "      3rd     "     "  "   "    */
o.30= copies(0, 30)                              /*construct  30  bits of zeros.        */
o.27= copies(0, 27)                              /*     "     27    "   "   "           */
o.31= copies(0, 31)                              /*     "     31    "   "   "           */
w= max(3, length(n) )                            /*for aligning the left side of output.*/
state= seed1                                     /*     "     the   state  to seed #1.  */
             do j=1  for n
             if j==1  then do;   say center('n', w)     "     pseudo─random number   "
                                 say copies('═', w)     " ════════════════════════════"
                           end
             say right(j':', w)" "  right(commas(next()), 27)  /*display a random number*/
             end   /*j*/
say
if reps==0  then exit 0                          /*stick a fork in it,  we're all done. */
say center('#', w)   "   count of pseudo─random #"
say copies('═', w)   " ════════════════════════════"
state= seed2                                     /*     "     the   state  to seed #2.  */
@.= 0;                         div= pick / 2**64 /*convert division to inverse multiply.*/
             do k=1  for reps
             parse value next()*div  with  _ '.' /*get random #, floor of a "division". */
             @._= @._ + 1                        /*bump the counter for this random num.*/
             end   /*k*/

             do #=0  for pick
             say right(#':', w)" "  right(commas(@.#), 15) /*show count of a random num.*/
             end   /*#*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: parse arg _;   do ?=length(_)-3  to 1  by -3; _= insert(',', _, ?); end;  return _
b2d:    parse arg ?; return        x2d( b2x(?) )             /*convert bin──►decimal.   */
d2b:    parse arg ?; return right( x2b( d2x(?) ),  64, 0)    /*convert dec──►64 bit bin.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
next: procedure expose state const. o.
      state= state + const.1        ; z= d2b(state)          /*add const1──►STATE; conv.*/
      z= xor(z, left(o.30 || z, 64)); z= d2b(b2d(z)*const.2) /*shiftR 30 bits & XOR;  " */
      z= xor(z, left(o.27 || z, 64)); z= d2b(b2d(z)*const.3) /*   "   27  "   "  "    " */
      z= xor(z, left(o.31 || z, 64));        return b2d(z)   /*   "   31  "   "  "    " */
/*──────────────────────────────────────────────────────────────────────────────────────*/
xor:  parse arg a, b;                    $=                  /*perform a bit─wise  XOR. */
                do !=1  for length(a);   $= $  ||  (substr(a,!,1)  &&  substr(b,!,1) )
                end   /*!*/;      return $


mask64 = (1 << 64) - 1
mask32 = (1 << 32) - 1
const = 0x2545F4914F6CDD1D

class Xorshift_star():

    def __init__(self, seed=0):
        self.state = seed & mask64

    def seed(self, num):
        self.state =  num & mask64

    def next_int(self):
        "return random int between 0 and 2**32"
        x = self.state
        x = (x ^ (x >> 12)) & mask64
        x = (x ^ (x << 25)) & mask64
        x = (x ^ (x >> 27)) & mask64
        self.state = x
        answer = (((x * const) & mask64) >> 32) & mask32
        return answer

    def  next_float(self):
        "return random float between 0 and 1"
        return self.next_int() / (1 << 32)

if __name__ == '__main__':
    random_gen = Xorshift_star()
    random_gen.seed(1234567)
    for i in range(5):
        print(random_gen.next_int())

    random_gen.seed(987654321)
    hist = {i:0 for i in range(5)}
    for i in range(100_000):
        hist[int(random_gen.next_float() *5)] += 1
    print(hist)


class Xorshift-star {
    has $!state;

    submethod BUILD ( Int :$seed where * > 0 = 1 ) { $!state = $seed }

    method next-int {
        $!state +^= $!state +> 12;
        $!state +^= $!state +< 25 +& (2⁶⁴ - 1);
        $!state +^= $!state +> 27;
        ($!state * 0x2545F4914F6CDD1D) +> 32 +& (2³² - 1)
    }

    method next-rat { self.next-int / 2³² }
}

# Test next-int
say 'Seed: 1234567; first five Int values';
my $rng = Xorshift-star.new( :seed(1234567) );
.say for $rng.next-int xx 5;

# Test next-rat (since these are rational numbers by default)
say "\nSeed: 987654321; first 1e5 Rat values histogram";
$rng = Xorshift-star.new( :seed(987654321) );
say ( ($rng.next-rat * 5).floor xx 100_000 ).Bag;

# Test with default seed
say "\nSeed: default; first five Int values";
$rng = Xorshift-star.new;
.say for $rng.next-int xx 5;


class Splitmix64
  MASK64 = (1 << 64) - 1
  C1, C2, C3 = 0x9e3779b97f4a7c15, 0xbf58476d1ce4e5b9, 0x94d049bb133111eb

  def initialize(seed = 0) =  @state = seed & MASK64

  def rand_i
    z = @state = (@state + C1) & MASK64
    z = ((z ^ (z >> 30)) * C2) & MASK64
    z = ((z ^ (z >> 27)) * C3) & MASK64
    (z ^ (z >> 31)) & MASK64
  end

  def rand_f = rand_i.fdiv(1<<64)

end

rand_gen = Splitmix64.new(1234567)
5.times{ puts rand_gen.rand_i }

rand_gen = Splitmix64.new(987654321)
p 100_000.times.lazy.map{(rand_gen.rand_f * 5).floor}.tally.sort.to_h


class Splitmix64(state) {

    define (
        mask64 = (2**64 - 1)
    )

    method next_int {
        var n = (state = ((state + 0x9e3779b97f4a7c15) & mask64))
        n = ((n ^ (n >> 30)) * 0xbf58476d1ce4e5b9 & mask64)
        n = ((n ^ (n >> 27)) * 0x94d049bb133111eb & mask64)
        (n ^ (n >> 31)) & mask64
    }

    method next_float {
        self.next_int / (mask64+1)
    }
}

say 'Seed: 1234567, first 5 values:'
var rng = Splitmix64(1234567)
5.of { rng.next_int.say }

say "\nSeed: 987654321, values histogram:"
var rng = Splitmix64(987654321)
var histogram = Bag(1e5.of { floor(5*rng.next_float) }...)
histogram.pairs.sort.each { .join(": ").say }


import "/big" for BigInt

var Const1 = BigInt.fromBaseString("9e3779b97f4a7c15", 16)
var Const2 = BigInt.fromBaseString("bf58476d1ce4e5b9", 16)
var Const3 = BigInt.fromBaseString("94d049bb133111eb", 16)
var Mask64 = (BigInt.one << 64) - BigInt.one

class Splitmix64 {
    construct new(state) {
        _state  = state
    }

    nextInt {
        _state = (_state + Const1) & Mask64
        var z = _state
        z = ((z ^ (z >> 30)) * Const2) & Mask64
        z = ((z ^ (z >> 27)) * Const3) & Mask64
        return (z ^ (z >> 31)) & Mask64
    }

    nextFloat { nextInt.toNum / 2.pow(64) }
}

var randomGen = Splitmix64.new(BigInt.new(1234567))
for (i in 0..4) System.print(randomGen.nextInt)

var counts = List.filled(5, 0)
randomGen = Splitmix64.new(BigInt.new(987654321))
for (i in 1..1e5) {
    var i = (randomGen.nextFloat * 5).floor
    counts[i] = counts[i] + 1
}
System.print("\nThe counts for 100,000 repetitions are:")
for (i in 0..4) System.print("  %(i) : %(counts[i])")


/*REXX program  generates   pseudo─random numbers   using the  XOR─shift─star  method.  */
numeric digits 200                               /*ensure enough decimal digs for mult. */
parse arg n reps pick seed1 seed2 .              /*obtain optional arguments from the CL*/
if     n=='' |     n==","  then    n=          5 /*Not specified?  Then use the default.*/
if  reps=='' |  reps==","  then reps=     100000 /* "      "         "   "   "     "    */
if  pick=='' |  pick==","  then pick=          5 /* "      "         "   "   "     "    */
if seed1=='' | seed1==","  then seed1=   1234567 /* "      "         "   "   "     "    */
if seed2=='' | seed2==","  then seed2= 987654321 /* "      "         "   "   "     "    */
const= x2d(2545f4914f6cdd1d)                     /*initialize the constant to be used.  */
o.12= copies(0, 12)                              /*construct  12  bits of zeros.        */
o.25= copies(0, 25)                              /*     "     25    "   "   "           */
o.27= copies(0, 27)                              /*     "     27    "   "   "           */
w= max(3, length(n) )                            /*for aligning the left side of output.*/
state= seed1                                     /*     "     the   state  to seed #1.  */
             do j=1  for n
             if j==1  then do;   say center('n', w)   "    pseudo─random number"
                                 say copies('═', w)   " ══════════════════════════"
                           end
             say right(j':', w)" "  right(commas(next()), 18)  /*display a random number*/
             end   /*j*/
say
if reps==0  then exit 0                          /*stick a fork in it,  we're all done. */
say center('#', w)   "  count of pseudo─random #"
say copies('═', w)   " ══════════════════════════"
state= seed2                                     /*     "     the   state  to seed #2.  */
@.= 0;                         div= pick / 2**32 /*convert division to inverse multiply.*/
             do k=1  for reps
             parse value next()*div  with  _ '.' /*get random #, floor of a "division". */
             @._= @._ + 1                        /*bump the counter for this random num.*/
             end   /*k*/

             do #=0  for pick
             say right(#':', w)" "  right(commas(@.#), 14) /*show count of a random num.*/
             end   /*#*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
b2d:    parse arg ?; return        x2d( b2x(?) )           /*convert bin ──► decimal.   */
d2b:    parse arg ?; return right( x2b( d2x(?) ),  64, 0)  /*convert dec ──► 64 bit bin.*/
commas: parse arg _;   do ?=length(_)-3  to 1  by -3; _= insert(',', _, ?); end;  return _
/*──────────────────────────────────────────────────────────────────────────────────────*/
next: procedure expose state const o.;  x= d2b(state)      /*convert  STATE  to binary. */
        x  = xor(x,  left( o.12 || x,  64) )               /*shift right 12 bits and XOR*/
        x  = xor(x, right( x || o.25,  64) )               /*  "    left 25  "    "   " */
        x  = xor(x,  left( o.27 || x,  64) )               /*  "   right 27  "    "   " */
      state= b2d(x)                                        /*set  STATE to the latest X.*/
      return b2d( left( d2b(state * const), 32) )          /*return a pseudo─random num.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
xor:  parse arg a, b;                     $=               /*perform a bit─wise  XOR.   */
                do !=1  for length(a);    $= $  ||  (substr(a,!,1)  &&  substr(b,!,1) )
                end   /*!*/;       return $


class Xorshift_star
  MASK64 = (1 << 64) - 1
  MASK32 = (1 << 32) - 1

  def initialize(seed = 0) = @state = seed & MASK64

  def next_int
    x = @state
    x =  x ^ (x >> 12)
    x = (x ^ (x << 25)) & MASK64
    x =  x ^ (x >> 27)
    @state = x
    (((x * 0x2545F4914F6CDD1D) & MASK64) >> 32) & MASK32
  end

  def next_float = next_int.fdiv((1 << 32))

end

random_gen =  Xorshift_star.new(1234567)
5.times{ puts random_gen.next_int}

random_gen = Xorshift_star.new(987654321)
tally      = Hash.new(0)
100_000.times{ tally[(random_gen.next_float*5).floor] += 1 }
puts tally.sort.map{|ar| ar.join(": ") }


class Xorshift_star(state) {

    define (
        mask32 = (2**32 - 1),
        mask64 = (2**64 - 1),
    )

    method next_int {
        state ^= (state >> 12)
        state ^= (state << 25 & mask64)
        state ^= (state >> 27)
        (state * 0x2545F4914F6CDD1D) >> 32 & mask32
    }

    method next_float {
        self.next_int / (mask32+1)
    }
}

say 'Seed: 1234567, first 5 values:';
var rng = Xorshift_star(1234567)
say 5.of { rng.next_int }

say "\nSeed: 987654321, values histogram:";
var rng = Xorshift_star(987654321)
var histogram = Bag(1e5.of { floor(5*rng.next_float) }...)
histogram.pairs.sort.each { .join(": ").say }


import Foundation

struct XorshiftStar {
  private let magic: UInt64 = 0x2545F4914F6CDD1D
  private var state: UInt64

  init(seed: UInt64) {
    state = seed
  }

  mutating func nextInt() -> UInt64 {
    state ^= state &>> 12
    state ^= state &<< 25
    state ^= state &>> 27

    return (state &* magic) &>> 32
  }

  mutating func nextFloat() -> Float {
    return Float(nextInt()) / Float(1 << 32)
  }
}

extension XorshiftStar: RandomNumberGenerator, IteratorProtocol, Sequence {
  mutating func next() -> UInt64 {
    return nextInt()
  }

  mutating func next() -> UInt64? {
    return nextInt()
  }
}

for (i, n) in XorshiftStar(seed: 1234567).lazy.enumerated().prefix(5) {
  print("\(i): \(n)")
}

var gen = XorshiftStar(seed: 987654321)
var counts = [Float: Int]()

for _ in 0..<100_000 {
  counts[floorf(gen.nextFloat() * 5), default: 0] += 1
}

print(counts)


import "/big" for BigInt

var Const  = BigInt.fromBaseString("2545F4914F6CDD1D", 16)
var Mask64 = (BigInt.one << 64) - BigInt.one
var Mask32 = (BigInt.one << 32) - BigInt.one

class XorshiftStar {
    construct new(state) {
        _state  = state & Mask64
    }

    seed(num) { _state = num & Mask64}

    nextInt {
        var x = _state
        x = (x ^ (x >> 12)) & Mask64
        x = (x ^ (x << 25)) & Mask64
        x = (x ^ (x >> 27)) & Mask64
        _state = x
        return (((x * Const) & Mask64) >> 32) & Mask32
    }

    nextFloat { nextInt.toNum / 2.pow(32) }
}

var randomGen = XorshiftStar.new(BigInt.new(1234567))
for (i in 0..4) System.print(randomGen.nextInt)

var counts = List.filled(5, 0)
randomGen.seed(BigInt.new(987654321))
for (i in 1..1e5) {
    var i = (randomGen.nextFloat * 5).floor
    counts[i] = counts[i] + 1
}
System.print("\nThe counts for 100,000 repetitions are:")
for (i in 0..4) System.print("  %(i) : %(counts[i])")


V a1 = [Int64(0), 1403580, -810728]
V m1 = Int64(2) ^ 32 - 209
V a2 = [Int64(527612), 0, -1370589]
V m2 = Int64(2) ^ 32 - 22853
V d = m1 + 1

T MRG32k3a
   [Int64] x1, x2

   F (seed_state = 123)
      .seed(seed_state)

   F seed(Int64 seed_state)
      assert(seed_state C Int64(0) <.< :d, ‘Out of Range 0 x < #.’.format(:d))
      .x1 = [Int64(seed_state), 0, 0]
      .x2 = [Int64(seed_state), 0, 0]

   F next_int()
      ‘return random int in range 0..d’
      V x1i = (sum(zip(:a1, .x1).map((aa, xx) -> aa * xx)) % :m1 + :m1) % :m1
      V x2i = (sum(zip(:a2, .x2).map((aa, xx) -> aa * xx)) % :m2 + :m2) % :m2
      .x1 = [x1i] [+] .x1[0.<2]
      .x2 = [x2i] [+] .x2[0.<2]
      V z = ((x1i - x2i) % :m1 + :m1) % :m1
      R z + 1

   F next_float()
      ‘return random float between 0 and 1’
      R Float(.next_int()) / :d

V random_gen = MRG32k3a()
random_gen.seed(1234567)
L 5
   print(random_gen.next_int())

random_gen.seed(987654321)
V hist = Dict(0.<5, i -> (i, 0))
L 100'000
   hist[Int(random_gen.next_float() * 5)]++
print(hist)


package MRG32KA is
   type I64 is range -2**63..2**63 - 1;
   m1 : constant I64 := 2**32 - 209;
   m2 : constant I64 := 2**32 - 22853;

   subtype state_value is I64 range 1..m1;

   procedure Seed (seed_state : state_value);
   function Next_Int return I64;
   function Next_Float return Long_Float;
end MRG32KA;


#include <math.h>
#include <stdio.h>
#include <stdint.h>

int64_t mod(int64_t x, int64_t y) {
    int64_t m = x % y;
    if (m < 0) {
        if (y < 0) {
            return m - y;
        } else {
            return m + y;
        }
    }
    return m;
}

// Constants
// First generator
const static int64_t a1[3] = { 0, 1403580, -810728 };
const static int64_t m1 = (1LL << 32) - 209;
// Second generator
const static int64_t a2[3] = { 527612, 0, -1370589 };
const static int64_t m2 = (1LL << 32) - 22853;

const static int64_t d = (1LL << 32) - 209 + 1; // m1 + 1

// the last three values of the first generator
static int64_t x1[3];
// the last three values of the second generator
static int64_t x2[3];

void seed(int64_t seed_state) {
    x1[0] = seed_state;
    x1[1] = 0;
    x1[2] = 0;

    x2[0] = seed_state;
    x2[1] = 0;
    x2[2] = 0;
}

int64_t next_int() {
    int64_t x1i = mod((a1[0] * x1[0] + a1[1] * x1[1] + a1[2] * x1[2]), m1);
    int64_t x2i = mod((a2[0] * x2[0] + a2[1] * x2[1] + a2[2] * x2[2]), m2);
    int64_t z = mod(x1i - x2i, m1);

    // keep last three values of the first generator
    x1[2] = x1[1];
    x1[1] = x1[0];
    x1[0] = x1i;

    // keep last three values of the second generator
    x2[2] = x2[1];
    x2[1] = x2[0];
    x2[0] = x2i;

    return z + 1;
}

double next_float() {
    return (double)next_int() / d;
}

int main() {
    int counts[5] = { 0, 0, 0, 0, 0 };
    int i;

    seed(1234567);
    printf("%lld\n", next_int());
    printf("%lld\n", next_int());
    printf("%lld\n", next_int());
    printf("%lld\n", next_int());
    printf("%lld\n", next_int());
    printf("\n");

    seed(987654321);
    for (i = 0; i < 100000; i++) {
        int64_t value = floor(next_float() * 5);
        counts[value]++;
    }
    for (i = 0; i < 5; i++) {
        printf("%d: %d\n", i, counts[i]);
    }

    return 0;
}


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program pRandom64.s   */

/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"

/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:        .asciz " @ \n"
szCarriageReturn:   .asciz "\n"

qSeed:              .quad 675248
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:                  .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                             // entry of program

    ldr x0,qAdrqSeed
    ldr x3,[x0]
    mov x2,#5
1:
    mov x0,x3
    bl computePseudo
    mov x3,x0
    ldr x1,qAdrsZoneConv
    bl conversion10               // call décimal conversion
    ldr x0,qAdrsMessResult
    ldr x1,qAdrsZoneConv          // insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess              // display message
    subs x2,x2,#1
    bgt 1b

100:                              // standard end of the program
    mov x0, #0                    // return code
    mov x8, #EXIT                 // request to exit program
    svc #0                        // perform the system call
qAdrszCarriageReturn:   .quad szCarriageReturn
qAdrsMessResult:        .quad sMessResult
qAdrsZoneConv:          .quad sZoneConv
qAdrqSeed:              .quad qSeed
/***************************************************/
/*   compute pseudo random number                  */
/***************************************************/
/* x0 contains the number            */
computePseudo:
    stp x1,lr,[sp,-16]! // save  registers
    stp x2,x3,[sp,-16]! // save  registers
    mov x2,x0
    mul x0,x2,x2
    ldr x2,qdiv
    udiv x1,x0,x2
    ldr x2,qdiv2
    udiv x0,x1,x2
    msub x0,x2,x0,x1
    ldp x2,x3,[sp],16   // restaur  2 registers
    ldp x1,lr,[sp],16   // restaur  2 registers
    ret                 // return to address lr x30
qdiv:            .quad 1000
qdiv2:           .quad 1000000

/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"


with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
   type long is range 0 .. 2**64;
   Seed : long := 675_248;
   function random return long is
   begin
      Seed := Seed * Seed / 1_000 rem 1_000_000;
      return Seed;
   end random;
begin
   for I in 1 .. 5 loop
      Put (long'Image (random));
   end loop;
   New_Line;
end Main;


#include <array>
#include <iostream>

int64_t mod(int64_t x, int64_t y) {
    int64_t m = x % y;
    if (m < 0) {
        if (y < 0) {
            return m - y;
        } else {
            return m + y;
        }
    }
    return m;
}

class RNG {
private:
    // First generator
    const std::array<int64_t, 3> a1{ 0, 1403580, -810728 };
    const int64_t m1 = (1LL << 32) - 209;
    std::array<int64_t, 3> x1;
    // Second generator
    const std::array<int64_t, 3> a2{ 527612, 0, -1370589 };
    const int64_t m2 = (1LL << 32) - 22853;
    std::array<int64_t, 3> x2;
    // other
    const int64_t d = (1LL << 32) - 209 + 1; // m1 + 1

public:
    void seed(int64_t state) {
        x1 = { state, 0, 0 };
        x2 = { state, 0, 0 };
    }

    int64_t next_int() {
        int64_t x1i = mod((a1[0] * x1[0] + a1[1] * x1[1] + a1[2] * x1[2]), m1);
        int64_t x2i = mod((a2[0] * x2[0] + a2[1] * x2[1] + a2[2] * x2[2]), m2);
        int64_t z = mod(x1i - x2i, m1);

        // keep last three values of the first generator
        x1 = { x1i, x1[0], x1[1] };
        // keep last three values of the second generator
        x2 = { x2i, x2[0], x2[1] };

        return z + 1;
    }

    double next_float() {
        return static_cast<double>(next_int()) / d;
    }
};

int main() {
    RNG rng;

    rng.seed(1234567);
    std::cout << rng.next_int() << '\n';
    std::cout << rng.next_int() << '\n';
    std::cout << rng.next_int() << '\n';
    std::cout << rng.next_int() << '\n';
    std::cout << rng.next_int() << '\n';
    std::cout << '\n';

    std::array<int, 5> counts{ 0, 0, 0, 0, 0 };
    rng.seed(987654321);
    for (size_t i = 0; i < 100000; i++) 		{
        auto value = floor(rng.next_float() * 5.0);
        counts[value]++;
    }
    for (size_t i = 0; i < counts.size(); i++) 		{
        std::cout << i << ": " << counts[i] << '\n';
    }

    return 0;
}


BEGIN # generate random numbers by the middle-square method #
    INT seed := 675248;
    # returns the next middle-square random number #
    PROC ms random = INT: seed := SHORTEN( ( ( LONG INT( seed ) * LONG INT( seed ) ) OVER 1000 ) MOD 1 000 000 );
    # test the ms random procedure #
    FOR i TO 5 DO
        print( ( " ", whole( ms random, 0 ) ) )
    OD
END


on newGenerator(n, seed)
    script generator
        property seed : missing value
        property p1 : 10 ^ (n div 2)
        property p2 : 10 ^ n

        on getRandom()
            set seed to seed * seed div p1 mod p2
            return seed div 1
        end getRandom
    end script

    set generator's seed to seed mod (10 ^ n)
    return generator
end newGenerator

local generator, output
set generator to newGenerator(6, 675248)
set output to {}
repeat 5 times
    set end of output to generator's getRandom()
end repeat
return output


/* ARM assembly Raspberry PI or android with termux */
/*  program pRandom.s   */

 /* REMARK 1 : this program use routines in a include file
   see task Include a file language arm assembly
   for the routine affichageMess conversion10
   see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes                       */
/************************************/
.include "../constantes.inc"

/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:        .asciz " @ \n"
szCarriageReturn:   .asciz "\n"

iSeed:              .int 675248
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:                  .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                             @ entry of program

    ldr r0,iAdriSeed
    ldr r3,[r0]
    mov r2,#5
1:
    mov r0,r3
    bl computePseudo
    mov r3,r0
    ldr r1,iAdrsZoneConv
    bl conversion10               @ call décimal conversion
    ldr r0,iAdrsMessResult
    ldr r1,iAdrsZoneConv          @ insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess              @ display message
    subs r2,r2,#1
    bgt 1b

100:                              @ standard end of the program
    mov r0, #0                    @ return code
    mov r7, #EXIT                 @ request to exit program
    svc #0                        @ perform the system call
iAdrszCarriageReturn:   .int szCarriageReturn
iAdrsMessResult:        .int sMessResult
iAdrsZoneConv:          .int sZoneConv
iAdriSeed:              .int iSeed
/***************************************************/
/*   compute pseudo random number                  */
/***************************************************/
/* r0 contains the number            */
computePseudo:
    push {r1-r2,lr}           @ save registers
    mov r2,r0
    umull r0,r1,r2,r2
    ldr r2,idiv
    bl division32R
    ldr r2,idiv2
    bl division32R
    mov r0,r2
    pop {r1-r2,pc}            @ restaur registers
idiv:            .int 1000
idiv2:           .int 1000000
/***************************************************/
/*   division number 64 bits in 2 registers by number 32 bits */
/***************************************************/
/* r0 contains lower part dividende   */
/* r1 contains upper part dividende   */
/* r2 contains divisor   */
/* r0 return lower part quotient    */
/* r1 return upper part quotient    */
/* r2 return remainder               */
division32R:
    push {r3-r9,lr}    @ save registers
    mov r6,#0          @ init upper upper part remainder  !!
    mov r7,r1          @ init upper part remainder with upper part dividende
    mov r8,r0          @ init lower part remainder with lower part dividende
    mov r9,#0          @ upper part quotient
    mov r4,#0          @ lower part quotient
    mov r5,#32         @ bits number
1:                     @ begin loop
    lsl r6,#1          @ shift upper upper part remainder
    lsls r7,#1         @ shift upper  part remainder
    orrcs r6,#1
    lsls r8,#1         @ shift lower  part remainder
    orrcs r7,#1
    lsls r4,#1         @ shift lower part quotient
    lsl r9,#1          @ shift upper part quotient
    orrcs r9,#1
                       @ divisor sustract  upper  part remainder
    subs r7,r2
    sbcs  r6,#0        @ and substract carry
    bmi 2f             @ négative ?

                       @ positive or equal
    orr r4,#1          @ 1 -> right bit quotient
    b 3f
2:                     @ negative
    orr r4,#0          @ 0 -> right bit quotient
    adds r7,r2         @ and restaur remainder
    adc  r6,#0
3:
    subs r5,#1         @ decrement bit size
    bgt 1b             @ end ?
    mov r0,r4          @ lower part quotient
    mov r1,r9          @ upper part quotient
    mov r2,r7          @ remainder
100:                   @ function end
    pop {r3-r9,lr}     @ restaur registers
    bx lr
/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../affichage.inc"


import std.math;
import std.stdio;

long mod(long x, long y) {
    long m = x % y;
    if (m < 0) {
        if (y < 0) {
            return m - y;
        } else {
            return m + y;
        }
    }
    return m;
}

class RNG {
private:
    // First generator
    immutable(long []) a1 = [0, 1403580, -810728];
    immutable long m1 = (1L << 32) - 209;
    long[3] x1;
    // Second generator
    immutable(long []) a2 = [527612, 0, -1370589];
    immutable long m2 = (1L << 32) - 22853;
    long[3] x2;
    // other
    immutable long d = m1 + 1;

public:
    void seed(long state) {
        x1 = [state, 0, 0];
        x2 = [state, 0, 0];
    }

    long next_int() {
        long x1i = mod((a1[0] * x1[0] + a1[1] * x1[1] + a1[2] * x1[2]), m1);
        long x2i = mod((a2[0] * x2[0] + a2[1] * x2[1] + a2[2] * x2[2]), m2);
        long z = mod(x1i - x2i, m1);

        // keep the last three values of the first generator
        x1 = [x1i, x1[0], x1[1]];
        // keep the last three values of the second generator
        x2 = [x2i, x2[0], x2[1]];

        return z + 1;
    }

    double next_float() {
        return cast(double) next_int() / d;
    }
}

void main() {
    auto rng = new RNG();

    rng.seed(1234567);
    writeln(rng.next_int);
    writeln(rng.next_int);
    writeln(rng.next_int);
    writeln(rng.next_int);
    writeln(rng.next_int);
    writeln;

    int[5] counts;
    rng.seed(987654321);
    foreach (i; 0 .. 100_000) {
        auto value = cast(int) floor(rng.next_float * 5.0);
        counts[value]++;
    }
    foreach (i,v; counts) {
        writeln(i, ": ", v);
    }
}


# syntax: GAWK -f PSEUDO-RANDOM_NUMBERS_MIDDLE-SQUARE_METHOD.AWK
BEGIN {
    seed = 675248
    srand(seed)
    for (i=1; i<=5; i++) {
      printf("%2d: %s\n",i,main())
    }
    exit(0)
}
function main(  s) {
    s = seed ^ 2
    while (length(s) < 12) {
      s = "0" s
    }
    seed = substr(s,4,6)
    return(seed)
}


#include<stdio.h>
long long seed;
long long random(){
        seed = seed * seed / 1000 % 1000000;
        return seed;
}
int main(){
        seed = 675248;
        for(int i=1;i<=5;i++)
                printf("%lld\n",random());
        return 0;
}


#include <exception>
#include <iostream>

using ulong = unsigned long;

class MiddleSquare {
private:
    ulong state;
    ulong div, mod;
public:
    MiddleSquare() = delete;
    MiddleSquare(ulong start, ulong length) {
        if (length % 2) throw std::invalid_argument("length must be even");
        div = mod = 1;
        for (ulong i=0; i<length/2; i++) div *= 10;
        for (ulong i=0; i<length; i++) mod *= 10;
        state = start % mod;
    }

    ulong next() {
        return state = state * state / div % mod;
    }
};

int main() {
    MiddleSquare msq(675248, 6);
    for (int i=0; i<5; i++)
        std::cout << msq.next() << std::endl;
    return 0;
}


USING: arrays kernel math math.order math.statistics
math.vectors prettyprint sequences ;

CONSTANT: m1 4294967087
CONSTANT: m2 4294944443

: seed ( n -- seq1 seq2 )
    dup 1 m1 between? t assert= 0 0 3array dup ;

: new-state ( seq1 seq2 n -- new-seq )
    [ dup ] [ vdot ] [ rem prefix but-last ] tri* ;

: next-state ( a b -- a' b' )
    [ { 0 1403580 -810728 } m1 new-state ]
    [ { 527612 0 -1370589 } m2 new-state ] bi* ;

: next-int ( a b -- a' b' n )
    next-state 2dup [ first ] [email protected] - m1 rem 1 + ;

: next-float ( a b -- a' b' x ) next-int m1 1 + /f ;

! Task
1234567 seed 5 [ next-int . ] times 2drop

987654321 seed 100,000 [ next-float 5 * >integer ] replicate
2nip histogram .


6 array (seed)                         \ holds the seed
6 array (gens)                         \ holds the generators
                                       \ set up constants
       0 (gens) 0 th !                 \ 1st generator
 1403580 (gens) 1 th !
 -810728 (gens) 2 th !
  527612 (gens) 3 th !                 \ 2nd generator
       0 (gens) 4 th !
-1370589 (gens) 5 th !

1 32 lshift   209 - value (m)          \ 1st generator constant
1 32 lshift 22853 - value (n)          \ 2nd generator constant
                                       ( n1 n2 -- n3)
: (mod) tuck mod tuck 0< if abs + ;then drop ;
: (generate) do (seed) i th @ (gens) i th @ * + loop swap (mod) ;
: (reseed) ?do (seed) i th ! loop ;    ( n1 n2 n3 limit index --)
: randomize 6 0 do dup i 3 mod if >zero then (seed) i th ! loop drop ;
                                       ( n --)
: random                               ( -- n)
  (m) 0 3 0 (generate) (n) 0 6 3 (generate) over over
  (seed) 4 th @ (seed) 3 th @ rot 6 3 (reseed)
  (seed) 1 th @ (seed) 0 th @ rot 3 0 (reseed) - (m) (mod) 1+
;

include lib/fp1.4th                    \ simple floating point support
include lib/zenfloor.4th               \ for FLOOR

5 array (count)                        \ setup an array of 5 elements

: test
  1234567 randomize
  random . cr random . cr random . cr
  random . cr random . cr cr           \ perform the first test

  987654321 randomize (m) 1+ s>f       \ set up denominator

  100000 0 ?do                         \ do this 100,000 times
    random s>f fover f/ 5 s>f f* floor f>s cells (count) + 1 swap +!
  loop fdrop
                                       \ show the results
  5 0 ?do i . ." : " (count) i th ? cr loop
;

test


package main

import (
    "fmt"
    "log"
    "math"
)

var a1 = []int64{0, 1403580, -810728}
var a2 = []int64{527612, 0, -1370589}

const m1 = int64((1 << 32) - 209)
const m2 = int64((1 << 32) - 22853)
const d = m1 + 1

// Python style modulus
func mod(x, y int64) int64 {
    m := x % y
    if m < 0 {
        if y < 0 {
            return m - y
        } else {
            return m + y
        }
    }
    return m
}

type MRG32k3a struct{ x1, x2 [3]int64 }

func MRG32k3aNew() *MRG32k3a { return &MRG32k3a{} }

func (mrg *MRG32k3a) seed(seedState int64) {
    if seedState <= 0 || seedState >= d {
        log.Fatalf("Argument must be in the range [0, %d].\n", d)
    }
    mrg.x1 = [3]int64{seedState, 0, 0}
    mrg.x2 = [3]int64{seedState, 0, 0}
}

func (mrg *MRG32k3a) nextInt() int64 {
    x1i := mod(a1[0]*mrg.x1[0]+a1[1]*mrg.x1[1]+a1[2]*mrg.x1[2], m1)
    x2i := mod(a2[0]*mrg.x2[0]+a2[1]*mrg.x2[1]+a2[2]*mrg.x2[2], m2)
    mrg.x1 = [3]int64{x1i, mrg.x1[0], mrg.x1[1]} /* keep last three */
    mrg.x2 = [3]int64{x2i, mrg.x2[0], mrg.x2[1]} /* keep last three */
    return mod(x1i-x2i, m1) + 1
}

func (mrg *MRG32k3a) nextFloat() float64 { return float64(mrg.nextInt()) / float64(d) }

func main() {
    randomGen := MRG32k3aNew()
    randomGen.seed(1234567)
    for i := 0; i < 5; i++ {
        fmt.Println(randomGen.nextInt())
    }

    var counts [5]int
    randomGen.seed(987654321)
    for i := 0; i < 1e5; i++ {
        j := int(math.Floor(randomGen.nextFloat() * 5))
        counts[j]++
    }
    fmt.Println("\nThe counts for 100,000 repetitions are:")
    for i := 0; i < 5; i++ {
        fmt.Printf("  %d : %d\n", i, counts[i])
    }
}


middle_square = cluster is seed, next
    rep = null
    own state: int

    seed = proc (s: int)
        state := s
    end seed

    next = proc () returns (int)
        state := (state ** 2) / 1000 // 1000000
        return(state)
    end next
end middle_square

start_up = proc ()
    po: stream := stream$primary_output()
    middle_square$seed(675248)
    for i: int in int$from_to(1, 5) do
        stream$putl(po, int$unparse(middle_square$next()))
    end
end start_up


       IDENTIFICATION DIVISION.
       PROGRAM-ID. MIDDLE-SQUARE.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 STATE.
          03 SEED         PIC 9(6) VALUE 675248.
          03 SQUARE       PIC 9(12).
          03 FILLER       REDEFINES SQUARE.
             05 FILLER    PIC 9(3).
             05 NEXT-SEED PIC 9(6).
             05 FILLER    PIC 9(3).

       PROCEDURE DIVISION.
       BEGIN.
           PERFORM SHOW-NUM 5 TIMES.
           STOP RUN.

       SHOW-NUM.
           PERFORM MAKE-RANDOM.
           DISPLAY SEED.

       MAKE-RANDOM.
           MULTIPLY SEED BY SEED GIVING SQUARE.
           MOVE NEXT-SEED TO SEED.


// Pseudo-random numbers/Middle-square method. Nigel Galloway: January 5th., 2022
Seq.unfold(fun n->let n=n*n%1000000000L/1000L in Some(n,n)) 675248L|>Seq.take 5|>Seq.iter(printfn "%d")


USING: kernel math namespaces prettyprint ;

SYMBOL: seed
675248 seed set-global

: rand ( -- n ) seed get sq 1000 /i 1000000 mod dup seed set ;

5 [ rand . ] times


: next-random dup * 1000 / 1000000 mod ;
: 5-random-num 5 0 do next-random dup . loop ;
675248 5-random-num


Dim Shared seed As Integer = 675248
Dim i As Integer
Declare Function Rand As Integer
For i = 1 To 5
	Print Rand
Next i
Sleep

Function Rand As Integer
	Dim s As String
	s = Str(seed ^ 2)
	Do While Len(s) <> 12
		s = "0" + s
	Loop
	seed = Val(Mid(s, 4, 6))
	Rand = seed
End Function


import Data.List

randoms :: Int -> [Int]
randoms seed = unfoldr go ([seed,0,0],[seed,0,0])
  where
    go (x1,x2) =
      let x1i = sum (zipWith (*) x1 a1) `mod` m1
          x2i = sum (zipWith (*) x2 a2) `mod` m2
      in Just $ ((x1i - x2i) `mod` m1, (x1i:init x1, x2i:init x2))

    a1 = [0, 1403580, -810728]
    m1 = 2^32 - 209
    a2 = [527612, 0, -1370589]
    m2 = 2^32 - 22853

randomsFloat = map ((/ (2^32 - 208)) . fromIntegral) . randoms


public class App {
    private static long mod(long x, long y) {
        long m = x % y;
        if (m < 0) {
            if (y < 0) {
                return m - y;
            } else {
                return m + y;
            }
        }
        return m;
    }

    public static class RNG {
        // first generator
        private final long[] a1 = {0, 1403580, -810728};
        private static final long m1 = (1L << 32) - 209;
        private long[] x1;
        // second generator
        private final long[] a2 = {527612, 0, -1370589};
        private static final long m2 = (1L << 32) - 22853;
        private long[] x2;
        // other
        private static final long d = m1 + 1;

        public void seed(long state) {
            x1 = new long[]{state, 0, 0};
            x2 = new long[]{state, 0, 0};
        }

        public long nextInt() {
            long x1i = mod(a1[0] * x1[0] + a1[1] * x1[1] + a1[2] * x1[2], m1);
            long x2i = mod(a2[0] * x2[0] + a2[1] * x2[1] + a2[2] * x2[2], m2);
            long z = mod(x1i - x2i, m1);

            // keep the last three values of the first generator
            x1 = new long[]{x1i, x1[0], x1[1]};
            // keep the last three values of the second generator
            x2 = new long[]{x2i, x2[0], x2[1]};

            return z + 1;
        }

        public double nextFloat() {
            return 1.0 * nextInt() / d;
        }
    }

    public static void main(String[] args) {
        RNG rng = new RNG();

        rng.seed(1234567);
        System.out.println(rng.nextInt());
        System.out.println(rng.nextInt());
        System.out.println(rng.nextInt());
        System.out.println(rng.nextInt());
        System.out.println(rng.nextInt());
        System.out.println();

        int[] counts = {0, 0, 0, 0, 0};
        rng.seed(987654321);
        for (int i = 0; i < 100_000; i++) {
            int value = (int) Math.floor(rng.nextFloat() * 5.0);
            counts[value]++;
        }
        for (int i = 0; i < counts.length; i++) {
            System.out.printf("%d: %d%n", i, counts[i]);
        }
    }
}


package main

import "fmt"

func random(seed int) int {
    return seed * seed / 1e3 % 1e6
}

func main() {
    seed := 675248
    for i := 1; i <= 5; i++ {
        seed = random(seed)
        fmt.Println(seed)
    }
}


findPseudoRandom :: Int -> Int
findPseudoRandom seed =
   let square = seed * seed
       squarestr = show square
       enlarged = replicate ( 12 - length squarestr ) '0' ++ squarestr
   in read $ take 6 $ drop 3 enlarged

solution :: [Int]
solution = tail $ take 6 $ iterate findPseudoRandom 675248


# Input: a positive integer
# Output: the "middle-square"
def middle_square:
  (tostring|length) as $len
  | (. * .)
  | tostring
  | (3*length/4|ceil) as $n
  | .[ -$n : $len-$n]
  | if length == 0 then 0 else tonumber end;

# Input: a positive integer
# Output: middle_square, applied recursively
def middle_squares:
  middle_square | ., middle_squares;

limit(5; 675248 | middle_squares)


const seed = [675248]

function random()
    s = string(seed[] * seed[], pad=12) # turn a number into string, pad to 12 digits
    seed[] = parse(Int, s[begin+3:end-3]) # take middle of number string, parse to Int
    return seed[]
end

# Middle-square method use

for i = 1:5
    println(random())
end


proc rand:int =
  var seed {.global.} = 675248
  seed = int(seed*seed) div 1000 mod 1000000
  return seed

for _ in 1..5: echo rand()


#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Pseudo-random_numbers/Middle-square_method
use warnings;

sub msq
  {
  use feature qw( state );
  state $seed = 675248;
  $seed = sprintf "%06d", $seed ** 2 / 1000 % 1e6;
  }

print msq, "\n" for 1 .. 5;


import kotlin.math.floor

fun mod(x: Long, y: Long): Long {
    val m = x % y
    return if (m < 0) {
        if (y < 0) {
            m - y
        } else {
            m + y
        }
    } else m
}

class RNG {
    // first generator
    private val a1 = arrayOf(0L, 1403580L, -810728L)
    private val m1 = (1L shl 32) - 209
    private var x1 = arrayOf(0L, 0L, 0L)

    // second generator
    private val a2 = arrayOf(527612L, 0L, -1370589L)
    private val m2 = (1L shl 32) - 22853
    private var x2 = arrayOf(0L, 0L, 0L)

    private val d = m1 + 1

    fun seed(state: Long) {
        x1 = arrayOf(state, 0, 0)
        x2 = arrayOf(state, 0, 0)
    }

    fun nextInt(): Long {
        val x1i = mod(a1[0] * x1[0] + a1[1] * x1[1] + a1[2] * x1[2], m1)
        val x2i = mod(a2[0] * x2[0] + a2[1] * x2[1] + a2[2] * x2[2], m2)
        val z = mod(x1i - x2i, m1)

        // keep last three values of the first generator
        x1 = arrayOf(x1i, x1[0], x1[1])
        // keep last three values of the second generator
        x2 = arrayOf(x2i, x2[0], x2[1])

        return z + 1
    }

    fun nextFloat(): Double {
        return nextInt().toDouble() / d
    }
}

fun main() {
    val rng = RNG()

    rng.seed(1234567)
    println(rng.nextInt())
    println(rng.nextInt())
    println(rng.nextInt())
    println(rng.nextInt())
    println(rng.nextInt())
    println()

    val counts = IntArray(5)
    rng.seed(987654321)
    for (i in 0 until 100_000) {
        val v = floor((rng.nextFloat() * 5.0)).toInt()
        counts[v]++
    }
    for (iv in counts.withIndex()) {
        println("${iv.index}: ${iv.value}")
    }
}


with javascript_semantics
integer seed = 675248
function random()
    seed = remainder(floor(seed*seed/1000),1e6)
--  seed = to_integer(sprintf("%012d",seed*seed)[4..9])
    return seed
end function
for i=1 to 5 do
    ?random()
end for


Procedure.i MSRandom()
  Static.i seed=675248
  seed = (seed*seed/1000)%1000000
  ProcedureReturn seed
EndProcedure

If OpenConsole()
  For i=1 To 5 : PrintN(Str(i)+": "+Str(MSRandom())) : Next
  Input()
EndIf


seed = 675248
def random():
    global seed
    s = str(seed ** 2)
    while len(s) != 12:
        s = "0" + s
    seed = int(s[3:9])
    return seed
for i in range(0,5):
    print(random())


sub msq {
    state $seed = 675248;
    $seed = $seed² div 1000 mod 1000000;
}

say msq() xx 5;


Red[]
seed: 675248
rand: does [seed: to-integer (seed * 1.0 * seed / 1000) % 1000000]  ; multiply by 1.0 to avoid integer overflow (32-bit)
loop 5 [print rand]


import algorithm, math, sequtils, strutils, tables

const
  # First generator.
  a1 = [int64 0, 1403580, -810728]
  m1: int64 = 2^32 - 209
  # Second generator.
  a2 = [int64 527612, 0, -1370589]
  m2: int64 = 2^32 - 22853

  d = m1 + 1

type MRG32k3a = object
  x1: array[3, int64]   # List of three last values of gen #1.
  x2: array[3, int64]   # List of three last values of gen #2.

func seed(gen: var MRG32k3a; seedState: int64) =
  assert seedState in 1..<d
  gen.x1 = [seedState, 0, 0]
  gen.x2 = [seedState, 0, 0]

func nextInt(gen: var MRG32k3a): int64 =
  let x1i = floormod(a1[0] * gen.x1[0] + a1[1] * gen.x1[1] + a1[2] * gen.x1[2], m1)
  let x2i = floormod(a2[0] * gen.x2[0] + a2[1] * gen.x2[1] + a2[2] * gen.x2[2], m2)
  # In version 1.4, the following two lines doesn't work.
  # gen.x1 = [x1i, gen.x1[0], gen.x1[1]]    # Keep last three.
  # gen.x2 = [x2i, gen.x2[0], gen.x2[1]]    # Keep last three.
  gen.x1[2] = gen.x1[1]; gen.x1[1] = gen.x1[0]; gen.x1[0] = x1i
  gen.x2[2] = gen.x2[1]; gen.x2[1] = gen.x2[0]; gen.x2[0] = x2i
  result = floormod(x1i - x2i, m1) + 1

func nextFloat(gen: var MRG32k3a): float =
  gen.nextInt().float / d.float

when isMainModule:
  var gen: MRG32k3a

  gen.seed(1234567)
  for _ in 1..5:
    echo gen.nextInt()

  echo ""
  gen.seed(987654321)
  var counts: CountTable[int]
  for _ in 1..100_000:
    counts.inc int(gen.nextFloat() * 5)
  echo sorted(toSeq(counts.pairs)).mapIt($it[0] & ": " & $it[1]).join(", ")


def middle_square (seed)
  return to_enum(__method__, seed) unless block_given?
  s = seed.digits.size
  loop { yield seed = (seed*seed).to_s.rjust(s*2, "0")[s/2, s].to_i }
end

puts middle_square(675248).take(5)


class MiddleSquareMethod(seed, k = 1000) {
    method next {
        seed = (seed**2 // k % k**2)
    }
}

var obj = MiddleSquareMethod(675248)
say 5.of { obj.next }


If Info("wordsize") < 64 Then Print "This needs a 64-bit uBasic" : End

s = 675248
For i = 1 To 5
  Print Set(s, FUNC(_random(s)))
Next

End

_random Param (1) : Return ([email protected]*[email protected]/1000%1000000)


seed=675248
random(){
        seed=`expr $seed \* $seed / 1000 % 1000000`
        return seed
}
for ((i=1;i<=5;i++));
do
        random
        echo $?
done


Option Explicit
Dim seed As Long
Sub Main()
    Dim i As Integer
    seed = 675248
    For i = 1 To 5
        Debug.Print Rand
    Next i
End Sub
Function Rand() As Variant
    Dim s As String
    s = CStr(seed ^ 2)
    Do While Len(s) <> 12
        s = "0" + s
    Loop
    seed = Val(Mid(s, 4, 6))
    Rand = seed
End Function


with javascript_semantics
constant
    -- First generator
    a1 = {0, 1403580, -810728},
    m1 = power(2,32) - 209,
    -- Second Generator
    a2 = {527612, 0, -1370589},
    m2 = power(2,32) - 22853,
     d = m1 + 1

sequence x1 = {0, 0, 0},  /* list of three last values of gen #1 */
         x2 = {0, 0, 0}   /* list of three last values of gen #2 */

procedure seed(integer seed_state)
    assert(seed_state>0 and seed_state<d)
    x1 = {seed_state, 0, 0}
    x2 = {seed_state, 0, 0}
end procedure

function next_int()
    atom x1i = mod(a1[1]*x1[1] + a1[2]*x1[2] + a1[3]*x1[3],m1),
         x2i = mod(a2[1]*x2[1] + a2[2]*x2[2] + a2[3]*x2[3],m2)
    x1 = {x1i, x1[1], x1[2]}    /* Keep last three */
    x2 = {x2i, x2[1], x2[2]}    /* Keep last three */
    atom z = mod(x1i-x2i,m1),
    answer = (z + 1)
    return answer
end function

function next_float()
    return next_int() / d
end function

seed(1234567)
for i=1 to 5 do
    printf(1,"%d\n",next_int())
end for
seed(987654321)
sequence r = repeat(0,5)
for i=1 to 100_000 do
    integer rdx = floor(next_float()*5)+1
    r[rdx] += 1
end for
?r


var random = Fn.new { |seed| ((seed * seed)/1e3).floor % 1e6 }

var seed = 675248
for (i in 1..5) System.print(seed = random.call(seed))


real Seed;
func Random;
[Seed:= Floor(Mod(Seed*Seed/1e3, 1e6));
return fix(Seed);
];

int N;
[Seed:= 675248.;
for N:= 1 to 5 do
    [IntOut(0, Random);  ChOut(0, ^ )];
]


# Constants
a1 = [0, 1403580, -810728]
m1 = 2**32 - 209
#
a2 = [527612, 0, -1370589]
m2 = 2**32 - 22853
#
d = m1 + 1

class MRG32k3a():

    def __init__(self, seed_state=123):
        self.seed(seed_state)

    def seed(self, seed_state):
        assert 0 <seed_state < d, f"Out of Range 0 x < {d}"
        self.x1 = [seed_state, 0, 0]
        self.x2 = [seed_state, 0, 0]

    def next_int(self):
        "return random int in range 0..d"
        x1i = sum(aa * xx  for aa, xx in zip(a1, self.x1)) % m1
        x2i = sum(aa * xx  for aa, xx in zip(a2, self.x2)) % m2
        self.x1 = [x1i] + self.x1[:2]
        self.x2 = [x2i] + self.x2[:2]

        z = (x1i - x2i) % m1
        answer = (z + 1)

        return answer

    def  next_float(self):
        "return random float between 0 and 1"
        return self.next_int() / d

if __name__ == '__main__':
    random_gen = MRG32k3a()
    random_gen.seed(1234567)
    for i in range(5):
        print(random_gen.next_int())

    random_gen.seed(987654321)
    hist = {i:0 for i in range(5)}
    for i in range(100_000):
        hist[int(random_gen.next_float() *5)] += 1
    print(hist)


class MRG32k3a {
    has @!x1;
    has @!x2;

    constant a1 = 0, 1403580, -810728;
    constant a2 = 527612, 0, -1370589;
    constant m1 = 2**32 - 209;
    constant m2 = 2**32 - 22853;

    submethod BUILD ( Int :$seed where 0 < * <= m1 = 1 ) { @!x1 = @!x2 = $seed, 0, 0 }

    method next-int {
        @!x1.unshift: (a1[0] * @!x1[0] + a1[1] * @!x1[1] + a1[2] * @!x1[2]) % m1; @!x1.pop;
        @!x2.unshift: (a2[0] * @!x2[0] + a2[1] * @!x2[1] + a2[2] * @!x2[2]) % m2; @!x2.pop;
        (@!x1[0] - @!x2[0]) % (m1 + 1)
    }

    method next-rat { self.next-int / (m1 + 1) }
}

# Test next-int with custom seed
say 'Seed: 1234567; first five Int values:';
my $rng = MRG32k3a.new :seed(1234567);
.say for $rng.next-int xx 5;

# Test next-rat (since these are rational numbers by default)
say "\nSeed: 987654321; first 1e5 Rat values histogram:";
$rng = MRG32k3a.new :seed(987654321);
say ( ($rng.next-rat * 5).floor xx 100_000 ).Bag;

# Test next-int with default seed
say "\nSeed: default; first five Int values:";
$rng = MRG32k3a.new;
.say for $rng.next-int xx 5;


def mod(x, y)
    m = x % y
    if m < 0 then
        if y < 0 then
            return m - y
        else
            return m + y
        end
    end
    return m
end

# Constants
# First generator
A1 = [0, 1403580, -810728]
A1.freeze
M1 = (1 << 32) - 209
# Second generator
A2 = [527612, 0, -1370589]
A2.freeze
M2 = (1 << 32) - 22853

D = M1 + 1

# the last three values of the first generator
$x1 = [0, 0, 0]
# the last three values of the second generator
$x2 = [0, 0, 0]

def seed(seed_state)
    $x1 = [seed_state, 0, 0]
    $x2 = [seed_state, 0, 0]
end

def next_int()
    x1i = mod((A1[0] * $x1[0] + A1[1] * $x1[1] + A1[2] * $x1[2]), M1)
    x2i = mod((A2[0] * $x2[0] + A2[1] * $x2[1] + A2[2] * $x2[2]), M2)
    z = mod(x1i - x2i, M1)

    $x1 = [x1i, $x1[0], $x1[1]]
    $x2 = [x2i, $x2[0], $x2[1]]

    return z + 1
end

def next_float()
    return 1.0 * next_int() / D
end

########################################

seed(1234567)
print next_int(), "\n"
print next_int(), "\n"
print next_int(), "\n"
print next_int(), "\n"
print next_int(), "\n"
print "\n"

counts = [0, 0, 0, 0, 0]
seed(987654321)
for i in 1 .. 100000
    value = (next_float() * 5.0).floor
    counts[value] = counts[value] + 1
end
counts.each_with_index { |v,i|
    print i, ": ", v, "\n"
}


class MRG32k3a(seed) {

    define(
        m1 = (2**32 - 209)
        m2 = (2**32 - 22853)
    )

    define(
        a1 = %n<     0 1403580  -810728>
        a2 = %n<527612       0 -1370589>
    )

    has x1 = [seed, 0, 0]
    has x2 = x1.clone

    method next_int {
        x1.unshift(a1.map_kv {|k,v| v * x1[k] }.sum % m1); x1.pop
        x2.unshift(a2.map_kv {|k,v| v * x2[k] }.sum % m2); x2.pop
        (x1[0] - x2[0]) % (m1 + 1)
    }

    method next_float { self.next_int / (m1 + 1) -> float }
}

say "Seed: 1234567, first 5 values:"
var rng = MRG32k3a(seed: 1234567)
5.of { rng.next_int }.each { .say }

say "\nSeed: 987654321, values histogram:";
var rng = MRG32k3a(seed: 987654321)
var freq = 100_000.of { rng.next_float * 5 -> int }.freq
freq.sort.each_2d {|k,v| say "#{k} #{v}" }


@(0) = 0                               ' First generator
@(1) = 1403580
@(2) = -810728
m = SHL(1, 32) - 209

@(3) = 527612                          ' Second generator
@(4) = 0
@(5) = -1370589
n = SHL(1, 32) - 22853

d = SHL(1, 32) - 209 + 1               ' m + 1

Proc  _Seed(1234567)
Print FUNC(_NextInt)
Print FUNC(_NextInt)
Print FUNC(_NextInt)
Print FUNC(_NextInt)
Print FUNC(_NextInt)
Print
End

_Mod Param(2)
  Local(1)
  [email protected] = [email protected] % [email protected]
  If [email protected] < 0 Then
     If [email protected] < 0 Then
       Return ([email protected]@)
     Else
       Return ([email protected][email protected])
     Endif
  EndIf
Return ([email protected])

_Seed Param(1)                         ' seed the PRNG
  @(6) = [email protected]
  @(7) = 0
  @(8) = 0

  @(9) = [email protected]
  @(10) = 0
  @(11) = 0
Return

_NextInt                               ' get the next random integer value
  Local(3)

  [email protected] = FUNC(_Mod((@(0) * @(6) + @(1) *  @(7) + @(2) *  @(8)), m))
  [email protected] = FUNC(_Mod((@(3) * @(9) + @(4) * @(10) + @(5) * @(11)), n))
  [email protected] = FUNC(_Mod([email protected] - [email protected], m))

  ' keep last three values of the first generator
  @(8) = @(7)
  @(7) = @(6)
  @(6) = [email protected]

  ' keep last three values of the second generator
  @(11) = @(10)
  @(10) = @(9)
  @(9) = [email protected]

Return ([email protected] + 1)


// constants
var A1 = [0, 1403580, -810728]
var M1 = 2.pow(32) - 209
var A2 = [527612, 0, -1370589]
var M2 = 2.pow(32) - 22853
var D = M1 + 1

// Python style modulus
var Mod = Fn.new { |x, y|
    var m = x % y
    return (m < 0) ?  m + y.abs : m
}

class MRG32k3a {
    construct new() {
        _x1 = [0, 0, 0]
        _x2 = [0, 0, 0]
    }

    seed(seedState) {
        if (seedState <= 0 || seedState >= D) {
            Fiber.abort("Argument must be in the range [0, %(D)].")
        }
        _x1 = [seedState, 0, 0]
        _x2 = [seedState, 0, 0]
    }

    nextInt {
        var x1i = Mod.call(A1[0]*_x1[0] + A1[1]*_x1[1] + A1[2]*_x1[2], M1)
        var x2i = Mod.call(A2[0]*_x2[0] + A2[1]*_x2[1] + A2[2]*_x2[2], M2)
        _x1 = [x1i, _x1[0], _x1[1]]    /* keep last three */
        _x2 = [x2i, _x2[0], _x2[1]]    /* keep last three */
        return Mod.call(x1i - x2i, M1) + 1
    }

    nextFloat { nextInt / D }
}

var randomGen = MRG32k3a.new()
randomGen.seed(1234567)
for (i in 0..4) System.print(randomGen.nextInt)

var counts = List.filled(5, 0)
randomGen.seed(987654321)
for (i in 1..1e5) {
    var i = (randomGen.nextFloat * 5).floor
    counts[i] = counts[i] + 1
}
System.print("\nThe counts for 100,000 repetitions are:")
for (i in 0..4) System.print("  %(i) : %(counts[i])")


T PCG32
   UInt64 state, inc

   F next_int()
      V old = .state
      .state = (old * 6364136223846793005) + .inc
      V shifted = UInt32(((old >> 18) (+) old) >> 27)
      V rot = UInt32(old >> 59)
      R (shifted >> rot) [|] (shifted << (((-)rot + 1) [&] 31))

   F seed(UInt64 seed_state, seed_sequence)
      .state = 0
      .inc = (seed_sequence << 1) [|] 1
      .next_int()
      .state += seed_state
      .next_int()

   F next_float()
      R Float(.next_int()) / (UInt64(1) << 32)

V random_gen = PCG32()
random_gen.seed(42, 54)
L 5
   print(random_gen.next_int())

random_gen.seed(987654321, 1)
V hist = Dict(0.<5, i -> (i, 0))
L 100'000
   hist[Int(random_gen.next_float() * 5)]++
print(hist)


with Interfaces; use Interfaces;

package random_pcg32 is
   function Next_Int return Unsigned_32;
   function Next_Float return Long_Float;
   procedure Seed (seed_state : Unsigned_64; seed_sequence : Unsigned_64);
end random_pcg32;


BEGIN # generate some pseudo random numbers using PCG32 #
    # note that although LONG INT is 64 bits in Algol 68G, LONG BITS is longer than 64 bits #
    LONG BITS state     :=     LONG 16r853c49e6748fea9b;
    LONG INT  inc       := ABS LONG 16rda3e39cb94b95bdb;
    LONG BITS mask 64    =     LONG 16rffffffffffffffff;
    LONG BITS mask 32    =     LONG 16rffffffff;
    LONG BITS mask 31    =     LONG 16r7fffffff;
    LONG INT  one shl 32 = ABS ( LONG 16r1 SHL 32 );
    # XOR and assign convenience operator #
    PRIO XORAB = 1;
    OP   XORAB = ( REF LONG BITS x, LONG BITS v )REF LONG BITS: x := ( x XOR v ) AND mask 64;
    # initialises the state to the specified seed #
    PROC seed = ( LONG INT seed state, seed sequence )VOID:
         BEGIN
            state := 16r0;
            inc   := ABS ( ( ( BIN seed sequence SHL 1 ) OR 16r1 ) AND mask 64 );
            next int;
            state := SHORTEN ( BIN ( ABS state + seed state ) AND mask 64 );
            next int
         END # seed # ;
    # gets the next pseudo random integer #
    PROC next int = LONG INT:
         BEGIN
            LONG BITS old     = state;
            LONG INT const    = LONG 6364136223846793005;
            state            := SHORTEN ( mask 64 AND BIN ( ( ABS old * LENG const ) + inc ) );
            LONG BITS x      := old;
            x XORAB ( old SHR 18 );
            BITS  xor shifted = SHORTEN ( mask 32 AND ( x SHR 27 ) );
            INT   rot         = SHORTEN ABS ( mask 32 AND ( old SHR 59 ) );
            INT   rot 2       = IF rot = 0 THEN 0 ELSE 32 - rot FI;
            BITS  xor shr    := SHORTEN ( mask 32 AND LENG ( xor shifted SHR rot ) );
            BITS  xor shl    := xor shifted;
            TO rot 2 DO
                xor shl      := SHORTEN ( ( mask 31 AND LENG xor shl ) SHL 1 )
            OD;
            ABS ( LENG xor shr OR LENG xor shl )
         END # next int # ;
    # gets the next pseudo random real #
    PROC next float = LONG REAL: next int / one shl 32;
    BEGIN # task test cases #
        seed( 42, 54 );
        print( ( whole( next int, 0 ), newline ) ); # 2707161783 #
        print( ( whole( next int, 0 ), newline ) ); # 2068313097 #
        print( ( whole( next int, 0 ), newline ) ); # 3122475824 #
        print( ( whole( next int, 0 ), newline ) ); # 2211639955 #
        print( ( whole( next int, 0 ), newline ) ); # 3215226955 #
        # count the number of occurances of 0..4 in a sequence of pseudo random reals scaled to be in [0..5) #
        seed( 987654321, 1 );
        [ 0 : 4 ]INT counts; FOR i FROM LWB counts TO UPB counts DO counts[ i ] := 0 OD;
        TO 100 000 DO counts[ SHORTEN ENTIER ( next float * 5 ) ] +:= 1 OD;
        FOR i FROM LWB counts TO UPB counts DO
            print( ( whole( i, -2 ), ": ", whole( counts[ i ], -6 ) ) )
        OD;
        print( ( newline ) )
    END
END


#include <math.h>
#include <stdint.h>
#include <stdio.h>

const uint64_t N = 6364136223846793005;

static uint64_t state = 0x853c49e6748fea9b;
static uint64_t inc = 0xda3e39cb94b95bdb;

uint32_t pcg32_int() {
    uint64_t old = state;
    state = old * N + inc;
    uint32_t shifted = (uint32_t)(((old >> 18) ^ old) >> 27);
    uint32_t rot = old >> 59;
    return (shifted >> rot) | (shifted << ((~rot + 1) & 31));
}

double pcg32_float() {
    return ((double)pcg32_int()) / (1LL << 32);
}

void pcg32_seed(uint64_t seed_state, uint64_t seed_sequence) {
    state = 0;
    inc = (seed_sequence << 1) | 1;
    pcg32_int();
    state = state + seed_state;
    pcg32_int();
}

int main() {
    int counts[5] = { 0, 0, 0, 0, 0 };
    int i;

    pcg32_seed(42, 54);
    printf("%u\n", pcg32_int());
    printf("%u\n", pcg32_int());
    printf("%u\n", pcg32_int());
    printf("%u\n", pcg32_int());
    printf("%u\n", pcg32_int());
    printf("\n");

    pcg32_seed(987654321, 1);
    for (i = 0; i < 100000; i++) {
        int j = (int)floor(pcg32_float() * 5.0);
        counts[j]++;
    }

    printf("The counts for 100,000 repetitions are:\n");
    for (i = 0; i < 5; i++) {
        printf("  %d : %d\n", i, counts[i]);
    }

    return 0;
}


#include <array>
#include <iostream>

class PCG32 {
private:
    const uint64_t N = 6364136223846793005;
    uint64_t state = 0x853c49e6748fea9b;
    uint64_t inc = 0xda3e39cb94b95bdb;
public:
    uint32_t nextInt() {
        uint64_t old = state;
        state = old * N + inc;
        uint32_t shifted = (uint32_t)(((old >> 18) ^ old) >> 27);
        uint32_t rot = old >> 59;
        return (shifted >> rot) | (shifted << ((~rot + 1) & 31));
    }

    double nextFloat() {
        return ((double)nextInt()) / (1LL << 32);
    }

    void seed(uint64_t seed_state, uint64_t seed_sequence) {
        state = 0;
        inc = (seed_sequence << 1) | 1;
        nextInt();
        state = state + seed_state;
        nextInt();
    }
};

int main() {
    auto r = new PCG32();

    r->seed(42, 54);
    std::cout << r->nextInt() << '\n';
    std::cout << r->nextInt() << '\n';
    std::cout << r->nextInt() << '\n';
    std::cout << r->nextInt() << '\n';
    std::cout << r->nextInt() << '\n';
    std::cout << '\n';

    std::array<int, 5> counts{ 0, 0, 0, 0, 0 };
    r->seed(987654321, 1);
    for (size_t i = 0; i < 100000; i++) {
        int j = (int)floor(r->nextFloat() * 5.0);
        counts[j]++;
    }

    std::cout << "The counts for 100,000 repetitions are:\n";
    for (size_t i = 0; i < counts.size(); i++) {
        std::cout << "  " << i << " : " << counts[i] << '\n';
    }

    return 0;
}


Int64 nTriples, nPrimitives, limit

F countTriples(Int64 =x, =y, =z)
   L
      V p = x + y + z
      I p > :limit
         R

      :nPrimitives++
      :nTriples += :limit I/ p

      V t0 = x - 2 * y + 2 * z
      V t1 = 2 * x - y + 2 * z
      V t2 = t1 - y + z
      countTriples(t0, t1, t2)

      t0 += 4 * y
      t1 += 2 * y
      t2 += 4 * y
      countTriples(t0, t1, t2)

      z = t2 - 4 * x
      y = t1 - 4 * x
      x = t0 - 2 * x

L(p) 1..8
   limit = Int64(10) ^ p
   nTriples = nPrimitives = 0
   countTriples(3, 4, 5)
   print(‘Up to #11: #11 triples, #9 primitives.’.format(limit, nTriples, nPrimitives))


import std.math;
import std.stdio;

struct PCG32 {
private:
    immutable ulong N = 6364136223846793005;
    ulong state = 0x853c49e6748fea9b;
    ulong inc = 0xda3e39cb94b95bdb;

public:
    void seed(ulong seed_state, ulong seed_sequence) {
        state = 0;
        inc = (seed_sequence << 1) | 1;
        nextInt();
        state = state + seed_state;
        nextInt();
    }

    uint nextInt() {
        ulong old = state;
        state = old * N + inc;
        uint shifted = cast(uint)(((old >> 18) ^ old) >> 27);
        uint rot = old >> 59;
        return (shifted >> rot) | (shifted << ((~rot + 1) & 31));
    }

    double nextFloat() {
        return (cast(double) nextInt()) / (1L << 32);
    }
}

void main() {
    auto r = PCG32();

    r.seed(42, 54);
    writeln(r.nextInt());
    writeln(r.nextInt());
    writeln(r.nextInt());
    writeln(r.nextInt());
    writeln(r.nextInt());
    writeln;

    auto counts = [0, 0, 0, 0, 0];
    r.seed(987654321, 1);
    foreach (_; 0..100_000) {
        int j = cast(int)floor(r.nextFloat() * 5.0);
        counts[j]++;
    }

    writeln("The counts for 100,000 repetitions are:");
    foreach (i,v; counts) {
        writeln("  ", i, " : ", v);
    }
}


*        Pythagorean triples -     12/06/2018
PYTHTRI  CSECT
         USING  PYTHTRI,R13        base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         SAVE   (14,12)            save previous context
         ST     R13,4(R15)         link backward
         ST     R15,8(R13)         link forward
         LR     R13,R15            set addressability
         MVC    PMAX,=F'1'         pmax=1
         LA     R6,1               i=1
       DO WHILE=(C,R6,LE,=F'6')    do i=1 to 6
         L      R5,PMAX              pmax
         MH     R5,=H'10'            *10
         ST     R5,PMAX              pmax=pmax*10
         MVC    PRIM,=F'0'           prim=0
         MVC    COUNT,=F'0'          count=0
         L      R1,PMAX              pmax
         BAL    R14,ISQRT            isqrt(pmax)
         SRA    R0,1                 /2
         ST     R0,NMAX              nmax=isqrt(pmax)/2
         LA     R7,1                 n=1
       DO WHILE=(C,R7,LE,NMAX)       do n=1 to nmax
         LA     R9,1(R7)               m=n+1
         LR     R5,R9                  m
         AR     R5,R7                  +n
         MR     R4,R9                  *m
         SLA    R5,1                   *2
         LR     R8,R5                  p=2*m*(m+n)
       DO WHILE=(C,R8,LE,PMAX)         do while p<=pmax
         LR     R1,R9                    m
         LR     R2,R7                    n
         BAL    R14,GCD                  gcd(m,n)
       IF C,R0,EQ,=F'1' THEN             if gcd(m,n)=1 then
         L      R2,PRIM                    prim
         LA     R2,1(R2)                   +1
         ST     R2,PRIM                    prim=prim+1
         L      R4,PMAX                    pmax
         SRDA   R4,32                      ~
         DR     R4,R8                      /p
         A      R5,COUNT                   +count
         ST     R5,COUNT                   count=count+pmax/p
       ENDIF    ,                        endif
         LA     R9,2(R9)                 m=m+2
         LR     R5,R9                    m
         AR     R5,R7                    +n
         MR     R4,R9                    *m
         SLA    R5,1                     *2
         LR     R8,R5                    p=2*m*(m+n)
       ENDDO    ,                      enddo n
         LA     R7,1(R7)               n++
       ENDDO    ,                    enddo n
         L      R1,PMAX              pmax
         XDECO  R1,XDEC              edit pmax
         MVC    PG+15(9),XDEC+3      output pmax
         L      R1,COUNT             count
         XDECO  R1,XDEC              edit count
         MVC    PG+33(9),XDEC+3      output count
         L      R1,PRIM              prim
         XDECO  R1,XDEC              edit prim
         MVC    PG+55(9),XDEC+3      output prim
         XPRNT  PG,L'PG              print
         LA     R6,1(R6)             i++
       ENDDO    ,                  enddo i
         L      R13,4(0,R13)       restore previous savearea pointer
         RETURN (14,12),RC=0       restore registers from calling sav
NMAX     DS     F                  nmax
PMAX     DS     F                  pmax
COUNT    DS     F                  count
PRIM     DS     F                  prim
PG     DC CL80'Max Perimeter: ........., Total: ........., Primitive:'
XDEC     DS     CL12
GCD      EQU    *  --------------- function gcd(a,b)
         STM    R2,R7,GCDSA        save context
         LR     R3,R1              c=a
         LR     R4,R2              d=b
GCDLOOP  LR     R6,R3              c
         SRDA   R6,32              ~
         DR     R6,R4              /d
         LTR    R6,R6              if c mod d=0
         BZ     GCDELOOP           then leave loop
         LR     R5,R6              e=c mod d
         LR     R3,R4              c=d
         LR     R4,R5              d=e
         B      GCDLOOP            loop
GCDELOOP LR     R0,R4              return(d)
         LM     R2,R7,GCDSA        restore context
         BR     R14                return
GCDSA    DS     6A                 context store
ISQRT    EQU    *  --------------- function isqrt(n)
         STM    R3,R10,ISQRTSA     save context
         LR     R6,R1              n=r1
         LR     R10,R6             sqrtn=n
         SRA    R10,1              sqrtn=n/2
       IF LTR,R10,Z,R10 THEN       if sqrtn=0 then
         LA     R10,1                sqrtn=1
       ELSE     ,                  else
         LA     R9,0                 snm2=0
         LA     R8,0                 snm1=0
         LA     R7,0                 sn=0
         LA     R3,0                 okexit=0
       DO UNTIL=(C,R3,EQ,=A(1))      do until okexit=1
         AR     R10,R7                 sqrtn=sqrtn+sn
         LR     R9,R8                  snm2=snm1
         LR     R8,R7                  snm1=sn
         LR     R4,R6                  n
         SRDA   R4,32                  ~
         DR     R4,R10                 /sqrtn
         SR     R5,R10                 -sqrtn
         SRA    R5,1                   /2
         LR     R7,R5                  sn=(n/sqrtn-sqrtn)/2
       IF C,R7,EQ,=F'0',OR,CR,R7,EQ,R9 THEN  if sn=0 or sn=snm2 then
         LA     R3,1                     okexit=1
       ENDIF    ,                      endif
       ENDDO    ,                    enddo until
       ENDIF    ,                  endif
         LR     R5,R10             sqrtn
         MR     R4,R10             *sqrtn
       IF CR,R5,GT,R6 THEN         if sqrtn*sqrtn>n then
         BCTR   R10,0                sqrtn=sqrtn-1
       ENDIF    ,                  endif
         LR     R0,R10             return(sqrtn)
         LM     R3,R10,ISQRTSA     restore context
         BR     R14                return
ISQRTSA  DS     8A                 context store
         YREGS
         END    PYTHTRI


DEFINE PTR="CARD"
DEFINE ENTRY_SIZE="3"
TYPE TRIPLE=[BYTE a,b,c]
TYPE TRIPLES=[
  PTR buf ;BYTE ARRAY
  BYTE count]

PTR FUNC GetItemAddr(TRIPLES POINTER arr BYTE index)
  PTR addr

  addr=arr.buf+index*ENTRY_SIZE
RETURN (addr)

PROC PrintTriples(TRIPLES POINTER arr)
  INT i
  TRIPLE POINTER t

  FOR i=0 TO arr.count-1
  DO
    t=GetItemAddr(arr,i)
    PrintF("(%B %B %B) ",t.a,t.b,t.c)
  OD
RETURN

PROC Init(TRIPLES POINTER arr BYTE ARRAY b)
  arr.buf=b
  arr.count=0
RETURN

PROC AddItem(TRIPLES POINTER arr TRIPLE POINTER t)
  TRIPLE POINTER p

  p=GetItemAddr(arr,arr.count)
  p.a=t.a
  p.b=t.b
  p.c=t.c
  arr.count==+1
RETURN

PROC FindTriples(TRIPLES POINTER res BYTE limit)
  BYTE ARRAY data(100)
  BYTE half,i,j,k
  TRIPLE t

  Init(res,data)
  half=limit/2
  FOR i=1 TO half
  DO
    FOR j=i TO half
    DO
      FOR k=j TO limit
      DO
        IF i+j+k<limit AND i*i+j*j=k*k THEN
          t.a=i t.b=j t.c=k
          AddItem(res,t)
        FI
      OD
    OD
  OD
RETURN

BYTE FUNC Gcd(BYTE a,b)
  BYTE tmp

  IF a<b THEN
    tmp=a a=b b=tmp
  FI

  WHILE b#0
  DO
    tmp=a MOD b
    a=b b=tmp
  OD
RETURN (a)

BYTE FUNC IsPrimitive(TRIPLE POINTER t)
  IF Gcd(t.a,t.b)>1 THEN RETURN (0) FI
  IF Gcd(t.b,t.c)>1 THEN RETURN (0) FI
  IF Gcd(t.a,t.c)>1 THEN RETURN (0) FI
RETURN (1)

PROC FindPrimitives(TRIPLES POINTER arr,res)
  BYTE ARRAY data(100)
  INT i
  TRIPLE POINTER t

  Init(res,data)
  FOR i=0 TO arr.count-1
  DO
    t=GetItemAddr(arr,i)
    IF IsPrimitive(t) THEN
      AddItem(res,t)
    FI
  OD
RETURN

PROC Main()
  DEFINE LIMIT="100"
  TRIPLES res,res2

  FindTriples(res,LIMIT)
  PrintF("There are %B pythagorean triples with a perimeter less than %B:%E%E",res.count,LIMIT)
  PrintTriples(res)

  FindPrimitives(res,res2)
  PrintF("%E%E%E%B of them are primitive:%E%E",res2.count)
  PrintTriples(res2)
RETURN


program PCG32_test;

{$APPTYPE CONSOLE}
uses
  System.SysUtils,
  Velthuis.BigIntegers,
  System.Generics.Collections;

type
  TPCG32 = class
  public
    FState: BigInteger;
    FInc: BigInteger;
    mask64: BigInteger;
    mask32: BigInteger;
    k: BigInteger;
    constructor Create(seedState, seedSequence: BigInteger); overload;
    constructor Create(); overload;
    destructor Destroy; override;
    procedure Seed(seed_state, seed_sequence: BigInteger);
    function NextInt(): BigInteger;
    function NextIntRange(size: Integer): TArray<BigInteger>;
    function NextFloat(): Extended;
  end;

{ TPCG32 }

constructor TPCG32.Create(seedState, seedSequence: BigInteger);
begin
  Create();
  Seed(seedState, seedSequence);
end;

constructor TPCG32.Create;
begin
  k := '6364136223846793005';
  mask64 := (BigInteger(1) shl 64) - 1;
  mask32 := (BigInteger(1) shl 32) - 1;
  FState := 0;
  FInc := 0;
end;

destructor TPCG32.Destroy;
begin

  inherited;
end;

function TPCG32.NextFloat: Extended;
begin
  Result := (NextInt.AsExtended / (BigInteger(1) shl 32).AsExtended);
end;

function TPCG32.NextInt(): BigInteger;
var
  old, xorshifted, rot, answer: BigInteger;
begin
  old := FState;
  FState := ((old * k) + FInc) and mask64;
  xorshifted := (((old shr 18) xor old) shr 27) and mask32;
  rot := (old shr 59) and mask32;
  answer := (xorshifted shr rot.AsInteger) or (xorshifted shl ((-rot) and
    BigInteger(31)).AsInteger);
  Result := answer and mask32;
end;

function TPCG32.NextIntRange(size: Integer): TArray<BigInteger>;
var
  i: Integer;
begin
  SetLength(Result, size);
  if size = 0 then
    exit;

  for i := 0 to size - 1 do
    Result[i] := NextInt;
end;

procedure TPCG32.Seed(seed_state, seed_sequence: BigInteger);
begin
  FState := 0;
  FInc := ((seed_sequence shl 1) or 1) and mask64;
  nextint();
  Fstate := (Fstate + seed_state);
  nextint();
end;

var
  PCG32: TPCG32;
  i, key: Integer;
  count: TDictionary<Integer, Integer>;

begin
  PCG32 := TPCG32.Create(42, 54);

  for i := 0 to 4 do
    Writeln(PCG32.NextInt().ToString);

  PCG32.seed(987654321, 1);

  count := TDictionary<Integer, Integer>.Create();

  for i := 1 to 100000 do
  begin
    key := Trunc(PCG32.NextFloat * 5);
    if count.ContainsKey(key) then
      count[key] := count[key] + 1
    else
      count.Add(key, 1);
  end;

  Writeln(#10'The counts for 100,000 repetitions are:');

  for key in count.Keys do
    Writeln(key, ' : ', count[key]);

  count.free;
  PCG32.free;
  Readln;
end.


with Ada.Text_IO;

procedure Pythagorean_Triples is

   type Large_Natural is range 0 .. 2**63-1;
     -- this is the maximum for gnat

   procedure New_Triangle(A, B, C: Large_Natural;
                          Max_Perimeter: Large_Natural;
                          Total_Cnt, Primitive_Cnt: in out Large_Natural) is
      Perimeter: constant Large_Natural := A + B + C;
   begin
      if Perimeter <= Max_Perimeter then
         Primitive_Cnt := Primitive_Cnt + 1;
         Total_Cnt     := Total_Cnt + Max_Perimeter / Perimeter;
         New_Triangle(A-2*B+2*C,     2*A-B+2*C,    2*A-2*B+3*C,   Max_Perimeter, Total_Cnt, Primitive_Cnt);
         New_Triangle(A+2*B+2*C,     2*A+B+2*C,    2*A+2*B+3*C,   Max_Perimeter, Total_Cnt, Primitive_Cnt);
         New_Triangle(2*B+2*C-A,     B+2*C-2*A,    2*B+3*C-2*A,   Max_Perimeter, Total_Cnt, Primitive_Cnt);
      end if;
   end New_Triangle;

   T_Cnt, P_Cnt: Large_Natural;

begin
   for I in 1 .. 9 loop
      T_Cnt := 0;
      P_Cnt := 0;
      New_Triangle(3,4,5, 10**I, Total_Cnt => T_Cnt, Primitive_Cnt => P_Cnt);
      Ada.Text_IO.Put_Line("Up to 10 **" & Integer'Image(I) & " :" &
                             Large_Natural'Image(T_Cnt) & " Triples," &
                             Large_Natural'Image(P_Cnt) & " Primitives");
   end loop;
end Pythagorean_Triples;


100 DECLARE EXTERNAL SUB tri
110 !
120 PUBLIC NUMERIC U0(3,3), U1(3,3), U2(3,3), all, prim
130 DIM seed(3)
140 MAT READ U0, U1, U2
150 DATA 1, -2, 2, 2, -1, 2, 2, -2, 3
160 DATA 1, 2, 2, 2, 1, 2, 2, 2, 3
170 DATA -1, 2, 2, -2, 1, 2, -2, 2, 3
180 !
190 MAT READ seed
200 DATA 3, 4, 5
210 FOR power  = 1 TO 7
220    LET all  = 0
230    LET prim  = 0
240    CALL tri(seed, 10^power , all , prim)
250    PRINT "Up to 10^";power,
260    PRINT USING "######### triples ######### primitives":all,prim
270 NEXT power
280 END
290 !
300 EXTERNAL SUB tri(i(), mp, all, prim)
310 DECLARE EXTERNAL FUNCTION SUM
320 DECLARE NUMERIC t(3)
330 !
340 IF SUM(i) > mp THEN EXIT SUB
350 LET prim = prim + 1
360 LET all  = all + INT(mp  / SUM(i))
370 !
380 MAT t = U0 * i
390 CALL tri(t, mp , all , prim)
400 MAT t = U1 * i
410 CALL tri(t, mp , all , prim)
420 MAT t = U2 * i
430 CALL tri(t, mp , all , prim)
440 END SUB
450 !
460 EXTERNAL FUNCTION SUM(a())
470 LET temp = 0
480 FOR i=LBOUND(a) TO UBOUND(a)
490    LET temp = temp + a(i)
500 NEXT i
510 LET SUM = temp
520 END FUNCTION


USING: accessors kernel locals math math.bitwise math.statistics
prettyprint sequences ;

CONSTANT: const 6364136223846793005

TUPLE: pcg32 state inc ;

: <pcg32> ( -- pcg32 )
    0x853c49e6748fea9b 0xda3e39cb94b95bdb pcg32 boa ;

:: next-int ( pcg -- n )
    pcg state>> :> old
    old const * pcg inc>> + 64 bits pcg state<<
    old -18 shift old bitxor -27 shift 32 bits :> shifted
    old -59 shift 32 bits :> r
    shifted r neg shift
    shifted r neg 31 bitand shift bitor 32 bits ;

: next-float ( pcg -- x ) next-int 1 32 shift /f ;

:: seed ( pcg st seq -- )
    0x0 pcg state<<
    seq 0x1 shift 1 bitor 64 bits pcg inc<<
    pcg next-int drop
    pcg state>> st + pcg state<<
    pcg next-int drop ;

! Task
<pcg32> 42 54 [ seed ] keepdd 5 [ dup next-int . ] times

987654321 1 [ seed ] keepdd
100,000 [ dup next-float 5 * >integer ] replicate nip
histogram .


package main

import (
    "fmt"
    "math"
)

const CONST = 6364136223846793005

type Pcg32 struct{ state, inc uint64 }

func Pcg32New() *Pcg32 { return &Pcg32{0x853c49e6748fea9b, 0xda3e39cb94b95bdb} }

func (pcg *Pcg32) seed(seedState, seedSequence uint64) {
    pcg.state = 0
    pcg.inc = (seedSequence << 1) | 1
    pcg.nextInt()
    pcg.state = pcg.state + seedState
    pcg.nextInt()
}

func (pcg *Pcg32) nextInt() uint32 {
    old := pcg.state
    pcg.state = old*CONST + pcg.inc
    pcgshifted := uint32(((old >> 18) ^ old) >> 27)
    rot := uint32(old >> 59)
    return (pcgshifted >> rot) | (pcgshifted << ((-rot) & 31))
}

func (pcg *Pcg32) nextFloat() float64 {
    return float64(pcg.nextInt()) / (1 << 32)
}

func main() {
    randomGen := Pcg32New()
    randomGen.seed(42, 54)
    for i := 0; i < 5; i++ {
        fmt.Println(randomGen.nextInt())
    }

    var counts [5]int
    randomGen.seed(987654321, 1)
    for i := 0; i < 1e5; i++ {
        j := int(math.Floor(randomGen.nextFloat() * 5))
        counts[j]++
    }
    fmt.Println("\nThe counts for 100,000 repetitions are:")
    for i := 0; i < 5; i++ {
        fmt.Printf("  %d : %d\n", i, counts[i])
    }
}


triples: new []
loop 1..50 'x [
    loop 1..50 'y [
        loop (max @[x y])..100 'z [
            if 100 > sum @[x y z] [
                if (z^2) = add x^2 y^2 ->
                    'triples ++ @[sort @[x y z]]
            ]
        ]
    ]
]
unique 'triples

print ["Found" size triples "pythagorean triples with a perimeter no larger than 100:"]
print triples

primitive: select triples => [1 = gcd]

print ""
print [size primitive "of them are primitive:"]
print primitive


⍝ Determine whether given list of integers has GCD = 1
primitive←∧/1=2∨/⊢
⍝ Filter list given as right operand by applying predicate given as left operand
filter←{⍵⌿⍨⍺⍺ ⍵}

⍝ Function pytriples finds all triples given a maximum perimeter
∇res←pytriples maxperimeter;sos;sqrt;cartprod;ascending;ab_max;c_max;a_b_pairs;sos_is_sq;add_c;perimeter_rule
 ⍝ Input parameter maxperimeter is the maximum perimeter
 ⍝ Sum of squares of given list of nrs
 sos←+/(×⍨⊢)
 ⍝ Square root
 sqrt←(÷2)*⍨⊢
 ⍝ (cartesian product) all possible pairs of integers
 ⍝ from 1 to ⍵
 cartprod←{,{⍺∘.,⍵}⍨⍳⍵}
 ⍝ Predicate: are values in given list ascending
 ⍝ Given e.g. pair a, b, c: is a ≤ b ≤ c?
 ascending←∧/2≤/⊢
 ab_max←⌊maxperimeter÷2
 c_max←⌈maxperimeter×sqrt 2
 ⍝ Selects from all a,b combinations (a<abmax, b<abmax)
 ⍝ only those pairs where a ≤ b.
 a_b_pairs←ascending filter¨cartprod(ab_max)
 ⍝ Predicate: is the sum of squares of a and b
 ⍝ itself a square? (does it occur in the squares list)
 sos_is_sq←{{⍵≠1+c_max}(×⍨⍳c_max)⍳sos¨⍵}
 ⍝ Given a pair a,b add corresponding c to form a triple
 add_c←{⍵,sqrt sos ⍵}
 ⍝ Predicate: sum of items less than or equal to max
 perimeter_rule←{maxperimeter≥+/⍵}
 res←perimeter_rule¨filter add_c¨sos_is_sq filter a_b_pairs
∇


import Data.Bits
import Data.Word
import System.Random
import Data.List

data PCGen = PCGen !Word64 !Word64

mkPCGen state sequence =
  let
    n = 6364136223846793005 :: Word64
    inc = (sequence `shiftL` 1) .|. 1 :: Word64
  in PCGen ((inc + state)*n + inc) inc

instance RandomGen PCGen where
   next (PCGen state inc) =
     let
       n = 6364136223846793005 :: Word64
       xs = fromIntegral $ ((state `shiftR` 18) `xor` state) `shiftR` 27 :: Word32
       rot = fromIntegral $ state `shiftR` 59 :: Int
     in (fromIntegral $ (xs `shiftR` rot) .|. (xs `shiftL` ((-rot) .&. 31))
        , PCGen (state * n + inc) inc)

   split _ = error "PCG32 is not splittable"

randoms' :: RandomGen g => g -> [Int]
randoms' g = unfoldr (pure . next) g

toFloat n = fromIntegral n / (2^32 - 1)


public class PCG32 {
    private static final long N = 6364136223846793005L;

    private long state = 0x853c49e6748fea9bL;
    private long inc = 0xda3e39cb94b95bdbL;

    public void seed(long seedState, long seedSequence) {
        state = 0;
        inc = (seedSequence << 1) | 1;
        nextInt();
        state = state + seedState;
        nextInt();
    }

    public int nextInt() {
        long old = state;
        state = old * N + inc;
        int shifted = (int) (((old >>> 18) ^ old) >>> 27);
        int rot = (int) (old >>> 59);
        return (shifted >>> rot) | (shifted << ((~rot + 1) & 31));
    }

    public double nextFloat() {
        var u = Integer.toUnsignedLong(nextInt());
        return (double) u / (1L << 32);
    }

    public static void main(String[] args) {
        var r = new PCG32();

        r.seed(42, 54);
        System.out.println(Integer.toUnsignedString(r.nextInt()));
        System.out.println(Integer.toUnsignedString(r.nextInt()));
        System.out.println(Integer.toUnsignedString(r.nextInt()));
        System.out.println(Integer.toUnsignedString(r.nextInt()));
        System.out.println(Integer.toUnsignedString(r.nextInt()));
        System.out.println();

        int[] counts = {0, 0, 0, 0, 0};
        r.seed(987654321, 1);
        for (int i = 0; i < 100_000; i++) {
            int j = (int) Math.floor(r.nextFloat() * 5.0);
            counts[j]++;
        }

        System.out.println("The counts for 100,000 repetitions are:");
        for (int i = 0; i < counts.length; i++) {
            System.out.printf("  %d : %d\n", i, counts[i]);
        }
    }
}


#NoEnv
SetBatchLines, -1
#SingleInstance, Force

; Greatest common divisor, from http://rosettacode.org/wiki/Greatest_common_divisor#AutoHotkey
gcd(a,b) {
	Return b=0 ? Abs(a) : Gcd(b,mod(a,b))
}

count_triples(max) {
	primitives := 0, triples := 0, m := 2
	while m <= (max / 2)**0.5
	{
		n := mod(m, 2) + 1
		,p := 2*m*(m + n)
		, delta := 4*m
		while n < m and p <= max
			gcd(m, n) = 1
				? (primitives++
				, triples += max // p)
				: ""
			, n += 2
			, p += delta
		m++
	}
	Return primitives " primitives out of " triples " triples"
}

Loop, 8
	Msgbox % 10**A_Index ": " count_triples(10**A_Index)


const mask32, CONST = 0xffffffff, UInt(6364136223846793005)

mutable struct PCG32
    state::UInt64
    inc::UInt64
    PCG32(st=0x853c49e6748fea9b, i=0xda3e39cb94b95bdb) = new(st, i)
end

"""return random 32 bit unsigned int"""
function next_int!(x::PCG32)
    old = x.state
    x.state = (old * CONST) + x.inc
    xorshifted = (((old >> 18) ⊻ old) >> 27) & mask32
    rot = (old >> 59) & mask32
    return ((xorshifted >> rot) | (xorshifted << ((-rot) & 31))) & mask32
end

"""return random float between 0 and 1"""
next_float!(x::PCG32) = next_int!(x) / (1 << 32)

function seed!(x::PCG32, st, seq)
    x.state = 0x0
    x.inc = (UInt(seq) << 0x1) | 1
    next_int!(x)
    x.state = x.state + UInt(st)
    next_int!(x)
end

function testPCG32()
    random_gen = PCG32()
    seed!(random_gen, 42, 54)
    for _ in 1:5
        println(next_int!(random_gen))
    end
    seed!(random_gen, 987654321, 1)
    hist = fill(0, 5)
    for _ in 1:100_000
        hist[Int(floor(next_float!(random_gen) * 5)) + 1] += 1
    end
    println(hist)
    for n in 1:5
        print(n - 1, ": ", hist[n], "  ")
    end
end

testPCG32()


import kotlin.math.floor

class PCG32 {
    private var state = 0x853c49e6748fea9buL
    private var inc = 0xda3e39cb94b95bdbuL

    fun nextInt(): UInt {
        val old = state
        state = old * N + inc
        val shifted = old.shr(18).xor(old).shr(27).toUInt()
        val rot = old.shr(59)
        return (shifted shr rot.toInt()) or shifted.shl((rot.inv() + 1u).and(31u).toInt())
    }

    fun nextFloat(): Double {
        return nextInt().toDouble() / (1L shl 32)
    }

    fun seed(seedState: ULong, seedSequence: ULong) {
        state = 0u
        inc = (seedSequence shl 1).or(1uL)
        nextInt()
        state += seedState
        nextInt()
    }

    companion object {
        private const val N = 6364136223846793005uL
    }
}

fun main() {
    val r = PCG32()

    r.seed(42u, 54u)
    println(r.nextInt())
    println(r.nextInt())
    println(r.nextInt())
    println(r.nextInt())
    println(r.nextInt())
    println()

    val counts = Array(5) { 0 }
    r.seed(987654321u, 1u)
    for (i in 0 until 100000) {
        val j = floor(r.nextFloat() * 5.0).toInt()
        counts[j] += 1
    }

    println("The counts for 100,000 repetitions are:")
    for (iv in counts.withIndex()) {
        println("  %d : %d".format(iv.index, iv.value))
    }
}