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: | 768 / 1043 | 
| Version history: | 39 change(s) | 
| Referenced in: | [show references] |