Transpiled version (9372L) is out of date.
1 | // Deterministic shuffled list iterator using an XORSHIFT RNG |
2 | // Each step is O(1), iterator is OSPACE(1) |
3 | |
4 | // This iterator doesn't have a seed parameter and is completely |
5 | // deterministic with respect to a given list size. |
6 | // If you want to pass a seed, use WeightlessShuffledIteratorWithSeed. |
7 | |
8 | // Performance: Takes between 5 and 18 ns per nextIndex() on a laptop |
9 | // and between 2 and 11 ns on a desktop CPU. |
10 | // (these numbers are actually for WeightlessShuffledIteratorWithSeed, |
11 | // WeightlessShuffledIterator itself is a tiny bit faster.) |
12 | |
13 | sclass WeightlessShuffledIterator<A> extends ItIt<A> is IndexIterator { |
14 | final L<A> list; |
15 | final int n; |
16 | final int bits, cycleLength, a, b, c; |
17 | |
18 | int i; // step counter |
19 | |
20 | // now doing the TripletLSFR stuff directly in here |
21 | int value; |
22 | |
23 | // initialize only with a length (i.e. list containing 0, 1, ...) |
24 | // if you are going to be calling nextIndex() instead of next() |
25 | *(int n) { |
26 | this((L) iotaZeroList(n)); |
27 | } |
28 | |
29 | // initialize with a list to shuffle |
30 | *(L<A> *list) { |
31 | n = l(list); |
32 | if (n == 0) ret with a = b = c = bits = cycleLength = 0; |
33 | bits = numberOfBitsNeededToRepresentNOptions(n+1); |
34 | var lsfr = new TripletLSFR(bits); |
35 | meta-for a also as b, c, value, cycleLength { a = lsfr.a; } |
36 | } |
37 | |
38 | public bool hasNext() { ret i < n; } |
39 | |
40 | public A next() { |
41 | ret list.get(nextIndex()); |
42 | } |
43 | |
44 | // you can call nextIndex() without having checked hasNext(), |
45 | // then it will just return -1 when the iteration is complete. |
46 | public int nextIndex() { |
47 | if (i >= n) ret -1; |
48 | ++i; |
49 | |
50 | int raw; |
51 | do { |
52 | int x = value; |
53 | x ^= (x << a) & cycleLength; |
54 | x ^= x >>> b; |
55 | x ^= (x << c) & cycleLength; |
56 | value = x; |
57 | raw = postProcessLSFRValue(x-1); |
58 | } while (raw >= n); |
59 | |
60 | ret raw; |
61 | }; |
62 | |
63 | int bits() { ret bits; } |
64 | |
65 | // overridable in subclasses |
66 | int postProcessLSFRValue(int i) { ret i; } |
67 | } |
Began life as a copy of #1017660
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1035206 |
Snippet name: | WeightlessShuffledIterator - iterate over list in random order using an LSFR (iterator is OSPACE(1)) |
Eternal ID of this version: | #1035206/40 |
Text MD5: | f880683492c99eaecdfe76ee643642db |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2023-02-12 14:31:28 |
Source code size: | 2019 bytes / 67 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 293 / 531 |
Version history: | 39 change(s) |
Referenced in: | [show references] |