Pseudo-random numbers/Middle-square method: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎J: shorter and faster)
Line 819: Line 819:


=={{header|J}}==
=={{header|J}}==
<syntaxhighlight lang="j">(_6{._3}.])&.:(10&#.^:_1)@(*~) ^: (>:i.6) 675248</syntaxhighlight>
<syntaxhighlight lang="j">(_6 {. _3 }. ])&.(10&#.^:_1)@*~^:(>: i. 6) 675248</syntaxhighlight>
Or, shorter & faster:
<syntaxhighlight lang="j">}. (1e6 1e3 {.@#: *:)^:(< 7) 675248</syntaxhighlight>
{{out}}
{{out}}
<pre>959861 333139 981593 524817 432883 387691</pre>
<pre>959861 333139 981593 524817 432883 387691</pre>

Revision as of 16:54, 13 October 2023

Task
Pseudo-random numbers/Middle-square method
You are encouraged to solve this task according to the task description, using any language you may know.
This page uses content from Wikipedia. The original article was at Middle-square method. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)
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
Task
  • 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.
  • Show your output here, on this page.

11l

Translation of: Python
F random()
   V :seed = 675248
   :seed = Int(String(Int64(:seed) ^ 2).zfill(12)[3 .+ 6])
   R :seed

L 5
   print(random())
Output:
959861
333139
981593
524817
432883

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              */
/*********************************/
.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"
~/.../rosetta/asm1 $ pRandom64
 959861
 333139
 981593
 524817
 432883

Ada

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 ) ) )
    OD
END
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 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
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              */
/*********************************/
.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"
959861
 333139
 981593
 524817
 432883

Arturo

seed: 675248

rand: function => [
    let 'seed <= ((seed^2) / 1000) % 1000000
]

do.times: 5 -> print rand
Output:
959861
333139
981593
524817
432883

AWK

# 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)
}
Output:
 1: 959861
 2: 333139
 3: 981593
 4: 524817
 5: 432883

BASIC

BASIC256

global semilla
semilla = 675248
for i = 1 to 5
	print i; ": "; Random()
next i
end

function Random()
	semilla = floor((semilla*semilla/1e3) mod 1e6)
	return int(semilla)
end function
Output:
1: 959861
2: 333139
3: 981593
4: 524817
5: 432883

Chipmunk Basic

Works with: Chipmunk Basic version 3.6.4
10 semilla = 675248
20 for i = 1 to 5
30 print i;": ";semilla
31 semilla = ((semilla*semilla)/1000) mod 1000000
40 next i

FreeBASIC

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

PureBasic

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
Output:
1: 959861
2: 333139
3: 981593
4: 524817
5: 432883

uBasic/4tH

Translation of: C
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 (a@*a@/1000%1000000)
Output:
959861
333139
981593
524817
432883

0 OK, 0:140 

Visual Basic

Translation of: FreeBASIC
Works with: Visual Basic version 5
Works with: Visual Basic version 6
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
Output:

As expected.

Yabasic

semilla = 675248
for i = 1 to 5
	print i, ": ", Random()
next i
end

sub Random()
	semilla = floor(mod(((semilla*semilla)/1e3), 1e6))
	return int(semilla)
end sub
Output:
1: 959861
2: 333139
3: 981593
4: 524817
5: 432883

bc

s = 675248
define r() {
    s = s * s / 1000 % 1000000
    return(s)
}

for (i = 0; i != 5; ++i) r()
Output:
959861
333139
981593
524817
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 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
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

Delphi

Works with: Delphi version 6.0


var Seed: int64 = 675248;

function MiddleSquareRandom: int64;
var S: string;
begin
S:=IntToStr(Seed * Seed);
while Length(S)<12 do S:='0'+S;
Seed:=StrToInt(MidStr(S, 4, 6));
Result:=Seed;
end;


procedure ShowMiddleSqrRandom(Memo: TMemo);
var I: integer;
begin
for I:=1 to 5 do
 Memo.Lines.Add(IntToStr(MiddleSquareRandom));
end;
Output:
959861
333139
981593
524817
432883
Elapsed Time: 5.610 ms.


dc

675248 5 sn
[d * 1000 / 1000000 %] sr
[lr x p ln 1 - d sn 0 <l] d sl x
Output:
959861
333139
981593
524817
432883

EasyLang

global seed .
seed = 675248
func rand .
   strSeed$ = seed
   s$ = seed * seed
   while not len s$ = len strSeed$ * 2
      s$ = "0" & s$
   .
   seed = number substr s$ (len strSeed$ / 2 + 1) len strSeed$
   randNum = seed
   return randNum
.
for i = 1 to 5
   print rand
.
Output:
959861
333139
981593
524817
432883

F#

// 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")
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: seed
675248 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

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

Haskell

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

J

(_6 {. _3 }. ])&.(10&#.^:_1)@*~^:(>: i. 6) 675248

Or, shorter & faster:

}. (1e6 1e3 {.@#: *:)^:(< 7) 675248
Output:
959861 333139 981593 524817 432883 387691

Java

public final class MiddleSquareTask {

	public static void main(String[] aArgs) {
		MiddleSquare random = new MiddleSquare(675248);
		
		for ( int i = 0; i < 5; i++ ) {
	        System.out.println(random.nextInt());
		}
	}	

}

final class MiddleSquare {
	
	public MiddleSquare(int aSeed) {
		final int length = String.valueOf(aSeed).length();
		if ( length % 2 == 1 ) {
			throw new IllegalArgumentException("Seed must have an even number of digits");
		}
		
		state = aSeed;
		divisor = (int) Math.pow(10, length / 2);
		modulus = (int) Math.pow(10, length);
	}
	
	public int nextInt() {
		state = ( ( state * state ) / divisor ) % modulus;		
		return (int) state;
	}
	
	private long state;
	
	private final int divisor, modulus;
	
}
Output:
959861
333139
981593
524817
432883

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 recursively
def 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

Lambdatalk

Translation of: C
{def W.fill
 {lambda {:v :n}
  {if {<= :n 0}
   then
   else :v{W.fill :v {- :n 1}}}}}
-> W.fill 

{def W.pad
 {lambda {:n :size}
  {if {<= {W.length :n} :size} 
   then :n{W.fill :size {- :size {W.length :n}}}
   else {W.slice 0 {- :size {W.length :n}} :n}}}}
-> W.pad

{def randoms
 {lambda {:s :n}
  {if {>= :n 0}
   then :s
        {randoms {W.pad {% {floor {/ {* :s :s} 1.e3}} 1.e6} 6}
                 {- :n 1}}
   else}}}
-> randoms

{randoms 959861 4}
-> 959861 333139 981593 524817 432883

Lua

seed = 675248

function rnd ()
    local s = tostring(seed * seed)
    while #s ~= 12 do
        s = "0" .. s
    end
    seed = tonumber(s:sub(4, 9))
    return seed
end

for i = 1, 5 do
    print(rnd())
end
Output:
959861
333139
981593
524817
432883

Miranda

main :: [sys_message]
main = [Stdout (lay (map show numbers))]
       where numbers = take 5 (randoms 6 seed)
             seed    = 675248

randoms :: num->num->[num]
randoms sz = tl . iterate (msq sz)

msq :: num->num->num
msq sz seed = sq div (10^(sz div 2)) mod 10^sz
              where sq = seed^2
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

OCaml

let random_seq seed =
  let next x = x * x / 1000 mod 1000_000 in
  Seq.iterate next (next seed)

(* test *)
let () =
  random_seq 675248 |> Seq.take 5 |> Seq.iter (Printf.printf " %u")
Output:
 959861 333139 981593 524817 432883

Perl

#!/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;
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

Python

seed = 675248
def random():
    global seed
    seed = int(str(seed ** 2).zfill(12)[3:9])
    return seed
for _ in range(5):
    print(random())
Output:
959861
333139
981593
524817
432883

Quackery

As specified in task pseudo-code.

(Adding one zero at a time irks me. If I wasn't sticking strictly to the pseudo-code I'd have written 12 over size - char 0 swap of join instead of the while loop – i.e. calculate how many 0s are required and add that many in one hit.

Or even "add more than enough 0s and then truncate". $ "000000000000" join 12 split drop.)

  [ dip [ split nip ]
    split drop ]           is mid  ( [ n n --> [ )
    
  [ stack 675248 ]         is seed (       --> n )

  [ seed take
    dup * number$
    [ dup size 12 != while
      char 0 join
      again ]
    3 6 mid $->n drop 
    dup seed put ]         is rand (       --> n )
 
  5 times [ rand echo sp ]

Divide and modulo.

  [ stack 675248 ] is seed ( --> s )

  [ seed take 
    dup * 1000 / 
    1000000 mod
    dup seed put ] is rand ( --> n )

  5 times [ rand echo sp ]
Output:

For both versions.

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

RPL

Works with: Halcyon Calc version 4.2.7
RPL code Comment
 ≪ 
    SQ →STR
    WHILE DUP SIZE 12 ≠ REPEAT
        "0" SWAP + END
    4 9 SUB STR→
≫ ‘RMID’ STO

≪ 675248 1 5 START RMID NEXT
≫ ‘TASK’ STO
RMID ( seed -- seed )
var s = str(seed * seed)
do while not len(s) = 12
       s = "0" + s end do
seed = val(mid(s, 4, 6))
return seed



Output:
5: 959861
4: 333139
3: 981593
2: 524817
1: 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]

Tcl

set seed 675248

proc rnd {} {
    global seed
    set s [expr {$seed * $seed}]
    while {[string length $s] ne 12} {
        set s [string cat 0 $s]
    }
    set seed [string range $s 3 8]
    return $seed
}

for {set i 0} {$i < 5}  {incr i} {
    puts [rnd]
}
Output:
959861
333139
981593
524817
432883

UNIX Shell

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

The same as Python's

VBA

See Visual Basic

Wren

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

var seed = 675248
for (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