Jump to content

Subtractive generator: Difference between revisions

m
syntax highlighting fixup automation
m (syntax highlighting fixup automation)
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 189:
=={{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:
IF FNsubrand(0)
NEXT
= 0</langsyntaxhighlight>
{{out}}
<pre>
Line 232:
This is a translation of the C example.
 
<langsyntaxhighlight lang="bracmat">1000000000:?MOD;
tbl$(state,55);
0:?si:?sj;
Line 283:
));
 
Main$;</langsyntaxhighlight>
 
{{out}}
Line 299:
=={{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:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">
public class SubtractiveGenerator {
public static int MAX = 1000000000;
Line 384:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 402:
=={{header|C++}}==
{{libheader|Boost}}
<langsyntaxhighlight lang="cpp">
// written for clarity not efficiency.
 
Line 466:
return 0;
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 480:
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(defn xpat2-with-seed
"produces an xpat2 function initialized from seed"
[seed]
Line 502:
 
(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:
;; 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:
foreach (i; 0 .. 10)
writeln(gen.subrand());
}</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 597:
 
=={{header|dc}}==
<langsyntaxhighlight lang="dc">[*
* (seed) lsx --
* Seeds the subtractive generator.
Line 648:
lrx psz
lrx psz
lrx psz</langsyntaxhighlight>
 
This program prints 467478574, 512932792, 539453717.
Line 656:
=={{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:
 
Subtractive.new(292929)
for _ <- 1..10, do: IO.puts Subtractive.rand</langsyntaxhighlight>
 
{{out}}
Line 693:
=={{header|F_Sharp|F#}}==
<p>Similar to Haskell, using lazy evaluation.</p>
<langsyntaxhighlight lang="fsharp">[<EntryPoint>]
let main argv =
let m = 1000000000
Line 707:
r |> Seq.skip 220 |> Seq.take 3
|> Seq.iter (printfn "%d")
0</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 715:
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">module subgenerator
implicit none
 
Line 770:
end do
end program</langsyntaxhighlight>
{{out}}
<pre>
Line 786:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 885:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 894:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">subtractgen :: Int -> [Int]
subtractgen seed = drop 220 out
where
Line 905:
 
main :: IO ()
main = mapM_ print $ take 10 $ subtractgen 292929</langsyntaxhighlight>
{{out}}
<pre>
Line 921:
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">procedure main()
every 1 to 10 do
write(rand_sub(292929))
Line 946:
put(ring,get(ring))
return ring[-1]
end</langsyntaxhighlight>
 
{{out}}
Line 967:
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:
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:
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:
.forEach(System.out::println);
}
}</langsyntaxhighlight>
 
<pre>467478574
Line 1,075:
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:
| foreach range(0; 10) as $i (.;
subrand;
"r[\($i+220)] = \(.x)")</langsyntaxhighlight>
{{out}}
<pre>
Line 1,129:
{{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:
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:
=={{header|Kotlin}}==
{{trans|C}}
<langsyntaxhighlight lang="scala">// version 1.1.51
 
const val MOD = 1_000_000_000
Line 1,201:
subrandSeed(292_929)
for (i in 0..9) println("r[${i + 220}] = ${subrand()}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,218:
 
=={{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:
end
subgen = SubGen(292929)
for n = 220,229 do print(n,subgen()) end</langsyntaxhighlight>
{{out}}
<pre>220 467478574
Line 1,245:
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">initialize[n_] :=
Module[{buffer},
buffer =
Line 1,253:
nextValue[buffer_] :=
Flatten@{Rest@buffer, Mod[Subtract @@ buffer[[{1, 32}]], 10^9]}</langsyntaxhighlight>
 
<pre>buffer = initialize[292929];
Line 1,272:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import deques, sequtils
 
template shfl(idx): untyped = (K*(idx+1)) mod I
Line 1,323:
let rand = subGen(292929)
for _ in 1..3:
echo rand()</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 1,332:
{{trans|C}}
 
<langsyntaxhighlight lang="ocaml">let _mod = 1_000_000_000
let state = Array.create 55 0
let si = ref 0
Line 1,365:
let () =
subrand_seed 292929;
for i = 1 to 10 do Printf.printf "%d\n" (subrand()) done</langsyntaxhighlight>
 
{{out}}
Line 1,382:
=={{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:
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:
 
bentley_clever(292929);
say subrand() for (1 .. 10);</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 1,458:
=={{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:
<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:
=={{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:
(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:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
subtractive_generator: procedure options (main);
 
Line 1,569:
 
end subtractive_generator;
</syntaxhighlight>
</lang>
<pre>
Required 3 results:
Line 1,597:
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:
Get-SubtractiveRandom
Get-SubtractiveRandom
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,658:
Uses collections.deque as a ring buffer
 
<langsyntaxhighlight lang="python">
import collections
s= collections.deque(maxlen=55)
Line 1,701:
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:
if __name__ == '__main__':
srand = Subtractive_generator()
print([srand() for i in range(5)])</langsyntaxhighlight>
 
{{out}}
Line 1,733:
 
=={{header|Racket}}==
<langsyntaxhighlight Racketlang="racket">#lang racket
(define (make-initial-state a-list max-i)
(for/fold ((state a-list))
Line 1,762:
;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:
{{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:
 
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:
 
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:
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,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.
 
<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:
 
rng = SubRandom.new(292929)
p (1..3).map { rng.rand }</langsyntaxhighlight>
 
<pre>[467478574, 512932792, 539453717]</pre>
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>.
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:
println!("{}", n);
}
}</langsyntaxhighlight>
<pre>467478574
512932792
Line 1,985:
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const integer: MOD is 1000000000;
Line 2,038:
writeln(subrand(gen));
end for;
end func;</langsyntaxhighlight>
 
{{out}}
Line 2,055:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">class SubRandom(seed, state=[]) {
 
const mod = 1_000_000_000;
Line 2,076:
 
var r = SubRandom(292929);
10.times { say r.subrand };</langsyntaxhighlight>
{{out}}
<pre>
Line 2,093:
=={{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:
for {set i 0} {$i < 10} {incr i} {
puts [subrand::gen]
}</langsyntaxhighlight>
 
=={{header|uBasic/4tH}}==
<syntaxhighlight lang="text">Push 292929 : Gosub 100 : d = Pop()
 
For i = 1 To 10
Line 2,164:
Next
 
Push 0 : Return</langsyntaxhighlight>
{{out}}
<pre>467478574
Line 2,182:
=={{header|Wren}}==
{{trans|C}}
<langsyntaxhighlight lang="ecmascript">var mod = 1e9
var state = List.filled(55, 0)
var si = 0
Line 2,217:
 
subrandSeed.call(292929)
for (i in 0..9) System.print("r[%(i+220)] = %(subrand.call())")</langsyntaxhighlight>
 
{{out}}
Line 2,237:
{{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:
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>
10,333

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.