I need to start the same random number list over every execution of my app.
srand/rand do not exist anymore. 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] }
}
You can use
srand48(seed) and drand48() in Swift3.
Unless you're developing with Swift for non-Apple platforms, you can get a much better randomization API in GameplayKit: several algorithms (trade randomness vs speed), seedable, distribution control, etc.
I can't find a way to use seeded random in Swift 3 Beta 1. Had to write a silly 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 bridging header to import it into Swift. Then you can call it in Swift like this:
srandom(42)
for _ in 0..<10 {
let x = next_random()
print(x)
}
random is better than rand. Read the man pages for discussion on these 2 functions.
Edit:
A 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)
}
For a simple repeatable random list try using a Linear Congruential 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 info here:
https://rosettacode.org/wiki/Linear_congruential_generator
I just happened to put this together for Swift 4. I am aware Swift 4.2 has new random extensions that are different from this, but like the OP, I needed them to be seedable during testing. Maybe someone will find it helpful. If you don't seed it, it will use arc4random, otherwise it will use drand48. It avoids mod bias both ways.
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()
Related
I am trying to solve the following coding challenge:
Given a positive number n > 1 find the prime factor decomposition of n. The result will be a string with the following form:
"(p1xxn1)(p2xxn2)...(pkxxnk)"
with the p(i) in increasing order and n(i) empty if n(i) is 1.
Example: n = 86240 should return "(2xx5)(5)(7xx2)(11)"
I believe I have figured out how to find the prime factors of a number... my problem is that I have no idea how to convert them into the form required by the question (i.e., a string where p(i) is in increasing order). I tried to convert an integer array containing the prime factors into some sort of array of tuples containing factors p and n, but I have been struggling fruitlessly for several hours.
Here is what I have so far:
func factors(_ number: Int) -> String {
var changedNumber = number
var numberArr = [Int]()
while changedNumber >= 2 {
for i in 2...changedNumber {
if changedNumber % i == 0 {
numberArr.append(i)
changedNumber /= i
break
}
}
}
}
Any insight or resources would be greatly appreciated.
func factors(_ number: Int) -> String
I think it’s a mistake to make this return the String directly. It violates the separation of responsibilities, and makes this hard to reuse.
Imagine elsewhere in a codebase that uses this function, there might be a function which tries to parse the string result of this back into an array to use it in some other way. It may sound ridiculous, but a large number of the questions we get on here are about people trying to build systems to accept silly input from other systems that they should just change instead!
Here's what I would suggest:
func primeFactorization(of value: Int) -> (factor: Int, exponent: Int) {
...
}
func format(_ primeFactors: [(factor: Int, exponent: Int)]) -> String {
return primeFactors
.map { $0.exponent == 1 ? "(\($0.factor))" : "(\($0.factor)xx\($0.exponent))" }
.joined()
}
So you can then do:
let factorization = primeFactorization(of: 86240)
// Which results in: [
// (factor: 2, exponent: 5),
// (factor: 2, exponent: 1),
// (factor: 7, exponent: 2),
// (factor: 11, exponent: 1),
// ]
// Which you can then format as this one question wants:
format(factorization) // => "(2xx5)(5)(7xx2)(11)"
For extra points, you could generify the first function into an extension on BinaryInteger, which would let you be able to write something like 86240.primeFactorization().
Just make your function group the numbers and then use each sub collection count when creating your string:
func factors(_ number: Int) -> String {
var changedNumber = number
var numberArr: [[Int]] = []
while changedNumber >= 2 {
for i in 2...changedNumber {
if changedNumber.isMultiple(of: i) {
if numberArr.last?.last == i {
numberArr[numberArr.count-1].append(i)
} else {
numberArr.append([i])
}
changedNumber /= i
break
}
}
}
return numberArr.reduce(into: "") {
if let last = $1.last {
if $1.count == 1 {
$0 += "(" + String(last) + ")"
} else {
$0 += "(" + String(last) + "xx\($1.count))"
}
}
}
}
print(factors(86240)) // (2xx5)(5)(7xx2)(11)
There's lots of ways to handle this. Here's one, off the top of my head:
Write an extension to Int that has the following functions
func isPrime() -> Bool
func nextPrime() -> Int.
First check to see if the input number n is prime. If it is, return the result as "(nxxx1)" and you're done.
Define a struct primeFactor:
struct PrimeFactor {
let value: Int
var count: Int
}
Create an array of PrimeFactors.
func primeFactorsString(of value: String) -> String {
var primeFactors = [PrimeFactor]()
var currentPrime = 1
var remainder = value
guard !value.isPrime() else { return "(\(value)xx1)" }
while remainder > 1 {
currentPrime = currentPrime.nextPrime()
if remainder % currentPrime == 0 {
let newPrimeFactor = PrimeFactor(value: currentPrime, count: 1)
remainder /= currentPrime
while remainder % currentPrime == 0 {
newPrimeFactor.count = newPrimeFactor.count + 1
remainder /= currentPrime
}
primeFactors.append(newPrimeFactor)
}
}
// Now loop through your array of primeFactors and build your output string.
return primeFactors.map { "(\($0.value)xx\($0.count))".joined()
I started this question for the purpose of asking it, but upon research I found an answer, so I compiled the answer here to share. Please let me know if it can be improved or if I have any errors.
I made an array of dictionaries where a 'tuple' (fake tuple, actually a class) is the key and a bool is the value.
I wanted something to this effect:
var dict = [(Int, Int): Bool]()
var pointDictionaryArray = [dict]()
of better compressed:
var pointDictionaryArray = [[(Int, Int): Bool]]()
However, upon research, I can't use a tuple as a key, because it's not hashable, but it seems that I can use a struct or class instead.
There is a very thorough answer given, but it was a bit confusing for me, so I'm sharing what I learned from it in a simplified manner for others.
// have an array of dictionaries with a tuple of the x,y being the key and a boolean being the value for each pixel array
class TupleClass: Hashable {
var x: Int!
var y: Int!
init(newX: Int, newY: Int) {
x = newX
y = newY
}
// required for the Hashable protocol
var hashValue: Int {
return x * y + y
}
}
// required function for the Equatable protocol, which Hashable inherits from
func ==(left: TupleStruct, right: TupleStruct) -> Bool {
return (left.x == right.x) && (left.y == right.y)
}
var pointDictionaryArray = [[TupleClass: Bool]]()
Assigning data example:
I'm using it to sort data from pixels similarly to this.
for i in 0..<image.count {
...
for j in 0..<imageWidth {
for k in 0..<imageHeight {
...
tempTuple = TupleClass(j, k)
...
if (/*pixel is white */) {
(pointDictionaryArray[i])[tempTuple] = true
} else {
(pointDictionaryArray[i])[tempTuple] = false
}
...
}
}
...
}
Retrieving data example:
for var i = 0; i < pointDictionaryArray.count; i++ {
for var j = 0; j < imageWidth; j++ {
for var k = 0; k < imageHeight; k++ {
let tempTuple = TupleClass(newX: j, newY: k)
// check to see if there is a key-value pair for the tempTuple used
if let temp = pointDictionaryArray[i][tempTuple] {
if temp {
print("true")
} else {
print("false")
}
}
}
}
}
Again, if I made any errors or if there are improvements to be made, let me know in the comments and I'll do my best to fix it.
This is what I'd like to do, but quantity property isn't available.
struct MyStruct {
var quantity: Int
let valueFn: () -> (Int)
}
var s1 = MyStruct(quantity: 2) { () -> (Int) in
return quantity * 2 // error: can't use `quantity`
}
It doesn't work with classes either:
class MyClass {
var quantity: Int
let valueFn: () -> (Int)
init(valueFn: () -> (Int)) {
self.valueFn = valueFn
}
}
var c1 = MyClass { () -> (Int) in
return quantity // error: can't use quantity or self
}
This one works, but I have to explicitly pass in the struct or struct property. My question is this: Can I do this without having a third property to wrap and pass in the reference? Is there a more Swifty approach?
struct MyOtherStruct {
var quantity: Int
private let valueFn: (Int) -> (Int)
var value: Int {
return valueFn(quantity)
}
}
var s3 = MyOtherStruct(quantity: 2) { (quantity) -> (Int) in
return quantity * 2
}
s3.value // -> 4
I've fibbled with this the last 20 minutes now, and I don't believe this is possible to achieve in the initialization of of your MyStruct instances; since at the call to the initializer (which you do with the trailing closure above), the instance does not yet exist. I will show below, however, a workaround for classes; one much like your third approach above, and one with more versatile usage (but horribly worse class implementation), making use of subclassing NSObject.
Anyway, possibly the above answers your question (as "no" for structs, and "possible, but overly complicated" for classes) with regard of use directly with the initializer in a versatile manner.
Below follows
A closure "wrapping" method much your third solution: wrapping a lazy closure over the closure you send at initialization. The drawback with this method is that you can't choose, for different class instances, which class properties you would like to use in the closure, as the wrapper (calling the mutable initialized closure) is already set at compile time.
Subclassing NSObject: a method that is probably overly complicated for any practical use (and also quite non-swifty), that however give you more versatile control over which class properties to use in the closure. By subclassing NSObject you get access to the method .valueForKey to apply to self. Added for the technical discussion/curiosity.
Method 1
class MyClass {
var quantity: Int
private let closure: (Int) -> (Int)
init(quantity: Int, closure: (Int) -> (Int)) {
self.quantity = quantity
self.closure = closure
}
lazy var valueFn : () -> Int = {
[unowned self] () -> Int in
return self.closure(self.quantity)
}
}
/* Example usage */
var c1 = MyClass(quantity: 2) { (a) -> (Int) in
return a * 2
}
c1.valueFn() // 4
c1.quantity = 4
c1.valueFn() // 8
Method 2
Class setup (...):
class MyClass : NSObject {
var quantity: Int = 0
var anotherQuantity: Int = 0
private var keyExists : Bool = true
private let key : String
private let foo: (Int) -> Int
init(operateClosureOn: (propertyWithKey: String, withInitialValue: Int),
closure: (Int) -> Int) {
key = operateClosureOn.propertyWithKey
foo = closure
super.init()
let val = operateClosureOn.withInitialValue
if let _ = (Mirror(reflecting: self).children.filter{ $0.label == key }).first {
self.setValue(val, forKey: key)
}
else { keyExists = false }
}
lazy var valueFn: () -> Int = {
[unowned self] () -> Int in
if !self.keyExists {
return 0
}
guard let a = self.valueForKey(self.key) as? Int else {
print("Unexpected: property for key '\(self.key)' is not if type 'Int'.")
return 0
}
return self.foo(a)
}
}
Example usage:
/* Example usage */
var c2 = MyClass(operateClosureOn: ("quantity", 2)) {
(val) -> Int in
return 2 * val
}
c2.valueFn() // 4
c2.quantity = 4
c2.valueFn() // 8
var c3 = MyClass(operateClosureOn: ("anotherQuantity", 20)) {
(val) -> Int in
return val / 2
}
c3.valueFn() // 10
c3.anotherQuantity = 40
c3.valueFn() // 20
var c4 = MyClass(operateClosureOn: ("aTypo", 20)) {
(val) -> Int in
return val / 2
}
c4.valueFn() // 0, OK, at least no runtime exception with this non-safe non-swifty solution :0)
Is there an elegant way (think one-liner) to get the first n elements of a SequenceType in Swift?
I could of course write a for-loop that terminates after n elements but that's a little bulky.
Note also that the solution should be able to deal with infinite sequences.
Isn't it exactly what mySequence.prefix(numberOfElements) does?
In Swift 2, you can create this as an extension:
extension SequenceType {
func take(n: Int) -> [Generator.Element] {
var result: [Generator.Element] = []
var g = self.generate()
for _ in 1...n {
if let next = g.next() {
result.append(next)
} else {
break
}
}
return result
}
}
In Swift 1, it would have to written as a function:
func take<Seq: SequenceType>(n: Int, xs: Seq) -> [Seq.Generator.Element] {
var result: [Seq.Generator.Element] = []
var g = xs.generate()
for _ in 1...n {
if let next = g.next() {
result.append(next)
} else {
break
}
}
return result
}
Note that in either case, SequenceType does not specify what happens if you call generate() more than once. It could return the same values (as in an Array). It could return different values (as in an audio data stream). It could return nothing at all. So the caller of take() may need some special knowledge about its impact on the sequence.
SequenceType only supports generate(). Perhaps a more 'Swiftly' approach would be to define a Generator that given a start and end index and a 'base' generator would skip over the first elements, start returning some, and then stop after end index. Like this:
struct SubscriptGenerator<Base: GeneratorType> : GeneratorType {
var nowIndex : Int = 0
let endIndex : Int
let begIndex : Int
var generator : Base
init (generator: Base, startIndex: Int, endIndex: Int) {
precondition(startIndex < endIndex, "oops")
self.generator = generator
self.endIndex = endIndex
self.begIndex = startIndex
}
// MARK - GeneratorType
typealias Element = Base.Element
mutating func next() -> Element? {
while (nowIndex < begIndex) { nowIndex++; generator.next () }
return nowIndex++ < endIndex ? generator.next() : nil
}
}
This is only an example. One could define an convenience init() that takes a SequenceType and produces the base generator. In action:
75> var gen = [10,20,30,40,50].generate()
76> var sg = SubscriptGenerator(generator: gen, startIndex: 1, endIndex:3)
sg: SubscriptGenerator<IndexingGenerator<[Int]>> = { ... }
77> sg.next()
$R2: Int? = 20
78> sg.next()
$R3: Int? = 30
79> sg.next()
$R4: Int? = nil
See Swift's EnumerateGenerator for an example.
Note: it might be the Stride nexus of Swift functionality does what you want already.
Why not
var seq = NominalSequence().generate()
var a = (0..<10).map({_ in seq.next()!})
?
Two lines, but funtional-ish.
I'm trying to implement a SequenceType / GeneratorType example and getting an error that doesn't quite make sense.
Here's the code:
// Here's my GeneratorType - it creates a random-number Generator:
struct RandomNumberGenerator:GeneratorType {
typealias Element = Int
mutating func next() -> Element? {
return Int(arc4random_uniform(100))
}
}
When I call this (in Playgrounds) it works perfectly well:
var randyNum = RandomNumberGenerator()
randyNum.next() // this shows a valid random number in the Gutter
// And calling it from within a println also works:
println("randyNum = \(randyNum.next()!)")
So far so so good.
Next is the SequenceType:
struct RandomNumbersSequence:SequenceType {
typealias Generator = RandomNumberGenerator
var numberOfRandomNumbers:Int
init(maxNum:Int) {
numberOfRandomNumbers = maxNum
}
func generate() -> Generator {
for i in 1...numberOfRandomNumbers {
var randNum = Generator()
randNum.next()
return randNum
}
}
}
That's what's generating an error: 'Type RandomNumberSequence' does not conform to protocol 'SequenceType'. (Xcode is showing this error right on that first line of the declaration struct RandomNumbersSequence:SequenceType statement.)
I actually think the logic of my for loop may be wrong - meaning I won't get the results I actually want - but regardless, in terms of satisfying what the SequenceType Protocol is requiring, I think I got that much right.
So what's causing this error?
This isn’t quite how generators work. Assuming you want to serve up a set number of random numbers, you have the right idea about taking a maximum as a parameter, but you need to store that in the generator, as well, plus some state for where it is up to.
The idea with a generator is that it stores its state, and every time you call next() you return the next element. So if you want to generate a run of up to n numbers, you could do something like the following:
struct RandomNumberGenerator: GeneratorType {
let n: Int
var i = 0
init(count: Int) { self.n = count }
mutating func next() -> Int? {
if i++ < n {
return Int(arc4random_uniform(100))
}
else {
return nil
}
}
}
Note, you don’t need a for loop here. Just each time next() is called, i is incremented, until it reaches the max, then the generator starts returning nil.
The purpose of SequenceType is to serve up fresh generators:
struct RandomNumberSequence: SequenceType {
let n: Int
init(count: Int) { self.n = count }
func generate() -> RandomNumberGenerator {
return RandomNumberGenerator(count: n)
}
}
Given this, you can now use it to generate a sequence of a fixed number of random integers:
let seq = RandomNumberSequence(count: 3)
for x in seq {
// loops 3 times with x being a new random number each time
}
// every time you use seq, you get a new set of 3 numbers
",".join(map(seq,toString)) // prints 3 comma-separated random nums
// but when you create a generator, it gets “used up”
var gen = seq.generate()
println(gen.next()) // prints a random number
println(gen.next()) // prints another random number
println(gen.next()) // prints the third
println(gen.next()) // prints nil
println(gen.next()) // and will keep printing nil
gen = seq.generate()
println(gen.next()) // will print the first of a new set of 3 numbers
Creating these stateful generators is quite a common problem, so the standard library has a helper struct, GeneratorOf, that allows to you skip defining them. It takes a closure that each time it is called should return the next value to generate:
struct RandomNumbersSequence: SequenceType {
let maxNum: Int
init(maxNum: Int) { self.maxNum = maxNum }
func generate() -> GeneratorOf<Int> {
// counter to track how many have been generated
var n = 0
return GeneratorOf {
// the closure “captures” n
if n++ < self.maxNum {
return Int(arc4random_uniform(100))
}
else {
return nil
}
}
}
}
The error message you're seeing:
'Type RandomNumberSequence' does not conform to protocol 'SequenceType'
Always means that your class or struct is missing something that the protocol declares as required.
In this case, we're missing the generate() -> Generator method. "But, it's right there!" you say? Well, it is, but it's not compiling.
func generate() -> Generator {
for i in 1...numberOfRandomNumbers {
var randNum = Generator()
randNum.next()
return randNum
}
}
The problem is, what if you initialize your struct with numberOfRandomNumbers less than or equal to 0? Your loop executes zero times and generate can't return anything.
I'm not sure exactly what logic you're trying to to do in this loop, but we can fix the compilation errors by simply a adding a return statement that will return a Generator:
func generate() -> Generator {
for i in 1...numberOfRandomNumbers {
var randNum = Generator()
randNum.next()
return randNum
}
return Generator()
}
This won't do what you're trying to accomplish. This isn't how generators are supposed to work. But it will fix the generate() -> Generator method and allow your struct to now conform to the protocol.
With Swift 3, you can choose one of the three RandomNumbersSequence implementations in order to solve your problem.
1. Using a struct that conforms to Sequence protocol and a struct that conforms to IteratorProtocol protocol
The following Playground code shows how to implement a RandomNumbersSequence struct that conforms to Sequence and that uses a RandomNumbersIterator struct that conforms to IteratorProtocol protocol:
import Darwin // required for arc4random_uniform
struct RandomNumbersIterator: IteratorProtocol {
let maxNum: Int
var n = 0
init(maxNum: Int) {
self.maxNum = maxNum
}
mutating func next() -> Int? {
n += 1
return n <= self.maxNum ? Int(arc4random_uniform(10)) : nil
}
}
struct RandomNumbersSequence: Sequence {
let maxNum: Int
init(maxNum: Int) {
self.maxNum = maxNum
}
func makeIterator() -> RandomNumbersIterator {
return RandomNumbersIterator(maxNum: maxNum)
}
}
Usage #1:
for value in RandomNumbersSequence(maxNum: 3) {
print(value)
}
/*
may print:
5
7
3
*/
Usage #2:
let randomArray = Array(RandomNumbersSequence(maxNum: 3))
print(randomArray)
/*
may print: [7, 6, 1]
*/
Usage #3:
let randomSequence = RandomNumbersSequence(maxNum: 3)
var randomGenerator = randomSequence.makeIterator()
randomGenerator.next() // may return: 4
randomGenerator.next() // may return: 8
randomGenerator.next() // may return: 3
randomGenerator.next() // will return: nil
2. Using a struct that conforms to Sequence and IteratorProtocol protocols
The following Playground code shows how to implement a RandomNumbersSequence struct that conforms to Sequence and IteratorProtocol protocols:
import Darwin // required for arc4random_uniform
struct RandomNumbersSequence: Sequence, IteratorProtocol {
let maxNum: Int
var n = 0
init(maxNum: Int) {
self.maxNum = maxNum
}
mutating func next() -> Int? {
n += 1
return n <= self.maxNum ? Int(arc4random_uniform(10)) : nil
}
}
Usage #1:
for value in RandomNumbersSequence(maxNum: 3) {
print(value)
}
/*
may print:
5
7
3
*/
Usage #2:
let randomArray = Array(RandomNumbersSequence(maxNum: 3))
print(randomArray)
/*
may print: [7, 6, 1]
*/
Usage #3:
var randomSequence = RandomNumbersSequence(maxNum: 3)
randomSequence.next() // may return: 4
randomSequence.next() // may return: 8
randomSequence.next() // may return: 3
randomSequence.next() // will return: nil
3. Using AnyIterator and a struct that conforms to Sequence
As an alternative to the previous implementation, you can use AnyIterator<T> as the return type of the makeIterator method inside your Sequence protocol conforming struct. The following Playground code shows how to implement it with your RandomNumbersSequence struct:
import Darwin // required for arc4random_uniform
struct RandomNumbersSequence: Sequence {
let maxNum: Int
init(maxNum: Int) {
self.maxNum = maxNum
}
func makeIterator() -> AnyIterator<Int> {
var n = 0
let iterator: AnyIterator<Int> = AnyIterator {
n += 1
return n <= self.maxNum ? Int(arc4random_uniform(10)) : nil
}
return iterator
}
}
Usage #1:
for value in RandomNumbersSequence(maxNum: 3) {
print(value)
}
/*
may print:
5
7
3
*/
Usage #2:
let randomArray = Array(RandomNumbersSequence(maxNum: 3))
print(randomArray)
/*
may print: [7, 6, 1]
*/
Usage #3:
let randomSequence = RandomNumbersSequence(maxNum: 3)
let randomGenerator = randomSequence.makeIterator()
randomGenerator.next() // may return: 4
randomGenerator.next() // may return: 8
randomGenerator.next() // may return: 3
randomGenerator.next() // will return: nil