Skip to content

Instantly share code, notes, and snippets.

@pyrtsa
Last active March 23, 2017 11:51
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pyrtsa/7ff1b493f674656b2718 to your computer and use it in GitHub Desktop.
Save pyrtsa/7ff1b493f674656b2718 to your computer and use it in GitHub Desktop.
Sampling random numbers in Swift
import Random
random(0 ..< 10) // Int
random(1 ... 1000_000) // Int
random(-1000_000 ... 1000_000) // Int
random(Int.min ... Int.max) // Int
randomMax(UInt64.max) // UInt64
random(0 ... UInt64.max) // UInt64
random(1 ... UInt(10)) // UInt
random(Int8.min ... Int8.max) // Int8
let r = 10 ..< 20 // Range<Int>
let xs = ["1", "3", "5"] // [String]
randomElement(r) // Int
randomElement(xs) // String
randomElement(indices(xs)) // Int
import Foundation
public func bitwiseCeil<T : UnsignedIntegerType>(x: T) -> T {
var i = ~T(0)
while ~i < x {
i = T.multiplyWithOverflow(i, 2).0
}
return ~i
}
public func randomMax<T : UnsignedIntegerType>(max: T) -> T {
let m = bitwiseCeil(max)
var buf = T(0)
do {
arc4random_buf(&buf, sizeof(UInt))
buf &= m
} while buf > max
return buf
}
public func random<T : UnsignedIntegerType>(interval: ClosedInterval<T>) -> T {
let a = interval.start
let b = interval.end
return a + randomMax(b - a)
}
public func random<T : UnsignedIntegerType>(interval: HalfOpenInterval<T>) -> T {
if interval.isEmpty {
return interval.end
} else {
return random(interval.start ... interval.end - 1)
}
}
public protocol Signable : UnsignedIntegerType {
typealias Signed //: Unsignable
init(bitPattern: Signed)
}
public protocol Unsignable : SignedIntegerType {
typealias Unsigned : Signable
init(bitPattern: Unsigned)
}
extension UInt : Signable { typealias Signed = Int }
extension UInt8 : Signable { typealias Signed = Int8 }
extension UInt16 : Signable { typealias Signed = Int16 }
extension UInt32 : Signable { typealias Signed = Int32 }
extension UInt64 : Signable { typealias Signed = Int64 }
extension Int : Unsignable { typealias Unsigned = UInt }
extension Int8 : Unsignable { typealias Unsigned = UInt8 }
extension Int16 : Unsignable { typealias Unsigned = UInt16 }
extension Int32 : Unsignable { typealias Unsigned = UInt32 }
extension Int64 : Unsignable { typealias Unsigned = UInt64 }
public func random<T : Unsignable where T.Unsigned.Signed == T>
(interval: ClosedInterval<T>) -> T
{
typealias Unsigned = T.Unsigned
let a = Unsigned(bitPattern: interval.start)
let b = Unsigned(bitPattern: interval.end)
let d = Unsigned.subtractWithOverflow(b, a).0
let r = random(0 ... d as ClosedInterval)
return T(bitPattern: Unsigned.addWithOverflow(a, r).0)
}
public func random<T : Unsignable where T.Unsigned.Signed == T>
(interval: HalfOpenInterval<T>) -> T
{
if interval.isEmpty {
return interval.end
} else {
return random(interval.start ... interval.end - 1)
}
}
public func randomElement<C : CollectionType
where C.Index : Unsignable, C.Index.Unsigned.Signed == C.Index>
(elements: C) -> C.Generator.Element
{
precondition(elements.startIndex < elements.endIndex)
return elements[random(HalfOpenInterval(elements.startIndex,
elements.endIndex))]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment