Search code examples
swiftarc4random

Calling different extent of randomness of arc4random in Swift?


This might be rather stupid question. I would like to know if different nuances/extent of randomness would be possible using arc4random_uniform in Swift. Here's an example:

let number = arc4random_uniform(10) + 1
print(number)

In this case, a number will be printed randomly from 1 to 10. But is there a way that I can repeat the random result, 2 to 3 times? The result would be something like this:

1, 1, 6, 6, 6, 3, 3, 8, 8, 9, 9, 9 ...

// 1) Randomly selected and 2) repeated 2 to 3 times randomly.

Perhaps I might use two arc4random_uniform functions together, but cannot express them properly. Would be much appreciated if you could give me some suggestions. <3


Solution

  • In order to do this, you will need to generate two values: your random value and a repeatCount. Also, you'll need to remember both of those values so that you can repeat the value. You can do this with a custom class:

    class RandomWithRepeats {
        var range: ClosedRange<Int>
        var repeatRange: ClosedRange<Int>
        var repeatCount = 0
        var value = 0
    
        init(range: ClosedRange<Int>, repeatRange: ClosedRange<Int>) {
            self.range = range
            self.repeatRange = repeatRange
        }
    
        // generate a random number in a range
        // Just use Int.random(in:) with Swift 4.2 and later
        func random(in range: ClosedRange<Int>) -> Int {
            return Int(arc4random_uniform(UInt32(range.upperBound - range.lowerBound + 1))) + range.lowerBound
        }
    
        func nextValue() -> Int {
            // if repeatCount is 0, its time to generate a new value and
            // a new repeatCount
            if repeatCount == 0 {
                // For Swift 4.2, just use Int.random(in:) instead
                value = self.random(in: range)
                repeatCount = self.random(in: repeatRange)
            }
    
            repeatCount -= 1
            return value
        }
    }
    

    Example:

    let rand = RandomWithRepeats(range: 1...10, repeatRange: 2...3)
    
    // generate 20 random repeated numbers    
    for _ in 1...20
    {
        print(rand.nextValue(), terminator: " ")
    }
    
    6 6 6 8 8 8 10 10 10 2 2 9 9 5 5 8 8 8 5 5