Subtractive generator: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
|||
Line 40: | Line 40: | ||
{{trans|Python: With explanation}} |
{{trans|Python: With explanation}} |
||
< |
<syntaxhighlight lang="11l">Deque[Int] s |
||
V seed = 292929 |
V seed = 292929 |
||
Line 66: | Line 66: | ||
L 5 |
L 5 |
||
print(‘result = ’getnextr())</ |
print(‘result = ’getnextr())</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 80: | Line 80: | ||
subtractive_generator.ads: |
subtractive_generator.ads: |
||
< |
<syntaxhighlight lang="ada">package Subtractive_Generator is |
||
type State is private; |
type State is private; |
||
procedure Initialize (Generator : in out State; Seed : Natural); |
procedure Initialize (Generator : in out State; Seed : Natural); |
||
Line 90: | Line 90: | ||
Last : Natural; |
Last : Natural; |
||
end record; |
end record; |
||
end Subtractive_Generator;</ |
end Subtractive_Generator;</syntaxhighlight> |
||
subtractive_generator.adb: |
subtractive_generator.adb: |
||
< |
<syntaxhighlight lang="ada">package body Subtractive_Generator is |
||
procedure Initialize (Generator : in out State; Seed : Natural) is |
procedure Initialize (Generator : in out State; Seed : Natural) is |
||
Line 125: | Line 125: | ||
end Next; |
end Next; |
||
end Subtractive_Generator;</ |
end Subtractive_Generator;</syntaxhighlight> |
||
Example main.adb: |
Example main.adb: |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; |
||
with Subtractive_Generator; |
with Subtractive_Generator; |
||
Line 141: | Line 141: | ||
Ada.Text_IO.Put_Line (Integer'Image (I) & ":" & Integer'Image (N)); |
Ada.Text_IO.Put_Line (Integer'Image (I) & ":" & Integer'Image (N)); |
||
end loop; |
end loop; |
||
end Main;</ |
end Main;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 150: | Line 150: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
{{works with|AutoHotkey_L}} |
{{works with|AutoHotkey_L}} |
||
< |
<syntaxhighlight lang="autohotkey">r := InitR(292929) |
||
Loop, 10 |
Loop, 10 |
||
Line 174: | Line 174: | ||
, r[i] := Mod(r[i] - r[Mod(A_Index + 30, 55)], r["m"]) |
, r[i] := Mod(r[i] - r[Mod(A_Index + 30, 55)], r["m"]) |
||
return, r |
return, r |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>220: 467478574 |
<pre>220: 467478574 |
||
Line 189: | Line 189: | ||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
< |
<syntaxhighlight lang="bbcbasic"> dummy% = FNsubrand(292929) |
||
FOR i% = 1 TO 10 |
FOR i% = 1 TO 10 |
||
PRINT FNsubrand(0) |
PRINT FNsubrand(0) |
||
Line 214: | Line 214: | ||
IF FNsubrand(0) |
IF FNsubrand(0) |
||
NEXT |
NEXT |
||
= 0</ |
= 0</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 232: | Line 232: | ||
This is a translation of the C example. |
This is a translation of the C example. |
||
< |
<syntaxhighlight lang="bracmat">1000000000:?MOD; |
||
tbl$(state,55); |
tbl$(state,55); |
||
0:?si:?sj; |
0:?si:?sj; |
||
Line 283: | Line 283: | ||
)); |
)); |
||
Main$;</ |
Main$;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 299: | Line 299: | ||
=={{header|C}}== |
=={{header|C}}== |
||
This is basically the same as the reference C code, only differs in that it's C89. |
This is basically the same as the reference C code, only differs in that it's C89. |
||
< |
<syntaxhighlight lang="c">#include<stdio.h> |
||
#define MOD 1000000000 |
#define MOD 1000000000 |
||
Line 341: | Line 341: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp"> |
||
public class SubtractiveGenerator { |
public class SubtractiveGenerator { |
||
public static int MAX = 1000000000; |
public static int MAX = 1000000000; |
||
Line 384: | Line 384: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 402: | Line 402: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
{{libheader|Boost}} |
{{libheader|Boost}} |
||
< |
<syntaxhighlight lang="cpp"> |
||
// written for clarity not efficiency. |
// written for clarity not efficiency. |
||
Line 466: | Line 466: | ||
return 0; |
return 0; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 480: | Line 480: | ||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
< |
<syntaxhighlight lang="clojure">(defn xpat2-with-seed |
||
"produces an xpat2 function initialized from seed" |
"produces an xpat2 function initialized from seed" |
||
[seed] |
[seed] |
||
Line 502: | Line 502: | ||
(println (xpat2) (xpat2) (xpat2)) ; prints: 467478574 512932792 539453717 |
(println (xpat2) (xpat2) (xpat2)) ; prints: 467478574 512932792 539453717 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
< |
<syntaxhighlight lang="lisp">(defun sub-rand (state) |
||
(let ((x (last state)) (y (last state 25))) |
(let ((x (last state)) (y (last state 25))) |
||
;; I take "circular buffer" very seriously (until some guru |
;; I take "circular buffer" very seriously (until some guru |
||
Line 527: | Line 527: | ||
;; test it (output same as everyone else's) |
;; test it (output same as everyone else's) |
||
(let ((f (bentley-clever 292929))) |
(let ((f (bentley-clever 292929))) |
||
(dotimes (x 10) (format t "~a~%" (funcall f))))</ |
(dotimes (x 10) (format t "~a~%" (funcall f))))</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="d">import std.stdio; |
||
struct Subtractive { |
struct Subtractive { |
||
Line 583: | Line 583: | ||
foreach (i; 0 .. 10) |
foreach (i; 0 .. 10) |
||
writeln(gen.subrand()); |
writeln(gen.subrand()); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>467478574 |
<pre>467478574 |
||
Line 597: | Line 597: | ||
=={{header|dc}}== |
=={{header|dc}}== |
||
< |
<syntaxhighlight lang="dc">[* |
||
* (seed) lsx -- |
* (seed) lsx -- |
||
* Seeds the subtractive generator. |
* Seeds the subtractive generator. |
||
Line 648: | Line 648: | ||
lrx psz |
lrx psz |
||
lrx psz |
lrx psz |
||
lrx psz</ |
lrx psz</syntaxhighlight> |
||
This program prints 467478574, 512932792, 539453717. |
This program prints 467478574, 512932792, 539453717. |
||
Line 656: | Line 656: | ||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
{{trans|Ruby}} |
{{trans|Ruby}} |
||
< |
<syntaxhighlight lang="elixir">defmodule Subtractive do |
||
def new(seed) when seed in 0..999_999_999 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) |
s = Enum.reduce(1..53, [1, seed], fn _,[a,b|_]=acc -> [b-a | acc] end) |
||
Line 675: | Line 675: | ||
Subtractive.new(292929) |
Subtractive.new(292929) |
||
for _ <- 1..10, do: IO.puts Subtractive.rand</ |
for _ <- 1..10, do: IO.puts Subtractive.rand</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 693: | Line 693: | ||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
<p>Similar to Haskell, using lazy evaluation.</p> |
<p>Similar to Haskell, using lazy evaluation.</p> |
||
< |
<syntaxhighlight lang="fsharp">[<EntryPoint>] |
||
let main argv = |
let main argv = |
||
let m = 1000000000 |
let m = 1000000000 |
||
Line 707: | Line 707: | ||
r |> Seq.skip 220 |> Seq.take 3 |
r |> Seq.skip 220 |> Seq.take 3 |
||
|> Seq.iter (printfn "%d") |
|> Seq.iter (printfn "%d") |
||
0</ |
0</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>467478574 |
<pre>467478574 |
||
Line 715: | Line 715: | ||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
{{works with|Fortran|90 and later}} |
{{works with|Fortran|90 and later}} |
||
< |
<syntaxhighlight lang="fortran">module subgenerator |
||
implicit none |
implicit none |
||
Line 770: | Line 770: | ||
end do |
end do |
||
end program</ |
end program</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 786: | Line 786: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 885: | Line 885: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 894: | Line 894: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">subtractgen :: Int -> [Int] |
||
subtractgen seed = drop 220 out |
subtractgen seed = drop 220 out |
||
where |
where |
||
Line 905: | Line 905: | ||
main :: IO () |
main :: IO () |
||
main = mapM_ print $ take 10 $ subtractgen 292929</ |
main = mapM_ print $ take 10 $ subtractgen 292929</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 921: | Line 921: | ||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
< |
<syntaxhighlight lang="icon">procedure main() |
||
every 1 to 10 do |
every 1 to 10 do |
||
write(rand_sub(292929)) |
write(rand_sub(292929)) |
||
Line 946: | Line 946: | ||
put(ring,get(ring)) |
put(ring,get(ring)) |
||
return ring[-1] |
return ring[-1] |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 967: | Line 967: | ||
Yes! '''f^:(-1)''' IS the inverse of '''f''' . When known. |
Yes! '''f^:(-1)''' IS the inverse of '''f''' . When known. |
||
< |
<syntaxhighlight lang="j">came_from_locale_sg_=: coname'' |
||
cocurrent'sg' NB. install the state of rng sg into locale sg |
cocurrent'sg' NB. install the state of rng sg into locale sg |
||
Line 984: | Line 984: | ||
cocurrent came_from_locale NB. return to previous locale |
cocurrent came_from_locale NB. return to previous locale |
||
sg=: sg_sg_ NB. make a local name for sg in locale sg |
sg=: sg_sg_ NB. make a local name for sg in locale sg |
||
</syntaxhighlight> |
|||
</lang> |
|||
Use: |
Use: |
||
< |
<syntaxhighlight lang="sh">$ jconsole |
||
load'sg.ijs' |
load'sg.ijs' |
||
sg 2 |
sg 2 |
||
Line 994: | Line 994: | ||
539453717 20349702 615542081 378707948 |
539453717 20349702 615542081 378707948 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
Translation of [[Subtractive_generator#C|C]] via [[Subtractive_generator#D|D]] |
Translation of [[Subtractive_generator#C|C]] via [[Subtractive_generator#D|D]] |
||
{{works with|Java|8}} |
{{works with|Java|8}} |
||
< |
<syntaxhighlight lang="java">import java.util.function.IntSupplier; |
||
import static java.util.stream.IntStream.generate; |
import static java.util.stream.IntStream.generate; |
||
Line 1,051: | Line 1,051: | ||
.forEach(System.out::println); |
.forEach(System.out::println); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
<pre>467478574 |
<pre>467478574 |
||
Line 1,075: | Line 1,075: | ||
except insofar as a subfunction may call its parent (or grandparent, etc), |
except insofar as a subfunction may call its parent (or grandparent, etc), |
||
we have defined `subrand` as an accessible subfunction of `subrandSeed`. |
we have defined `subrand` as an accessible subfunction of `subrandSeed`. |
||
< |
<syntaxhighlight lang="jq"># If $p is null, then call `subrand`, |
||
# which sets .x as the PRN and which expects the the input to |
# which sets .x as the PRN and which expects the the input to |
||
# be the PRNG state, which is updated. |
# be the PRNG state, which is updated. |
||
Line 1,110: | Line 1,110: | ||
| foreach range(0; 10) as $i (.; |
| foreach range(0; 10) as $i (.; |
||
subrand; |
subrand; |
||
"r[\($i+220)] = \(.x)")</ |
"r[\($i+220)] = \(.x)")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,129: | Line 1,129: | ||
{{works with|Julia|1.0}} |
{{works with|Julia|1.0}} |
||
< |
<syntaxhighlight lang="julia">i,j,m,d,seed = 55,24,10^9,34,292929 # parameters |
||
s = Array{Int32}(undef,i); r = similar(s) |
s = Array{Int32}(undef,i); r = similar(s) |
||
s[1:2] = [seed,1] # table initialization |
s[1:2] = [seed,1] # table initialization |
||
Line 1,144: | Line 1,144: | ||
x = readline(stdin) # wait until the ENTER key is pressed |
x = readline(stdin) # wait until the ENTER key is pressed |
||
length(x) > 0 && break # any other key before ENTER => exit |
length(x) > 0 && break # any other key before ENTER => exit |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>(220, 467478574) |
<pre>(220, 467478574) |
||
Line 1,162: | Line 1,162: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="scala">// version 1.1.51 |
||
const val MOD = 1_000_000_000 |
const val MOD = 1_000_000_000 |
||
Line 1,201: | Line 1,201: | ||
subrandSeed(292_929) |
subrandSeed(292_929) |
||
for (i in 0..9) println("r[${i + 220}] = ${subrand()}") |
for (i in 0..9) println("r[${i + 220}] = ${subrand()}") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,218: | Line 1,218: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang="lua">function SubGen(seed) |
||
local n, r, s = 54, {}, { [0]=seed, 1 } |
local n, r, s = 54, {}, { [0]=seed, 1 } |
||
for n = 2,54 do s[n] = (s[n-2] - s[n-1]) % 1e9 end |
for n = 2,54 do s[n] = (s[n-2] - s[n-1]) % 1e9 end |
||
Line 1,231: | Line 1,231: | ||
end |
end |
||
subgen = SubGen(292929) |
subgen = SubGen(292929) |
||
for n = 220,229 do print(n,subgen()) end</ |
for n = 220,229 do print(n,subgen()) end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>220 467478574 |
<pre>220 467478574 |
||
Line 1,245: | Line 1,245: | ||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">initialize[n_] := |
||
Module[{buffer}, |
Module[{buffer}, |
||
buffer = |
buffer = |
||
Line 1,253: | Line 1,253: | ||
nextValue[buffer_] := |
nextValue[buffer_] := |
||
Flatten@{Rest@buffer, Mod[Subtract @@ buffer[[{1, 32}]], 10^9]}</ |
Flatten@{Rest@buffer, Mod[Subtract @@ buffer[[{1, 32}]], 10^9]}</syntaxhighlight> |
||
<pre>buffer = initialize[292929]; |
<pre>buffer = initialize[292929]; |
||
Line 1,272: | Line 1,272: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">import deques, sequtils |
||
template shfl(idx): untyped = (K*(idx+1)) mod I |
template shfl(idx): untyped = (K*(idx+1)) mod I |
||
Line 1,323: | Line 1,323: | ||
let rand = subGen(292929) |
let rand = subGen(292929) |
||
for _ in 1..3: |
for _ in 1..3: |
||
echo rand()</ |
echo rand()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>467478574 |
<pre>467478574 |
||
Line 1,332: | Line 1,332: | ||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="ocaml">let _mod = 1_000_000_000 |
||
let state = Array.create 55 0 |
let state = Array.create 55 0 |
||
let si = ref 0 |
let si = ref 0 |
||
Line 1,365: | Line 1,365: | ||
let () = |
let () = |
||
subrand_seed 292929; |
subrand_seed 292929; |
||
for i = 1 to 10 do Printf.printf "%d\n" (subrand()) done</ |
for i = 1 to 10 do Printf.printf "%d\n" (subrand()) done</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,382: | Line 1,382: | ||
=={{header|ooREXX}}== |
=={{header|ooREXX}}== |
||
{{trans|REXX}} |
{{trans|REXX}} |
||
< |
<syntaxhighlight lang="oorexx">/*REXX program uses a subtractive generaTor,and creates a sequence of ranDom numbers. */ |
||
/* array index must be positive! */ |
/* array index must be positive! */ |
||
s=.array~new |
s=.array~new |
||
Line 1,413: | Line 1,413: | ||
mod: Procedure |
mod: Procedure |
||
Parse Arg a,b |
Parse Arg a,b |
||
Return ((a//b)+b)//b </ |
Return ((a//b)+b)//b </syntaxhighlight> |
||
{{out|output|text= when using the default input:}} |
{{out|output|text= when using the default input:}} |
||
<pre>same as with REXX</pre> |
<pre>same as with REXX</pre> |
||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
< |
<syntaxhighlight 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</ |
sg()=sgv[sgi=sgi%55+1]=(sgv[sgi]-sgv[(sgi+30)%55+1])%10^9</syntaxhighlight> |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl">use 5.10.0; |
||
use strict; |
use strict; |
||
Line 1,447: | Line 1,447: | ||
bentley_clever(292929); |
bentley_clever(292929); |
||
say subrand() for (1 .. 10);</ |
say subrand() for (1 .. 10);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>467478574 |
<pre>467478574 |
||
Line 1,458: | Line 1,458: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
{{trans|C#}} |
{{trans|C#}} |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<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> |
<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: | Line 1,496: | ||
<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: #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> |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,506: | Line 1,506: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Using a circular list (as a true "ring" buffer). |
Using a circular list (as a true "ring" buffer). |
||
< |
<syntaxhighlight lang="picolisp">(setq |
||
*Bentley (apply circ (need 55)) |
*Bentley (apply circ (need 55)) |
||
*Bentley2 (nth *Bentley 32) ) |
*Bentley2 (nth *Bentley 32) ) |
||
Line 1,523: | Line 1,523: | ||
(when (lt0 (dec *Bentley (pop '*Bentley2))) |
(when (lt0 (dec *Bentley (pop '*Bentley2))) |
||
(inc *Bentley 1000000000) ) |
(inc *Bentley 1000000000) ) |
||
(pop '*Bentley) )</ |
(pop '*Bentley) )</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<syntaxhighlight lang="picolisp">(subRandSeed 292929) |
||
(do 7 (println (subRand)))</ |
(do 7 (println (subRand)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>467478574 |
<pre>467478574 |
||
Line 1,537: | Line 1,537: | ||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
<syntaxhighlight lang="pl/i"> |
|||
<lang PL/I> |
|||
subtractive_generator: procedure options (main); |
subtractive_generator: procedure options (main); |
||
Line 1,569: | Line 1,569: | ||
end subtractive_generator; |
end subtractive_generator; |
||
</syntaxhighlight> |
|||
</lang> |
|||
<pre> |
<pre> |
||
Required 3 results: |
Required 3 results: |
||
Line 1,597: | Line 1,597: | ||
The first 55 generated values are placed directly into their reordered slots in the ring. |
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. |
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 ) |
function Get-SubtractiveRandom ( [int]$Seed ) |
||
{ |
{ |
||
Line 1,644: | Line 1,644: | ||
Get-SubtractiveRandom |
Get-SubtractiveRandom |
||
Get-SubtractiveRandom |
Get-SubtractiveRandom |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,658: | Line 1,658: | ||
Uses collections.deque as a ring buffer |
Uses collections.deque as a ring buffer |
||
< |
<syntaxhighlight lang="python"> |
||
import collections |
import collections |
||
s= collections.deque(maxlen=55) |
s= collections.deque(maxlen=55) |
||
Line 1,701: | Line 1,701: | ||
for i in xrange(5): |
for i in xrange(5): |
||
print "result = ", getnextr() |
print "result = ", getnextr() |
||
</syntaxhighlight> |
|||
</lang> |
|||
===Python: As a class within a module=== |
===Python: As a class within a module=== |
||
Python 2 and 3 compatable. |
Python 2 and 3 compatable. |
||
< |
<syntaxhighlight lang="python">import collections |
||
_ten2nine = 10**9 |
_ten2nine = 10**9 |
||
Line 1,727: | Line 1,727: | ||
if __name__ == '__main__': |
if __name__ == '__main__': |
||
srand = Subtractive_generator() |
srand = Subtractive_generator() |
||
print([srand() for i in range(5)])</ |
print([srand() for i in range(5)])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,733: | Line 1,733: | ||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket">#lang racket |
||
(define (make-initial-state a-list max-i) |
(define (make-initial-state a-list max-i) |
||
(for/fold ((state a-list)) |
(for/fold ((state a-list)) |
||
Line 1,762: | Line 1,762: | ||
;that returns a new random number each time it's called |
;that returns a new random number each time it's called |
||
(define rand (create-substractive-generator 292929)) |
(define rand (create-substractive-generator 292929)) |
||
(build-list 3 (lambda (_) (rand))) ;returns a list made from the 3 wanted numbers</ |
(build-list 3 (lambda (_) (rand))) ;returns a list made from the 3 wanted numbers</syntaxhighlight> |
||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
Line 1,769: | Line 1,769: | ||
{{works with|Rakudo|2018.03}} |
{{works with|Rakudo|2018.03}} |
||
<lang |
<syntaxhighlight lang="raku" line>sub bentley-clever($seed) { |
||
constant $mod = 1_000_000_000; |
constant $mod = 1_000_000_000; |
||
my @seeds = ($seed % $mod, 1, (* - *) % $mod ... *)[^55]; |
my @seeds = ($seed % $mod, 1, (* - *) % $mod ... *)[^55]; |
||
Line 1,785: | Line 1,785: | ||
my @sr = bentley-clever(292929); |
my @sr = bentley-clever(292929); |
||
.say for @sr[^10];</ |
.say for @sr[^10];</syntaxhighlight> |
||
Here we just make the seeder return the random sequence as a lazy list. |
Here we just make the seeder return the random sequence as a lazy list. |
||
Line 1,804: | Line 1,804: | ||
Some optimization was done so that the first two '''do''' loops executed faster. |
Some optimization was done so that the first two '''do''' loops executed faster. |
||
< |
<syntaxhighlight lang="rexx">/*REXX program uses a subtractive generator, and creates a sequence of random numbers. */ |
||
s.0= 292929; s.1= 1; billion= 1e9 |
s.0= 292929; s.1= 1; billion= 1e9 |
||
numeric digits 20 |
numeric digits 20 |
||
Line 1,825: | Line 1,825: | ||
mod: procedure; parse arg a,b; return ( (a // b) + b) // b |
mod: procedure; parse arg a,b; return ( (a // b) + b) // b |
||
r: parse arg #; return r.# |
r: parse arg #; return r.# |
||
s: parse arg #; return s.#</ |
s: parse arg #; return s.#</syntaxhighlight> |
||
{{out|output|text= when using the default input:}} |
{{out|output|text= when using the default input:}} |
||
<pre> |
<pre> |
||
Line 1,849: | Line 1,849: | ||
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. |
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. |
||
< |
<syntaxhighlight lang="ruby"># SubRandom is a subtractive random number generator which generates |
||
# the same sequences as Bentley's generator, as used in xpat2. |
# the same sequences as Bentley's generator, as used in xpat2. |
||
class SubRandom |
class SubRandom |
||
Line 1,885: | Line 1,885: | ||
rng = SubRandom.new(292929) |
rng = SubRandom.new(292929) |
||
p (1..3).map { rng.rand }</ |
p (1..3).map { rng.rand }</syntaxhighlight> |
||
<pre>[467478574, 512932792, 539453717]</pre> |
<pre>[467478574, 512932792, 539453717]</pre> |
||
Line 1,893: | Line 1,893: | ||
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>. |
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. |
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 |
/// m in the formula |
||
modulo: i32, |
modulo: i32, |
||
Line 1,977: | Line 1,977: | ||
println!("{}", n); |
println!("{}", n); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
<pre>467478574 |
<pre>467478574 |
||
512932792 |
512932792 |
||
Line 1,985: | Line 1,985: | ||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
< |
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i"; |
||
const integer: MOD is 1000000000; |
const integer: MOD is 1000000000; |
||
Line 2,038: | Line 2,038: | ||
writeln(subrand(gen)); |
writeln(subrand(gen)); |
||
end for; |
end for; |
||
end func;</ |
end func;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,055: | Line 2,055: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">class SubRandom(seed, state=[]) { |
||
const mod = 1_000_000_000; |
const mod = 1_000_000_000; |
||
Line 2,076: | Line 2,076: | ||
var r = SubRandom(292929); |
var r = SubRandom(292929); |
||
10.times { say r.subrand };</ |
10.times { say r.subrand };</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,093: | Line 2,093: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.5 |
||
namespace eval subrand { |
namespace eval subrand { |
||
variable mod 1000000000 state [lrepeat 55 0] si 0 sj 0 |
variable mod 1000000000 state [lrepeat 55 0] si 0 sj 0 |
||
Line 2,127: | Line 2,127: | ||
for {set i 0} {$i < 10} {incr i} { |
for {set i 0} {$i < 10} {incr i} { |
||
puts [subrand::gen] |
puts [subrand::gen] |
||
}</ |
}</syntaxhighlight> |
||
=={{header|uBasic/4tH}}== |
=={{header|uBasic/4tH}}== |
||
<lang>Push 292929 : Gosub 100 : d = Pop() |
<syntaxhighlight lang="text">Push 292929 : Gosub 100 : d = Pop() |
||
For i = 1 To 10 |
For i = 1 To 10 |
||
Line 2,164: | Line 2,164: | ||
Next |
Next |
||
Push 0 : Return</ |
Push 0 : Return</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>467478574 |
<pre>467478574 |
||
Line 2,182: | Line 2,182: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="ecmascript">var mod = 1e9 |
||
var state = List.filled(55, 0) |
var state = List.filled(55, 0) |
||
var si = 0 |
var si = 0 |
||
Line 2,217: | Line 2,217: | ||
subrandSeed.call(292929) |
subrandSeed.call(292929) |
||
for (i in 0..9) System.print("r[%(i+220)] = %(subrand.call())")</ |
for (i in 0..9) System.print("r[%(i+220)] = %(subrand.call())")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,237: | Line 2,237: | ||
{{trans|Python}} |
{{trans|Python}} |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="zkl">fcn rand_sub(x){ |
||
var ring=L(),m=(1e9).toInt(); |
var ring=L(),m=(1e9).toInt(); |
||
mod:='wrap(n){ if(n<0) n+m else n }; |
mod:='wrap(n){ if(n<0) n+m else n }; |
||
Line 2,248: | Line 2,248: | ||
ring.append((ring.pop(0)-ring[-24]):mod(_)); |
ring.append((ring.pop(0)-ring[-24]):mod(_)); |
||
return(ring[-1]); |
return(ring[-1]); |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">do(4){ println(rand_sub(292929)) } //seed ignored after first call</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |