Some definitions to help in the explanation

Floor operation

https://en.wikipedia.org/wiki/Floor_and_ceiling_functions

Greatest integer less than or equal to a real number.
Bitwise Logical shift operators (c-inspired)

https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts

Binary bits of value shifted left or right, with zero bits shifted in where appropriate. 
Examples are shown for 8 bit binary numbers; most significant bit to the left.
 << Logical shift left by given number of bits.
E.g Binary 00110101 << 2 == Binary 11010100
 >> Logical shift right by given number of bits.
E.g Binary 00110101 >> 2 == Binary 00001101
^ Bitwise exclusive-or operator
https://en.wikipedia.org/wiki/Exclusive_or
Bitwise comparison for if bits differ
E.g Binary 00110101 ^ Binary 00110011 == Binary 00000110
| Bitwise or operator
https://en.wikipedia.org/wiki/Bitwise_operation#OR
Bitwise comparison gives 1 if any of corresponding bits are 1
E.g Binary 00110101 | Binary 00110011 == Binary 00110111


PCG32 Generator (pseudo-code)

PCG32 has two unsigned 64-bit integers of internal state:

 state: All 2**64 values may be attained.
 sequence: Determines which of 2**63 sequences that state iterates through. (Once set together with state at time of seeding will stay constant for this generators lifetime).
Values of sequence allow 2**63 different sequences of random numbers from the same state.

The algorithm is given 2 U64 inputs called seed_state, and seed_sequence. The algorithm proceeds in accordance with the following pseudocode:-

const N<-U64 6364136223846793005
const inc<-U64 (seed_sequence << 1) | 1
state<-U64 ((inc+seed_state)*N+inc
do forever
  xs<-U32 (((state>>18)^state)>>27)
  rot<-INT (state>>59)
  OUTPUT U32 (xs>>rot)|(xs<<((-rot)&31))
  state<-state*N+inc
end do

Note that this an anamorphism – dual to catamorphism, and encoded in some languages as a general higher-order `unfold` function, dual to `fold` or `reduce`.

Task

 Generate a class/set of functions that generates pseudo-random
numbers using the above.

 Show that the first five integers generated with the seed 42, 54
are: 2707161783 2068313097 3122475824 2211639955 3215226955



 Show that for an initial seed of 987654321, 1 the counts of 100_000 repetitions of
   floor(random_gen.next_float() * 5)

Is as follows:
   0: 20049, 1: 20022, 2: 20115, 3: 19809, 4: 20005

 Show your output here, on this page.


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