// This is an LFSR (aka the XORSHIFT algorithm) which is a deterministic, // very fast random number generator cycling through all integers // between 1 and 2^n-1 (incl.). sclass TripletLSFR { // params int n; int value = 1; // start value, but is also changed during execution int a, b, c; // the triplet // calculated gettable int cycleLength; // changing variables int step; // triplets table for n's from 1 to 31 // (just the first triple that gives a full cycle, including degenerate ones, // so not optimized for "randomness") static final int[][] tripletsTable = { { 0, 0, 0 }, { 0, 1, 1 }, { 0, 1, 1 }, { 0, 1, 3 }, { 0, 1, 1 }, { 0, 1, 1 }, { 0, 1, 3 }, { 1, 1, 2 }, { 0, 1, 1 }, { 0, 3, 7 }, { 0, 1, 1 }, { 1, 1, 4 }, { 0, 1, 6 }, { 0, 1, 1 }, { 0, 1, 4 }, { 1, 1, 14 }, { 0, 3, 7 }, { 1, 3, 14 }, { 0, 1, 3 }, { 1, 5, 6 }, { 0, 1, 6 }, { 0, 1, 21 }, { 0, 1, 1 }, { 1, 5, 18 }, { 0, 1, 12 }, { 0, 1, 1 }, { 0, 2, 7 }, { 0, 3, 25 }, { 0, 1, 1 }, { 0, 1, 1 }, { 0, 3, 28 } }; *(int *n) { if (n < 1 || n > tripletsTable.length) fail("Don't have triples for " + nBits(n)); init(tripletsTable[n-1]); } *(int *n, int a, int b, int c) { init(a, b, c); } void init(int[] triplet) { init(triplet[0], triplet[1], triplet[2]); } void init(int a, int b, int c) { // handle triplets with 0s (meaning to skip one of the 3 xorshifts) meta-for a in a, b, c { this.a = a == 0 ? n : a; } cycleLength = (1 << n)-1; } int next() { step++; int x = value; x ^= (x << a) & cycleLength; x ^= x >>> b; x ^= (x << c) & cycleLength; ret value = x; } bool cycleComplete() { ret step >= cycleLength(); } // takes any integer selfType start aka value(int start) { value = mod(start, cycleLength)+1; this; } }