Created
July 31, 2022 02:09
-
-
Save HonmaMasaru/957447b8d71b72a02d67ad63e050fa64 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
// XORShiftのRandomNumberGenerator | |
// 参考: https://ja.wikipedia.org/wiki/Xorshift | |
struct XORShift: RandomNumberGenerator { | |
private var y: UInt64 | |
init(seed: UInt64 = 2463534242) { | |
y = seed > 0 ? seed : 2463534242 | |
next() | |
} | |
mutating func next() -> UInt64 { | |
y = y ^ (y << 13) | |
y = y ^ (y >> 17) | |
y = y ^ (y << 5) | |
return y | |
} | |
} | |
struct XORShift64: RandomNumberGenerator { | |
private var x: UInt64 | |
init(seed: UInt64 = 88172645463325252) { | |
x = seed > 0 ? seed : 88172645463325252 | |
next() | |
} | |
mutating func next() -> UInt64 { | |
x = x ^ (x << 13) | |
x = x ^ (x >> 7) | |
x = x ^ (x << 17) | |
return x | |
} | |
} | |
struct XORShift96: RandomNumberGenerator { | |
private var x: UInt64 | |
private var y: UInt64 = 362436069 | |
private var z: UInt64 = 521288629 | |
init(seed: UInt64 = 123456789) { | |
x = seed > 0 ? seed : 123456789 | |
next() | |
} | |
mutating func next() -> UInt64 { | |
let t = (x ^ (x << 3)) ^ (y ^ (y >> 19)) ^ (z ^ (z << 6)) | |
x = y | |
y = z | |
z = t | |
return z | |
} | |
} | |
struct XORShift128: RandomNumberGenerator { | |
private var x: UInt64 | |
private var y: UInt64 = 362436069 | |
private var z: UInt64 = 521288629 | |
private var w: UInt64 = 88675123 | |
init(seed: UInt64 = 123456789) { | |
x = seed > 0 ? seed : 123456789 | |
next() | |
} | |
mutating func next() -> UInt64 { | |
let t = x ^ (x << 11) | |
x = y | |
y = z | |
z = w | |
w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)) | |
return w | |
} | |
} | |
// テスト | |
var stack: [Bool] = [] | |
//var xor = XORShift(seed: UInt64(Date().timeIntervalSince1970)) | |
var xor = XORShift(seed: 111111111111111111) | |
(0..<100).forEach { _ in | |
if Int.random(in: 0..<10000, using: &xor) < 1000 { | |
stack.append(true) | |
} else { | |
stack.append(false) | |
} | |
} | |
print(stack.map { "\($0)" }.joined(separator: ", ")) | |
let counter = NSCountedSet(array: stack) | |
print("t: \(counter.count(for: true)), f: \(counter.count(for: false))") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment