RosettaCodeData/Task/Subtractive-generator/Dc/subtractive-generator.dc
2017-09-25 22:28:19 +02:00

52 lines
1.5 KiB
Text

[*
* (seed) lsx --
* Seeds the subtractive generator.
* Uses register R to hold the state.
*]sz
[
[* Fill ring buffer R[0] to R[54]. *]sz
d 54:R SA [A = R[54] = seed]sz
1 d 33:R SB [B = R[33] = 1]sz
12 SC [C = index 12, into array R.]sz
[55 -]SI
[ [Loop until C is 54:]sz
lA lB - d lC:R [R[C] = A - B]sz
lB sA sB [Parallel let A = B and B = A - B]sz
lC 34 + d 55 !>I d sC [C += 34 (mod 55)]sz
54 !=L
]d SL x
[* Point R[55] and R[56] into ring buffer. *]sz
0 55:R [R[55] = index 0, of 55th last number.]sz
31 56:R [R[56] = index 31, of 24th last number.]sz
[* Stir ring buffer. *]sz
165 [ [Loop 165 times:]sz
55;R;R 56;R;R - 55;R:R [Discard a random number.]sz
55;R 1 + d 55 !>I 55:R [R[55] += 1 (mod 55)]sz
56;R 1 + d 55 !>I 56:R [R[56] += 1 (mod 55)]sz
1 - d 0 <L
]d sL x
LAsz LBsz LCsz LIsz LLsz
]ss
[*
* lrx -- (random number from 0 to 10^9 - 1)
* Returns the next number from the subtractive generator.
* Uses register R, seeded by lsx.
*]sz
[
55;R;R 56;R;R - [R[R[55]] - R[R[56]] is next random number.]sz
d 55;R:R [Put it in R[R[55]]. Also leave it on stack.]sz
[55 -]SI
55;R 1 + d 55 !>I 55:R [R[55] += 1 (mod 55)]sz
56;R 1 + d 55 !>I 56:R [R[56] += 1 (mod 55)]sz
[1000000000 +]sI
1000000000 % d 0 >I [Random number = it (mod 10^9)]sz
LIsz
]sr
[* Seed with 292929 and print first three random numbers. *]sz
292929 lsx
lrx psz
lrx psz
lrx psz