I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

Pseudo-random numbers/Middle-square method

Pseudo-random numbers/Middle-square method
You are encouraged to solve this task according to the task description, using any language you may know.
Middle-square_method Generator
The Method

To generate a sequence of n-digit pseudorandom numbers, an n-digit starting value is created and squared, producing a 2n-digit number. If the result has fewer than 2n digits, leading zeroes are added to compensate. The middle n digits of the result would be the next number in the sequence and returned as the result. This process is then repeated to generate more numbers.

Pseudo code
```var seed = 675248
function random()
var s = str(seed * seed) 'str: turn a number into string
do while not len(s) = 12
s = "0" + s          'add zeroes before the string
end do
seed = val(mid(s, 4, 6)) 'mid: string variable, start, length
'val: turn a string into number
return seed
end function
```
Middle-square method use
```for i = 1 to 5
print random()
end for
```
• Generate a class/set of functions that generates pseudo-random

numbers (6 digits) as shown above.

• Show the first five integers generated with the seed 675248 as shown above.

AArch64 Assembly

Works with: as version Raspberry Pi 3B version Buster 64 bits
or android 64 bits with application Termux
` /* 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              *//*********************************/.datasMessResult:        .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,#51:    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 callqAdrszCarriageReturn:   .quad szCarriageReturnqAdrsMessResult:        .quad sMessResultqAdrsZoneConv:          .quad sZoneConvqAdrqSeed:              .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 x30qdiv:            .quad 1000qdiv2:           .quad 1000000 /********************************************************//*        File Include fonctions                        *//********************************************************//* for this file see task include a file in language AArch64 assembly */.include "../includeARM64.inc"  `
```~/.../rosetta/asm1 \$ pRandom64
959861
333139
981593
524817
432883
```

`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;`
Output:
``` 959861 333139 981593 524817 432883
```

ALGOL 68

Uses (long) integers.

`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 ) ) )    ODEND`
Output:
``` 959861 333139 981593 524817 432883
```

AppleScript

`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 generatorend newGenerator local generator, outputset generator to newGenerator(6, 675248)set output to {}repeat 5 times    set end of output to generator's getRandom()end repeatreturn output`
Output:
`{959861, 333139, 981593, 524817, 432883}`

ARM Assembly

Works with: as version Raspberry Pi
or android 32 bits with application Termux
` /* 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              *//*********************************/.datasMessResult:        .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,#51:    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 calliAdrszCarriageReturn:   .int szCarriageReturniAdrsMessResult:        .int sMessResultiAdrsZoneConv:          .int sZoneConviAdriSeed:              .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 registersidiv:            .int 1000idiv2:           .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 number1:                     @ 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 3f2:                     @ 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          @ remainder100:                   @ function end    pop {r3-r9,lr}     @ restaur registers    bx lr  /***************************************************//*      ROUTINES INCLUDE                           *//***************************************************/.include "../affichage.inc" `
```959861
333139
981593
524817
432883
```

AWK

` # syntax: GAWK -f PSEUDO-RANDOM_NUMBERS_MIDDLE-SQUARE_METHOD.AWKBEGIN {    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)} `
Output:
``` 1: 959861
2: 333139
3: 981593
4: 524817
5: 432883
```

C

`#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;}`
Output:

959861 333139 981593 524817 432883

C++

`#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;}`
Output:
```959861
333139
981593
524817
432883```

CLU

`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 nextend 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()))    endend start_up`
Output:
```959861
333139
981593
524817
432883```

COBOL

`       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.`
Output:
```959861
333139
981593
524817
432883
```

F#

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

Factor

Translation of: Phix
Works with: Factor version 0.99 2021-06-02
`USING: kernel math namespaces prettyprint ; SYMBOL: seed675248 seed set-global : rand ( -- n ) seed get sq 1000 /i 1000000 mod dup seed set ; 5 [ rand . ] times`
Output:
```959861
333139
981593
524817
432883
```

Forth

Works with: gforth version 0.7.3

The loop keeps the seed on top of the stack.

`: next-random dup * 1000 / 1000000 mod ;: 5-random-num 5 0 do next-random dup . loop ;675248 5-random-num`
Output:
`959861 333139 981593 524817 432883  ok`

FreeBASIC

`Dim Shared seed As Integer = 675248Dim i As IntegerDeclare Function Rand As IntegerFor i = 1 To 5	Print RandNext iSleep 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 = seedEnd Function `

Go

`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)    }}`
Output:
```959861
333139
981593
524817
432883
```

`findPseudoRandom :: Int -> IntfindPseudoRandom 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`
Output:
`[959861,333139,981593,524817,432883]`

J

`(_6{._3}.])&.:(10&#.^:_1)@(*~) ^: (>:i.6) 675248`
Output:
`959861 333139 981593 524817 432883 387691`

jq

Works with gojq, the Go implementation of jq

The proposed PRNG hardly deserves the name and so this entry avoids it.

`# 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 recursivelydef middle_squares:  middle_square | ., middle_squares; limit(5; 675248 | middle_squares)`
Output:

As expected.

Julia

`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 `
Output:
```959861
333139
981593
524817
432883
```

Nim

Translation of: Raku
`proc rand:int =   var seed {.global.} = 675248  seed = int(seed*seed) div 1000 mod 1000000  return seed  for _ in 1..5: echo rand()`
Output:
```959861
333139
981593
524817
432883
```

Perl

`#!/usr/bin/perl use strict; # https://rosettacode.org/wiki/Pseudo-random_numbers/Middle-square_methoduse warnings; sub msq  {  use feature qw( state );  state \$seed = 675248;  \$seed = sprintf "%06d", \$seed ** 2 / 1000 % 1e6;  } print msq, "\n" for 1 .. 5;`
Output:
```959861
333139
981593
524817
432883
```

Phix

You don't actually have to use strings, but should you so desire the commented-out line gives exactly the same results. Output matches Python.

```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
```

PureBasic

`Procedure.i MSRandom()  Static.i seed=675248  seed = (seed*seed/1000)%1000000  ProcedureReturn seedEndProcedure If OpenConsole()  For i=1 To 5 : PrintN(Str(i)+": "+Str(MSRandom())) : Next  Input()EndIf`
Output:
```1: 959861
2: 333139
3: 981593
4: 524817
5: 432883```

Python

`seed = 675248def random():    global seed    s = str(seed ** 2)    while len(s) != 12:        s = "0" + s    seed = int(s[3:9])    return seedfor i in range(0,5):    print(random()) `
Output:
```959861
333139
981593
524817
432883```

Raku

`sub msq {    state \$seed = 675248;    \$seed = \$seed² div 1000 mod 1000000;} say msq() xx 5;`
Output:
`(959861 333139 981593 524817 432883)`

Red

Translation of: Phix
`Red[]seed: 675248rand: does [seed: to-integer (seed * 1.0 * seed / 1000) % 1000000]  ; multiply by 1.0 to avoid integer overflow (32-bit)loop 5 [print rand]`
Output:
```959861
333139
981593
524817
432883
```

Ruby

`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)`
Output:
```959861
333139
981593
524817
432883```

Sidef

`class MiddleSquareMethod(seed, k = 1000) {    method next {        seed = (seed**2 // k % k**2)    }} var obj = MiddleSquareMethod(675248)say 5.of { obj.next }`
Output:
```[959861, 333139, 981593, 524817, 432883]
```

uBasic/4tH

Translation of: C
`If Info("wordsize") < 64 Then Print "This needs a 64-bit uBasic" : End s = 675248For i = 1 To 5  Print Set(s, FUNC(_random(s)))Next End _random Param (1) : Return ([email protected]*[email protected]/1000%1000000)`
Output:
```959861
333139
981593
524817
432883

0 OK, 0:140
```

UNIX Shell

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

The same as Python's

See Visual Basic

Visual Basic

Translation of: FreeBASIC
Works with: Visual Basic version 5
Works with: Visual Basic version 6
`Option ExplicitDim seed As LongSub Main()    Dim i As Integer    seed = 675248    For i = 1 To 5        Debug.Print Rand    Next iEnd SubFunction 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 = seedEnd Function`
Output:

As expected.

Wren

`var random = Fn.new { |seed| ((seed * seed)/1e3).floor % 1e6 } var seed = 675248for (i in 1..5) System.print(seed = random.call(seed))`
Output:
```959861
333139
981593
524817
432883
```

XPL0

`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, ^ )];]`
Output:
```959861 333139 981593 524817 432883
```