Which is equivalent to random seeding in Swift3 (Xcode8 beta 1)

I need to run the same list of random numbers for every execution of my application. srand / rand no longer exists. What should I do then?

private extension Array { private func randomValues(_ seed: UInt32, num: Int) -> [Element] { srand (seed) var indices = [Int]() indices.reserveCapacity(num) let range = 0..<self.count for _ in 0..<num { var random = 0 repeat { random = randomNumberInRange(range) } while indices.contains(random) indices.append(random) } return indices.map { self[$0] } } 
+6
source share
5 answers

You can use srand48 (seed) and drand48 () in Swift3.

+8
source

If you are not developing Swift for platforms other than Apple, you can get a much better randomization API in GameplayKit: several algorithms (trading randomness and speed), seeding, distribution, etc.

+5
source

I can’t find a way to use random crops in Swift 3 Beta 1. I had to write a dumb wrapper function in C:

 // ---------------------------------------------- // my_random.h // ---------------------------------------------- #ifndef my_random_h #define my_random_h #include <stdio.h> #endif /* my_random_h */ long next_random(); // ---------------------------------------------- // my_random.c // ---------------------------------------------- #include <stdlib.h> #include "my_random.h" long next_random() { return random(); } 

You can use the bridge title to import it into Swift. Then you can call it in Swift as follows:

 srandom(42) for _ in 0..<10 { let x = next_random() print(x) } 

random better than rand . Read the man pages for a discussion of these two features.


Edit:

The workaround, as @riskter suggested, is to use GameKit:

 import GameKit let seed = Data(bytes: [42]) // Use any array of [UInt8] let source = GKARC4RandomSource(seed: seed) for _ in 0..<10 { let x = source.nextInt() print(x) } 
+2
source

For a simple repeatable random list, try using a linear congruent generator:

 import Foundation class LinearCongruntialGenerator { var state = 0 //seed of 0 by default let a, c, m, shift: Int //we will use microsoft random by default init() { self.a = 214013 self.c = 2531011 self.m = Int(pow(2.0, 31.0)) //2^31 or 2147483648 self.shift = 16 } init(a: Int, c: Int, m: Int, shift: Int) { self.a = a self.c = c self.m = m //2^31 or 2147483648 self.shift = shift } func seed(seed: Int) -> Void { state = seed; } func random() -> Int { state = (a * state + c) % m return state >> shift } } let microsoftLinearCongruntialGenerator = LinearCongruntialGenerator() print("Microsft Rand:") for i in 0...10 { print(microsoftLinearCongruntialGenerator.random()) } 

More details here: https://rosettacode.org/wiki/Linear_congruential_generator

0
source

I just happened to collect this for Swift 4. I know that in Swift 4.2 there are new random extensions that differ from this, but like the OP, I needed them to be seeded during testing. Maybe someone will find this useful. If you do not fill it, it will use arc4random, otherwise it will use drand48. This avoids the bias of the mods in both directions.

 import Foundation class Random { static var number = unseededGenerator // the current generator /** * returns a random Int 0..<n **/ func get(anIntLessThan n: Int) -> Int { return generatingFunction(n) } class func set(seed: Int) { number = seedableGenerator srand48(seed) } // Don't normally need to call the rest typealias GeneratingFunction = (Int) -> Int static let unseededGenerator = Random(){ Int(arc4random_uniform(UInt32($0))) } static let seedableGenerator = Random(){ Int(drand48() * Double($0)) } init(_ gf: @escaping GeneratingFunction) { self.generatingFunction = gf } private let generatingFunction: GeneratingFunction } func randomTest() { Random.set(seed: 65) // comment this line out for unseeded for _ in 0..<10 { print( Random.number.get(anIntLessThan: 2), terminator: " " ) } } // Run randomTest() 
0
source

All Articles