Subtractive generator: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(14 intermediate revisions by 10 users not shown)
Line 40:
{{trans|Python: With explanation}}
 
<langsyntaxhighlight lang="11l">Deque[Int] s
V seed = 292929
 
Line 66:
 
L 5
print(‘result = ’getnextr())</langsyntaxhighlight>
 
{{out}}
Line 80:
 
subtractive_generator.ads:
<langsyntaxhighlight Adalang="ada">package Subtractive_Generator is
type State is private;
procedure Initialize (Generator : in out State; Seed : Natural);
Line 90:
Last : Natural;
end record;
end Subtractive_Generator;</langsyntaxhighlight>
 
subtractive_generator.adb:
<langsyntaxhighlight Adalang="ada">package body Subtractive_Generator is
 
procedure Initialize (Generator : in out State; Seed : Natural) is
Line 125:
end Next;
 
end Subtractive_Generator;</langsyntaxhighlight>
 
Example main.adb:
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
with Subtractive_Generator;
 
Line 141:
Ada.Text_IO.Put_Line (Integer'Image (I) & ":" & Integer'Image (N));
end loop;
end Main;</langsyntaxhighlight>
 
{{out}}
Line 150:
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
<langsyntaxhighlight AutoHotkeylang="autohotkey">r := InitR(292929)
 
Loop, 10
Line 174:
, r[i] := Mod(r[i] - r[Mod(A_Index + 30, 55)], r["m"])
return, r
}</langsyntaxhighlight>
{{out}}
<pre>220: 467478574
Line 187:
229: 380969305</pre>
 
=={{header|BBC BASIC}}==
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> dummy% = FNsubrand(292929)
FOR i% = 1 TO 10
PRINT FNsubrand(0)
Line 214 ⟶ 215:
IF FNsubrand(0)
NEXT
= 0</langsyntaxhighlight>
{{out}}
<pre>
Line 227 ⟶ 228:
506003769
380969305
</pre>
 
==={{header|FreeBASIC}}===
{{trans|Kotlin}}
<syntaxhighlight lang="vb">Const As Integer mod_ = 1e9
Dim Shared As Integer state(0 To 55)
Dim Shared As Integer sk = 0, sj = 0
 
Declare Function subrand() As Integer
 
Sub subrandSeed (p1 As Integer)
Dim As Integer i, j, p2
state(0) = p1 Mod mod_
p2 = 1
j = 21
For i = 1 To 54
If j >= 55 Then j -= 55
state(j) = p2
p2 = p1 - p2
If p2 < 0 Then p2 += mod_
p1 = state(j)
j += 21
Next
sk = 0
sj = 24
For i = 1 To 165
subrand()
Next
End Sub
 
Function subrand() As Integer
If sk = sj Then
subrandSeed(0)
Else
If sk = 0 Then sk = 54 Else sk -= 1
If sj = 0 Then sj = 54 Else sj -= 1
Dim As Integer x = state(sk) - state(sj)
If x < 0 Then x += mod_
state(sk) = x
Return x
End If
End Function
 
subrandSeed(292929)
For i As Integer = 0 To 9
Print Using "r[###] = &"; i+220; subrand()
Next i
 
Sleep</syntaxhighlight>
{{out}}
<pre>Same as Kotlin entry</pre>
 
==={{header|Gambas}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">Public mod_ As Integer = 1e9
Public state[55] As Integer
Public sk As Integer = 0
Public sj As Integer = 0
 
Public Sub Main()
subrandSeed(292929)
For i As Integer = 0 To 9
Print "r["; i + 220; "] = "; subrand()
Next
End
 
Sub subrandSeed(p1 As Integer)
 
Dim i As Integer
Dim p2 As Integer = 1
Dim j As Integer = 21
 
state[0] = p1 Mod mod_
For i = 1 To 54
If j >= 55 Then j -= 55
state[j] = p2
p2 = p1 - p2
If p2 < 0 Then p2 += mod_
p1 = state[j]
j += 21
Next
sk = 0
sj = 24
For i = 1 To 165
subrand()
Next
 
End Sub
 
Function subrand() As Integer
If sk = sj Then
subrandSeed(0)
Else
If sk = 0 Then sk = 54 Else sk -= 1
If sj = 0 Then sj = 54 Else sj -= 1
Dim x As Integer = state[sk] - state[sj]
If x < 0 Then x += mod_
state[sk] = x
Return x
End If
 
End Function</syntaxhighlight>
 
==={{header|uBasic/4tH}}===
<syntaxhighlight lang="text">Push 292929 : Gosub 100 : d = Pop()
 
For i = 1 To 10
Push 0 : Gosub 100
Print Pop()
Next
 
End
 
100 s = Pop()
If s = 0 Then
p = (p + 1) % 55
@(p) = @(p) - @((p + 31) % 55)
If @(p) < 0 Then
@(p) = @(p) + 1000000000
Endif
Push (@(p)) : Return
Endif
 
@(54) = s : @(33) = 1
p = 12
 
For i = 2 To 54
@(p) = @((p + 42) % 55) - @((p + 21) % 55)
If @(p) < 0 Then
@(p) = @(p) + 1000000000
Endif
p = (p + 34) % 55
Next
 
For i = 55 To 219
Push 0 : Gosub 100 : d = Pop()
Next
 
Push 0 : Return</syntaxhighlight>
{{out}}
<pre>467478574
512932792
539453717
20349702
615542081
378707948
933204586
824858649
506003769
380969305
 
0 OK, 0:864
</pre>
 
Line 232 ⟶ 390:
This is a translation of the C example.
 
<langsyntaxhighlight lang="bracmat">1000000000:?MOD;
tbl$(state,55);
0:?si:?sj;
Line 283 ⟶ 441:
));
 
Main$;</langsyntaxhighlight>
 
{{out}}
Line 299 ⟶ 457:
=={{header|C}}==
This is basically the same as the reference C code, only differs in that it's C89.
<langsyntaxhighlight lang="c">#include<stdio.h>
 
#define MOD 1000000000
Line 341 ⟶ 499:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">
public class SubtractiveGenerator {
public static int MAX = 1000000000;
Line 384 ⟶ 542:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 402 ⟶ 560:
=={{header|C++}}==
{{libheader|Boost}}
<langsyntaxhighlight lang="cpp">
// written for clarity not efficiency.
 
Line 466 ⟶ 624:
return 0;
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 480 ⟶ 638:
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(defn xpat2-with-seed
"produces an xpat2 function initialized from seed"
[seed]
Line 502 ⟶ 660:
 
(println (xpat2) (xpat2) (xpat2)) ; prints: 467478574 512932792 539453717
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun sub-rand (state)
(let ((x (last state)) (y (last state 25)))
;; I take "circular buffer" very seriously (until some guru
Line 527 ⟶ 685:
;; test it (output same as everyone else's)
(let ((f (bentley-clever 292929)))
(dotimes (x 10) (format t "~a~%" (funcall f))))</langsyntaxhighlight>
 
=={{header|D}}==
{{trans|C}}
 
<langsyntaxhighlight lang="d">import std.stdio;
 
struct Subtractive {
Line 583 ⟶ 741:
foreach (i; 0 .. 10)
writeln(gen.subrand());
}</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 597 ⟶ 755:
 
=={{header|dc}}==
<langsyntaxhighlight lang="dc">[*
* (seed) lsx --
* Seeds the subtractive generator.
Line 648 ⟶ 806:
lrx psz
lrx psz
lrx psz</langsyntaxhighlight>
 
This program prints 467478574, 512932792, 539453717.
 
This implementation never uses multiplication, but it does use modulus (remainder from division) to put each random number in range from 0 to 10^9 - 1.
 
=={{header|EasyLang}}==
{{trans|C}}
<syntaxhighlight>
MOD = 1000000000
len state[] 55
arrbase state[] 0
global si sj .
funcdecl subrand .
proc subrand_seed p1 . .
p2 = 1
state[0] = p1 mod MOD
j = 21
for i = 1 to 54
state[j] = p2
p2 = (p1 - p2) mod MOD
p1 = state[j]
j = (j + 21) mod 55
.
si = 0
sj = 24
for i = 0 to 164
h = subrand
h = h
.
.
func subrand .
if si = sj
subrand_seed 0
.
si = (si - 1) mod 55
sj = (sj - 1) mod 55
x = (state[si] - state[sj]) mod MOD
state[si] = x
return x
.
subrand_seed 292929
for i to 10
print subrand
.
</syntaxhighlight>
 
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule Subtractive do
def new(seed) when seed in 0..999_999_999 do
s = Enum.reduce(1..53, [1, seed], fn _,[a,b|_]=acc -> [b-a | acc] end)
Line 675 ⟶ 874:
 
Subtractive.new(292929)
for _ <- 1..10, do: IO.puts Subtractive.rand</langsyntaxhighlight>
 
{{out}}
Line 693 ⟶ 892:
=={{header|F_Sharp|F#}}==
<p>Similar to Haskell, using lazy evaluation.</p>
<langsyntaxhighlight lang="fsharp">[<EntryPoint>]
let main argv =
let m = 1000000000
Line 707 ⟶ 906:
r |> Seq.skip 220 |> Seq.take 3
|> Seq.iter (printfn "%d")
0</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 715 ⟶ 914:
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">module subgenerator
implicit none
 
Line 770 ⟶ 969:
end do
end program</langsyntaxhighlight>
{{out}}
<pre>
Line 786 ⟶ 985:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 885 ⟶ 1,084:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 894 ⟶ 1,093:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">subtractgen :: Int -> [Int]
subtractgen seed = drop 220 out
where
out = mmod $ r ++<> zipWith (-) out (drop 31 out)
where
r = take 55 $ shuffle $ cycle $ take 55 s
shuffle x = head(:) xx. :head <*> shuffle xx$ drop 34 x
where
xx = drop 34 x
s = mmod $ seed : 1 : zipWith (-) s (tail s)
mmod = mapfmap (`mod` 10 ^ 9)
 
main :: IO ()
main = mapM_ print $ take 10 $ subtractgen 292929</langsyntaxhighlight>
{{out}}
<pre>
Line 923 ⟶ 1,120:
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">procedure main()
every 1 to 10 do
write(rand_sub(292929))
Line 948 ⟶ 1,145:
put(ring,get(ring))
return ring[-1]
end</langsyntaxhighlight>
 
{{out}}
Line 969 ⟶ 1,166:
Yes! '''f^:(-1)''' IS the inverse of '''f''' . When known.
 
<langsyntaxhighlight Jlang="j">came_from_locale_sg_=: coname''
cocurrent'sg' NB. install the state of rng sg into locale sg
 
Line 986 ⟶ 1,183:
cocurrent came_from_locale NB. return to previous locale
sg=: sg_sg_ NB. make a local name for sg in locale sg
</syntaxhighlight>
</lang>
 
Use:
<langsyntaxhighlight lang="sh">$ jconsole
load'sg.ijs'
sg 2
Line 996 ⟶ 1,193:
539453717 20349702 615542081 378707948
</syntaxhighlight>
</lang>
 
=={{header|Java}}==
Translation of [[Subtractive_generator#C|C]] via [[Subtractive_generator#D|D]]
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.util.function.IntSupplier;
import static java.util.stream.IntStream.generate;
 
Line 1,053 ⟶ 1,250:
.forEach(System.out::println);
}
}</langsyntaxhighlight>
 
<pre>467478574
Line 1,077 ⟶ 1,274:
except insofar as a subfunction may call its parent (or grandparent, etc),
we have defined `subrand` as an accessible subfunction of `subrandSeed`.
<syntaxhighlight lang="jq"># If $p is null, then call `subrand`,
<lang jq># input: state
# which sets .x as the PRN and which expects the the input to
# output: updated state
# be the PRNG state, which is updated.
# If $p is null, then just call `subrand`, which sets .x as the PRN.
def subrandSeed($p):
 
Line 1,092 ⟶ 1,289:
if $p == null then subrand
else
{mod: 1e9, state: [], si: 0, sj: 0, p: $p, p2: 1, j: 21}
.p = $p
| .p2 = 1
| .state[0] = ($p % .mod)
| .j = 21
| reduce range(1; 55) as $i (.;
if .j >= 55 then .j += -55 else . end
Line 1,111 ⟶ 1,306:
subrandSeed(null);
 
subrandSeed(292929)
{ mod: 1e9,
state: [range(0;55)|0],
si: 0,
sj: 0 }
| subrandSeed(292929)
| foreach range(0; 10) as $i (.;
subrand;
"r[\($i+220)] = \(.x)")</langsyntaxhighlight>
{{out}}
<pre>
Line 1,137 ⟶ 1,328:
{{works with|Julia|1.0}}
 
<langsyntaxhighlight lang="julia">i,j,m,d,seed = 55,24,10^9,34,292929 # parameters
s = Array{Int32}(undef,i); r = similar(s)
s[1:2] = [seed,1] # table initialization
Line 1,152 ⟶ 1,343:
x = readline(stdin) # wait until the ENTER key is pressed
length(x) > 0 && break # any other key before ENTER => exit
end</langsyntaxhighlight>
{{out}}
<pre>(220, 467478574)
Line 1,170 ⟶ 1,361:
=={{header|Kotlin}}==
{{trans|C}}
<langsyntaxhighlight lang="scala">// version 1.1.51
 
const val MOD = 1_000_000_000
Line 1,209 ⟶ 1,400:
subrandSeed(292_929)
for (i in 0..9) println("r[${i + 220}] = ${subrand()}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,226 ⟶ 1,417:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function SubGen(seed)
local n, r, s = 54, {}, { [0]=seed, 1 }
for n = 2,54 do s[n] = (s[n-2] - s[n-1]) % 1e9 end
Line 1,239 ⟶ 1,430:
end
subgen = SubGen(292929)
for n = 220,229 do print(n,subgen()) end</langsyntaxhighlight>
{{out}}
<pre>220 467478574
Line 1,253 ⟶ 1,444:
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">initialize[n_] :=
Module[{buffer},
buffer =
Line 1,261 ⟶ 1,452:
nextValue[buffer_] :=
Flatten@{Rest@buffer, Mod[Subtract @@ buffer[[{1, 32}]], 10^9]}</langsyntaxhighlight>
 
<pre>buffer = initialize[292929];
Line 1,280 ⟶ 1,471:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import deques, sequtils
 
template shfl(idx): untyped = (K*(idx+1)) mod I
Line 1,331 ⟶ 1,522:
let rand = subGen(292929)
for _ in 1..3:
echo rand()</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 1,340 ⟶ 1,531:
{{trans|C}}
 
<langsyntaxhighlight lang="ocaml">let _mod = 1_000_000_000
let state = Array.create 55 0
let si = ref 0
Line 1,373 ⟶ 1,564:
let () =
subrand_seed 292929;
for i = 1 to 10 do Printf.printf "%d\n" (subrand()) done</langsyntaxhighlight>
 
{{out}}
Line 1,390 ⟶ 1,581:
=={{header|ooREXX}}==
{{trans|REXX}}
<langsyntaxhighlight lang="oorexx">/*REXX program uses a subtractive generaTor,and creates a sequence of ranDom numbers. */
/* array index must be positive! */
s=.array~new
Line 1,421 ⟶ 1,612:
mod: Procedure
Parse Arg a,b
Return ((a//b)+b)//b </langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>same as with REXX</pre>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">sgv=vector(55,i,random(10^9));sgi=1;
sg()=sgv[sgi=sgi%55+1]=(sgv[sgi]-sgv[(sgi+30)%55+1])%10^9</langsyntaxhighlight>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use 5.10.0;
use strict;
 
Line 1,455 ⟶ 1,646:
 
bentley_clever(292929);
say subrand() for (1 .. 10);</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 1,466 ⟶ 1,657:
=={{header|Phix}}==
{{trans|C#}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>sequence state = repeat(0,55)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
integer pos
<span style="color: #004080;">sequence</span> <span style="color: #000000;">state</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">55</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">pos</span>
constant MAX = 1e9
function cap(integer n)
<span style="color: #008080;">constant</span> <span style="color: #000000;">MAX</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1e9</span>
if n<0 then n += MAX end if
<span style="color: #008080;">function</span> <span style="color: #000000;">cap</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
return n
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">MAX</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">n</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function next()
pos = mod(pos,55)+1
<span style="color: #008080;">function</span> <span style="color: #000000;">next</span><span style="color: #0000FF;">()</span>
integer temp = cap(state[pos]-state[mod(pos+30,55)+1])
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">,</span><span style="color: #000000;">55</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
state[pos] = temp
<span style="color: #004080;">integer</span> <span style="color: #000000;">temp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">cap</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">+</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span><span style="color: #000000;">55</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
return temp
<span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">temp</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">temp</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
procedure init(integer seed)
sequence temp = repeat(0,55)
<span style="color: #008080;">procedure</span> <span style="color: #000000;">init</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">seed</span><span style="color: #0000FF;">)</span>
temp[1] = cap(seed)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">temp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">55</span><span style="color: #0000FF;">)</span>
temp[2] = 1
<span style="color: #000000;">temp</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">cap</span><span style="color: #0000FF;">(</span><span style="color: #000000;">seed</span><span style="color: #0000FF;">)</span>
for i=3 to 55 do
<span style="color: #000000;">temp</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
temp[i] = cap(temp[i-2]-temp[i-1])
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">3</span> <span style="color: #008080;">to</span> <span style="color: #000000;">55</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">temp</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">cap</span><span style="color: #0000FF;">(</span><span style="color: #000000;">temp</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">temp</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
for i=1 to 55 do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
state[i] = temp[mod(34*i,55)+1]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">55</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">temp</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">34</span><span style="color: #0000FF;">*</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">55</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
pos = 55
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for i=55 to 219 do
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">55</span>
{} = next()
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">55</span> <span style="color: #008080;">to</span> <span style="color: #000000;">219</span> <span style="color: #008080;">do</span>
end for
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">next</span><span style="color: #0000FF;">()</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
init(292929)
for i=220 to 222 do
<span style="color: #000000;">init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">292929</span><span style="color: #0000FF;">)</span>
printf(1,"%d: %d\n",{i,next()})
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">220</span> <span style="color: #008080;">to</span> <span style="color: #000000;">222</span> <span style="color: #008080;">do</span>
end for</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d: %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">next</span><span style="color: #0000FF;">()})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,511 ⟶ 1,705:
=={{header|PicoLisp}}==
Using a circular list (as a true "ring" buffer).
<langsyntaxhighlight PicoLisplang="picolisp">(setq
*Bentley (apply circ (need 55))
*Bentley2 (nth *Bentley 32) )
Line 1,528 ⟶ 1,722:
(when (lt0 (dec *Bentley (pop '*Bentley2)))
(inc *Bentley 1000000000) )
(pop '*Bentley) )</langsyntaxhighlight>
Test:
<langsyntaxhighlight PicoLisplang="picolisp">(subRandSeed 292929)
(do 7 (println (subRand)))</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 1,542 ⟶ 1,736:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
subtractive_generator: procedure options (main);
 
Line 1,574 ⟶ 1,768:
 
end subtractive_generator;
</syntaxhighlight>
</lang>
<pre>
Required 3 results:
Line 1,602 ⟶ 1,796:
The first 55 generated values are placed directly into their reordered slots in the ring.
An array object is used along with a rotating index object to simulate a ring.
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Get-SubtractiveRandom ( [int]$Seed )
{
Line 1,649 ⟶ 1,843:
Get-SubtractiveRandom
Get-SubtractiveRandom
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,663 ⟶ 1,857:
Uses collections.deque as a ring buffer
 
<langsyntaxhighlight lang="python">
import collections
s= collections.deque(maxlen=55)
Line 1,706 ⟶ 1,900:
for i in xrange(5):
print "result = ", getnextr()
</syntaxhighlight>
</lang>
 
===Python: As a class within a module===
Python 2 and 3 compatable.
<langsyntaxhighlight lang="python">import collections
 
_ten2nine = 10**9
Line 1,732 ⟶ 1,926:
if __name__ == '__main__':
srand = Subtractive_generator()
print([srand() for i in range(5)])</langsyntaxhighlight>
 
{{out}}
<pre>[467478574, 512932792, 539453717, 20349702, 615542081]</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery"> [ stack ] is randoms ( --> s )
 
' [ 292929 1 ]
53 times
[ dup -2 peek
over -1 peek
- 1000000000 mod
join ]
dup witheach
[ swap
i^ 34 * 1 - 55 mod
poke ]
randoms put
 
[ randoms take
behead over 30 peek
- 1000000000 mod
tuck join
randoms put ] is rand ( --> n )
 
165 times [ rand drop ]
 
10 times [ rand echo cr ]</syntaxhighlight>
 
{{out}}
 
<pre>467478574
512932792
539453717
20349702
615542081
378707948
933204586
824858649
506003769
380969305</pre>
 
=={{header|Racket}}==
<langsyntaxhighlight Racketlang="racket">#lang racket
(define (make-initial-state a-list max-i)
(for/fold ((state a-list))
Line 1,767 ⟶ 2,000:
;that returns a new random number each time it's called
(define rand (create-substractive-generator 292929))
(build-list 3 (lambda (_) (rand))) ;returns a list made from the 3 wanted numbers</langsyntaxhighlight>
 
=={{header|Raku}}==
Line 1,774 ⟶ 2,007:
{{works with|Rakudo|2018.03}}
 
<syntaxhighlight lang="raku" perl6line>sub bentley-clever($seed) {
constant $mod = 1_000_000_000;
my @seeds = ($seed % $mod, 1, (* - *) % $mod ... *)[^55];
Line 1,790 ⟶ 2,023:
 
my @sr = bentley-clever(292929);
.say for @sr[^10];</langsyntaxhighlight>
Here we just make the seeder return the random sequence as a lazy list.
 
Line 1,809 ⟶ 2,042:
 
Some optimization was done so that the first two &nbsp; '''do''' &nbsp; loops executed faster.
<langsyntaxhighlight lang="rexx">/*REXX program uses a subtractive generator, and creates a sequence of random numbers. */
s.0= 292929; s.1= 1; billion= 1e9
numeric digits 20
Line 1,830 ⟶ 2,063:
mod: procedure; parse arg a,b; return ( (a // b) + b) // b
r: parse arg #; return r.#
s: parse arg #; return s.#</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
Line 1,850 ⟶ 2,083:
563900213
</pre>
 
=={{header|RPL}}==
Here, most data manipulation is performed directly in the stack. This requires less code, but slows down execution: when handling large amounts of data in RPL, it is better to store them in array variables and perform operations directly on them.
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
≪ 1
2 54 '''START''' DUP2 - 1E9 MOD '''NEXT'''
55 →ARRY ''''SEEDS'''' STO
0 54 '''FOR''' j
''''SEEDS'''' j 1 + 34 * 55 MOD GET 1 + GET '''NEXT'''
55 →ARRY ''''SEEDS'''' STO
≫ ''''INITX'''' STO
'''SEEDS''' ARRY→ DROP
55 ROLL 25 PICK - 1E9 MOD
55 →ARRY ''''SEEDS'''' STO
≫ ''''XPAT2'''' STO
|
'''INITX''' ''( seed -- )''
calculate in stack s(n)=mod(s(n-2)-s(n-1),10^9) for 2≤n≤54
Store s(0)..s(54) as an array in SEEDS variable
for j=0 to 54
r(j) = s(mod(34*(j+1),55)) & keep it in stack
Store r(0)..r(54) as an array in SEEDS variable
'''XPAT2''' ''( -- )''
Put SEEDS in stack
r(n+1) = mod(r(n-55)-r(n-24),10^9)
Transfer stack to SEEDS
|}
{{in}}
<pre>
≪ 292929 INITX
55 222 START XPAT2 NEXT
220 222 FOR j SEEDS j GET NEXT
≫ EVAL
</pre>
{{out}}
<pre>
3: 467478574
2: 512932792
1: 539453717
</pre>
Runs in 97 seconds on a basic HP-28S
 
=={{header|Ruby}}==
This implementation aims for simplicity, not speed. <code>SubRandom#rand</code> pushes to and shifts from an array; this might be slower than a ring buffer. The seeding method must call <code>rand</code> 55 extra times (220 times instead of 165 times). The code also calls [[Arithmetic/Integer#Ruby|Ruby's modulus operator]], which always returns a non-negative integer if the modulus is positive.
 
<langsyntaxhighlight lang="ruby"># SubRandom is a subtractive random number generator which generates
# the same sequences as Bentley's generator, as used in xpat2.
class SubRandom
Line 1,890 ⟶ 2,174:
 
rng = SubRandom.new(292929)
p (1..3).map { rng.rand }</langsyntaxhighlight>
 
<pre>[467478574, 512932792, 539453717]</pre>
 
=={{header|Rust}}==
 
{{works with|Rust|2021}}
This implementation uses a ring buffer in the form of a <code>Vec<i32></code>. It is fully configurable, although the seeding algorithm is only implemented for a generator with i = 55, j = 24, and m = 10<sup>9</sup>.
Like C, Rust's <code>%</code> will give negative results for some negative parameters. This algorithm uses [https://doc.rust-lang.org/std/primitive.i32.html#method.rem_euclid the <code>i32::rem_euclid()</code> method] instead.
<syntaxhighlight lang="rust">struct SubtractiveGenerator {
/// m in the formula
modulo: i32,
/// i and j in the formula
offsets: (u32, u32),
/// r in the formula. It is used as a ring buffer.
state: Vec<i32>,
/// n in the formula
position: usize,
}
 
impl SubtractiveGenerator {
fn new(modulo: i32, first_offset: u32, second_offset: u32) -> Self {
// The state size has to fit into a usize to index state properly
// without overflow.
let state_size: usize = first_offset.try_into().unwrap();
 
// Both offsets have to fit in i32 for the substractions to work
// without overflow.
assert!(first_offset <= i32::MAX as u32);
assert!(first_offset > second_offset);
SubtractiveGenerator {
modulo,
offsets: (first_offset, second_offset),
state: Vec::with_capacity(state_size),
position: 0,
}
}
}
 
impl Iterator for SubtractiveGenerator {
type Item = i32;
 
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
let state_size = self.offsets.0 as usize;
 
assert_eq!(self.state.len(), state_size);
 
self.position = (self.position + 1) % self.offsets.0 as usize;
 
let i1 = (self.position as i32 - self.offsets.0 as i32).rem_euclid(state_size as i32);
let i2 = (self.position as i32 - self.offsets.1 as i32).rem_euclid(state_size as i32);
 
let p1 = self.state[i1 as usize];
let p2 = self.state[i2 as usize];
 
self.state[self.position] = (p1 - p2).rem_euclid(self.modulo);
 
Some(self.state[self.position])
}
}
 
/// Returns a pre-seeded subtractive generator, which generates the same
/// sequences as Bentley's generator, as used in xpat2.
fn get_seeded_xpat2_gen(seed: i32) -> SubtractiveGenerator {
let mut gen = SubtractiveGenerator::new(1_000_000_000, 55, 24);
 
let state_size = gen.offsets.0 as usize;
 
let mut pre_state = Vec::with_capacity(state_size);
pre_state.push(seed);
pre_state.push(1);
for i in 2..state_size {
pre_state.push((pre_state[i - 2] - pre_state[i - 1]).rem_euclid(gen.modulo));
}
 
for i in 0..state_size {
gen.state.push(pre_state[(34 * (i + 1)) % 55]);
}
 
gen.position = 54;
for _ in 0..165 {
gen.next();
}
 
gen
}
 
fn main() {
let gen = get_seeded_xpat2_gen(292929);
 
for n in gen.take(5) {
println!("{}", n);
}
}</syntaxhighlight>
<pre>467478574
512932792
539453717
20349702
615542081</pre>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const integer: MOD is 1000000000;
Line 1,948 ⟶ 2,328:
writeln(subrand(gen));
end for;
end func;</langsyntaxhighlight>
 
{{out}}
Line 1,965 ⟶ 2,345:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">class SubRandom(seed, state=[]) {
 
const mod = 1_000_000_000;
Line 1,986 ⟶ 2,366:
 
var r = SubRandom(292929);
10.times { say r.subrand };</langsyntaxhighlight>
{{out}}
<pre>
Line 2,003 ⟶ 2,383:
=={{header|Tcl}}==
{{trans|C}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
namespace eval subrand {
variable mod 1000000000 state [lrepeat 55 0] si 0 sj 0
Line 2,037 ⟶ 2,417:
for {set i 0} {$i < 10} {incr i} {
puts [subrand::gen]
}</langsyntaxhighlight>
 
=={{header|uBasic/4tH}}==
<lang>Push 292929 : Gosub 100 : d = Pop()
 
For i = 1 To 10
Push 0 : Gosub 100
Print Pop()
Next
 
End
 
100 s = Pop()
If s = 0 Then
p = (p + 1) % 55
@(p) = @(p) - @((p + 31) % 55)
If @(p) < 0 Then
@(p) = @(p) + 1000000000
Endif
Push (@(p)) : Return
Endif
 
@(54) = s : @(33) = 1
p = 12
 
For i = 2 To 54
@(p) = @((p + 42) % 55) - @((p + 21) % 55)
If @(p) < 0 Then
@(p) = @(p) + 1000000000
Endif
p = (p + 34) % 55
Next
 
For i = 55 To 219
Push 0 : Gosub 100 : d = Pop()
Next
 
Push 0 : Return</lang>
{{out}}
<pre>467478574
512932792
539453717
20349702
615542081
378707948
933204586
824858649
506003769
380969305
 
0 OK, 0:864
</pre>
 
=={{header|Wren}}==
{{trans|C}}
<langsyntaxhighlight ecmascriptlang="wren">var mod = 1e9
var state = List.filled(55, 0)
var si = 0
Line 2,127 ⟶ 2,456:
 
subrandSeed.call(292929)
for (i in 0..9) System.print("r[%(i+220)] = %(subrand.call())")</langsyntaxhighlight>
 
{{out}}
Line 2,147 ⟶ 2,476:
{{trans|Python}}
{{trans|C}}
<langsyntaxhighlight lang="zkl">fcn rand_sub(x){
var ring=L(),m=(1e9).toInt();
mod:='wrap(n){ if(n<0) n+m else n };
Line 2,158 ⟶ 2,487:
ring.append((ring.pop(0)-ring[-24]):mod(_));
return(ring[-1]);
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">do(4){ println(rand_sub(292929)) } //seed ignored after first call</langsyntaxhighlight>
{{out}}
<pre>
9,485

edits