extension Int
{
static func random(range: Range<Int> ) -> Int
{
var offset = 0
if range.startIndex < 0 // allow negative ranges
{
offset = abs(range.startIndex)
}
let mini = UInt32(range.startIndex + offset)
let maxi = UInt32(range.endIndex + offset)
return Int(mini + arc4random_uniform(maxi - mini)) - offset
}
}
如何将其修改为仅吐出25的增量?例如:
random(150...250)
可能会给我150,175,200,225和250之间的任何内容。
我知道我可以检查它是否可以被25分割,但是谁知道它有多少次再次滚动&#39;找到一个被接受的号码。我正在寻找一些在代码中更优化和/或更清洁的东西。公平地说,我不知道arc4random_uniform函数有多快。
答案 0 :(得分:2)
var num = 150 + ( random(0...4) * 25)
答案 1 :(得分:2)
func random25(min: Int, max: Int) -> Int {
assert(max > min)
let minIndex = min / 25
let r = arc4random_uniform(UInt32(max / 25 - minIndex))
return (Int(r) + minIndex) * 25
}
答案 2 :(得分:1)
func randomRange(range: Range<Int>, increment:Int ) -> Int {
if Int(range.endIndex-1) % increment != 0 { return 0 }
if increment > (Int(range.endIndex-1 ) - Int(range.startIndex )) { return 0 }
if increment == 1 { return Int( arc4random_uniform( UInt32( Int(range.endIndex) - Int(range.startIndex) ) ) ) + Int(range.startIndex) }
let numberOfRandomElements = ( ( Int(range.endIndex ) - Int(range.startIndex )) / increment ) + 1
let randomAux = Int(arc4random_uniform(UInt32(numberOfRandomElements)))
return randomAux * increment + Int(range.startIndex)
}
randomRange(100...250, 25)
randomRange(100...250, 25)
randomRange(100...250, 25)
randomRange(100...250, 25)
randomRange(100...250, 25)
randomRange(100...250, 25)
randomRange(100...250, 5)
randomRange(100...250, 5)
randomRange(100...250, 5)
randomRange(100...250, 5)
randomRange(100...250, 5)
randomRange(100...250, 5)
randomRange(100...250, 5)
答案 3 :(得分:0)
这是一个灵活的实现,用于在范围内以恒定的间隔生成随机整数。在游乐场中运行它并使用菜单命令编辑器&gt;执行Playground以测试多个随机结果。
import Foundation
/// Returns an integer within the specified range,
/// skipping values between intervals. Interval values are calculated
/// starting from the range's startIndex for positive intervals
/// and from the endIndex for negative intervals.
func randomInRange(range: Range<Int>, withInterval interval: Int = 1) -> Int {
assert(interval != 0, "Function failed because increment argument is zero")
let startIndex = range.startIndex
let endIndex = range.endIndex
assert(endIndex > startIndex, "Function failed because range's endIndex is not greater than startIndex")
let penultimateIndex = endIndex - 1
let possibilityCount = abs((penultimateIndex - startIndex) / interval) + 1
let randomOffset = Int(arc4random_uniform(UInt32(possibilityCount))) * interval
if interval > 0 {
return startIndex + randomOffset
} else {
return penultimateIndex + randomOffset
}
}
randomInRange(150...250, withInterval: 25) // As per OP's request
randomInRange(0..<2, withInterval: 1) // Only produces 0 or 1
randomInRange(0...2, withInterval: 1)
randomInRange(0...2) // Interval of 1 assumed
randomInRange(0...2, withInterval: 2)
randomInRange(0...2, withInterval: 3) // Only produces 0
randomInRange(0...2, withInterval: -3) // Only produces 2
randomInRange(0...4, withInterval: 2)
randomInRange(0...6, withInterval: 3)
randomInRange(0...6, withInterval: 4) // Only produces 0 or 4
randomInRange(0...6, withInterval: -4) // Only produces 6 or 2
randomInRange(1...10, withInterval: 3) // Produces 1, 4, 7, or 10
randomInRange(-3...3, withInterval: 3)
randomInRange(-7...5, withInterval: 3) // Produces values that are not multiples of the interval
randomInRange(0...100, withInterval: 25)
randomInRange(0...100, withInterval: -33) // Produces 100, 67, 34, or 1
randomInRange(0...0, withInterval: 1) // Only produces 0
// randomInRange(Range(start: 0, end: 0), withInterval: 1) // Assertion error for empty range
// randomInRange(0...100, withInterval: 0) // Assertion error for interval of 0
/// Returns an optional integer within the specified range,
/// skipping values between intervals.
/// If the range's startIndex and endIndex-1 are not multiples of the interval,
/// the function adjusts these values in a narrower range with start and end indices at interval multiples.
/// If no multiple of the interval exists in the given range, returns nil.
func randomInRange(range: Range<Int>, atMultipleOfInterval interval: Int) -> Int? {
assert(interval != 0, "Function failed because increment argument is zero")
let startIndex = range.startIndex
let endIndex = range.endIndex
assert(endIndex > startIndex, "Function failed because range's endIndex is not greater than startIndex")
let penultimateIndex = endIndex - 1
if (startIndex % interval != 0) || (penultimateIndex % interval != 0) {
let adjustedStart = startIndex - startIndex % interval + interval
let adjustedPenultimate: Int = penultimateIndex - penultimateIndex % interval
if adjustedPenultimate >= adjustedStart {
return randomInRange(adjustedStart...adjustedPenultimate, withInterval: interval)
} else {
return nil
}
} else {
return randomInRange(startIndex...penultimateIndex, withInterval: interval)
}
}
randomInRange(0...10, atMultipleOfInterval: 5)
randomInRange(2...4, atMultipleOfInterval: 5) // Produces nil
randomInRange(7...13, atMultipleOfInterval: 10)
randomInRange(1...500, atMultipleOfInterval: 7)
randomInRange(300...300, atMultipleOfInterval: 25)
// With random range, return only random values that are multiples of the random interval
let interval = Int(arc4random_uniform(25)) + 1
var startIndex = Int(arc4random_uniform(500)) - 250
var penultimateIndex = startIndex + interval + Int(arc4random_uniform(250))
randomInRange(startIndex...penultimateIndex, atMultipleOfInterval: interval)