Subtractive generator: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(9 intermediate revisions by 6 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
Line 905 ⟶ 1,104:
 
main :: IO ()
main = mapM_ print $ take 10 $ subtractgen 292929</langsyntaxhighlight>
{{out}}
<pre>
Line 921 ⟶ 1,120:
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">procedure main()
every 1 to 10 do
write(rand_sub(292929))
Line 946 ⟶ 1,145:
put(ring,get(ring))
return ring[-1]
end</langsyntaxhighlight>
 
{{out}}
Line 967 ⟶ 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 984 ⟶ 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 994 ⟶ 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,051 ⟶ 1,250:
.forEach(System.out::println);
}
}</langsyntaxhighlight>
 
<pre>467478574
Line 1,075 ⟶ 1,274:
except insofar as a subfunction may call its parent (or grandparent, etc),
we have defined `subrand` as an accessible subfunction of `subrandSeed`.
<langsyntaxhighlight lang="jq"># If $p is null, then call `subrand`,
# which sets .x as the PRN and which expects the the input to
# be the PRNG state, which is updated.
Line 1,110 ⟶ 1,309:
| foreach range(0; 10) as $i (.;
subrand;
"r[\($i+220)] = \(.x)")</langsyntaxhighlight>
{{out}}
<pre>
Line 1,129 ⟶ 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,144 ⟶ 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,162 ⟶ 1,361:
=={{header|Kotlin}}==
{{trans|C}}
<langsyntaxhighlight lang="scala">// version 1.1.51
 
const val MOD = 1_000_000_000
Line 1,201 ⟶ 1,400:
subrandSeed(292_929)
for (i in 0..9) println("r[${i + 220}] = ${subrand()}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,218 ⟶ 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,231 ⟶ 1,430:
end
subgen = SubGen(292929)
for n = 220,229 do print(n,subgen()) end</langsyntaxhighlight>
{{out}}
<pre>220 467478574
Line 1,245 ⟶ 1,444:
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">initialize[n_] :=
Module[{buffer},
buffer =
Line 1,253 ⟶ 1,452:
nextValue[buffer_] :=
Flatten@{Rest@buffer, Mod[Subtract @@ buffer[[{1, 32}]], 10^9]}</langsyntaxhighlight>
 
<pre>buffer = initialize[292929];
Line 1,272 ⟶ 1,471:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import deques, sequtils
 
template shfl(idx): untyped = (K*(idx+1)) mod I
Line 1,323 ⟶ 1,522:
let rand = subGen(292929)
for _ in 1..3:
echo rand()</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 1,332 ⟶ 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,365 ⟶ 1,564:
let () =
subrand_seed 292929;
for i = 1 to 10 do Printf.printf "%d\n" (subrand()) done</langsyntaxhighlight>
 
{{out}}
Line 1,382 ⟶ 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,413 ⟶ 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,447 ⟶ 1,646:
 
bentley_clever(292929);
say subrand() for (1 .. 10);</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 1,458 ⟶ 1,657:
=={{header|Phix}}==
{{trans|C#}}
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<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>
Line 1,496 ⟶ 1,695:
<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>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 1,506 ⟶ 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,523 ⟶ 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,537 ⟶ 1,736:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
subtractive_generator: procedure options (main);
 
Line 1,569 ⟶ 1,768:
 
end subtractive_generator;
</syntaxhighlight>
</lang>
<pre>
Required 3 results:
Line 1,597 ⟶ 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,644 ⟶ 1,843:
Get-SubtractiveRandom
Get-SubtractiveRandom
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,658 ⟶ 1,857:
Uses collections.deque as a ring buffer
 
<langsyntaxhighlight lang="python">
import collections
s= collections.deque(maxlen=55)
Line 1,701 ⟶ 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,727 ⟶ 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,762 ⟶ 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,769 ⟶ 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,785 ⟶ 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,804 ⟶ 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,825 ⟶ 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,845 ⟶ 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,885 ⟶ 2,174:
 
rng = SubRandom.new(292929)
p (1..3).map { rng.rand }</langsyntaxhighlight>
 
<pre>[467478574, 512932792, 539453717]</pre>
 
=={{header|Rust}}==
 
Line 1,893 ⟶ 2,183:
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.
<langsyntaxhighlight lang="rust">struct SubtractiveGenerator {
/// m in the formula
modulo: i32,
Line 1,977 ⟶ 2,267:
println!("{}", n);
}
}</langsyntaxhighlight>
<pre>467478574
512932792
Line 1,985 ⟶ 2,275:
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const integer: MOD is 1000000000;
Line 2,038 ⟶ 2,328:
writeln(subrand(gen));
end for;
end func;</langsyntaxhighlight>
 
{{out}}
Line 2,055 ⟶ 2,345:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">class SubRandom(seed, state=[]) {
 
const mod = 1_000_000_000;
Line 2,076 ⟶ 2,366:
 
var r = SubRandom(292929);
10.times { say r.subrand };</langsyntaxhighlight>
{{out}}
<pre>
Line 2,093 ⟶ 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,127 ⟶ 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,217 ⟶ 2,456:
 
subrandSeed.call(292929)
for (i in 0..9) System.print("r[%(i+220)] = %(subrand.call())")</langsyntaxhighlight>
 
{{out}}
Line 2,237 ⟶ 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,248 ⟶ 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