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

From Rosetta Code
Content added Content deleted
(Add Factor)
(Add Red)
Line 260: Line 260:
{{out}}
{{out}}
<pre>(959861 333139 981593 524817 432883)</pre>
<pre>(959861 333139 981593 524817 432883)</pre>

=={{header|Red}}==
{{trans|Phix}}
<lang rebol>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]</lang>
{{out}}
<pre>
959861
333139
981593
524817
432883
</pre>


=={{header|Wren}}==
=={{header|Wren}}==

Revision as of 21:50, 2 January 2022

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


ALGOL 68

Uses (long) integers. <lang algol68>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</lang>

Output:
 959861 333139 981593 524817 432883

C++

<lang cpp>#include <exception>

  1. 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;

}</lang>

Output:
959861
333139
981593
524817
432883

CLU

<lang 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</lang>

Output:
959861
333139
981593
524817
432883

COBOL

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

Factor

Translation of: Phix
Works with: Factor version 0.99 2021-06-02

<lang factor>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</lang>

Output:
959861
333139
981593
524817
432883

FreeBASIC

<lang 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 </lang>

J

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

Output:
959861 333139 981593 524817 432883 387691

Perl

<lang 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;</lang>

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

<lang python>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())

</lang>

Output:
959861
333139
981593
524817
432883

Raku

<lang perl6>sub msq {

   state $seed = 675248;
   $seed = $seed² div 1000 mod 1000000;

}

say msq() xx 5;</lang>

Output:
(959861 333139 981593 524817 432883)

Red

Translation of: Phix

<lang rebol>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]</lang>

Output:
959861
333139
981593
524817
432883

Wren

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

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

Output:
959861
333139
981593
524817
432883