package kjv // MT19937 seeded with init_by_array from one integer, and a choice made by // rejection sampling over its bits, so the verse of the day for any given date // never changes. type mtRandom struct { mt [624]uint32 idx int } func newMTRandom(seed uint32) *mtRandom { r := &mtRandom{} r.initGenrand(19650218) key := []uint32{seed} i, j := 1, 0 k := max(624, len(key)) for ; k > 0; k-- { r.mt[i] = (r.mt[i] ^ ((r.mt[i-1] ^ (r.mt[i-1] >> 30)) * 1664525)) + key[j] + uint32(j) i++ j++ if i >= 624 { r.mt[0] = r.mt[623] i = 1 } if j >= len(key) { j = 0 } } for k = 623; k > 0; k-- { r.mt[i] = (r.mt[i] ^ ((r.mt[i-1] ^ (r.mt[i-1] >> 30)) * 1566083941)) - uint32(i) i++ if i >= 624 { r.mt[0] = r.mt[623] i = 1 } } r.mt[0] = 0x80000000 r.idx = 624 return r } func (r *mtRandom) initGenrand(s uint32) { r.mt[0] = s for i := 1; i < 624; i++ { r.mt[i] = 1812433253*(r.mt[i-1]^(r.mt[i-1]>>30)) + uint32(i) } r.idx = 624 } func (r *mtRandom) next() uint32 { if r.idx >= 624 { for k := 0; k < 624; k++ { y := (r.mt[k] & 0x80000000) | (r.mt[(k+1)%624] & 0x7fffffff) v := r.mt[(k+397)%624] ^ (y >> 1) if y&1 != 0 { v ^= 0x9908b0df } r.mt[k] = v } r.idx = 0 } y := r.mt[r.idx] r.idx++ y ^= y >> 11 y ^= (y << 7) & 0x9d2c5680 y ^= (y << 15) & 0xefc60000 y ^= y >> 18 return y } // choiceIndex is random.choice's _randbelow(n) for n < 2**32. func (r *mtRandom) choiceIndex(n int) int { if n <= 0 { return 0 } k := 0 for v := n; v > 0; v >>= 1 { k++ } for { if x := int(r.next() >> (32 - k)); x < n { return x } } }