2

I have a function that generate an integer random number between two given values. This function in my app will be called only two times however, I want to avoid that it generates two same numbers or two number next to each other. How could I fix the function below to achieve that?

Example Result:

1, 1 = wrong
1, 2 = wrong
8, 7 = wrong

8, 12 = correct
1, 3 = correct
3, 0 = correct

Function:

func randomNumber(minX:UInt32, maxX:UInt32) -> Int {
        let result = (arc4random() % (maxX - minX + 1)) + minX
        return Int(result)
    }

EDIT: How can it be a duplicate??? I am not asking to shuffle an array but I want to generate a single Int from two given numbers

SNos
  • 3,430
  • 5
  • 42
  • 92
  • If you wanted to generate a random list of numbers, never repeating any, you'd use Fisher-Yates: http://stackoverflow.com/a/24029847/1271826. You can alter this to stop after two items. – Rob Aug 08 '16 at 17:01
  • Thanks Rob, but I don't want to shuffle an array. I need to generate a number from two values that are generated during some process of the app – SNos Aug 08 '16 at 17:08
  • 2
    Possible duplicate of [How to generate a random number in Swift without repeating the previous random number?](http://stackoverflow.com/questions/27541145/how-to-generate-a-random-number-in-swift-without-repeating-the-previous-random-n) – dfrib Aug 08 '16 at 17:36

2 Answers2

0

Make global/static variable, where you will remember last valid generated number. Then add if statement, which will recursively call randomNumber, when you generate same(/next to each other) number as in that variable. If there hasn't been generated any number, set number out of interval.

Přemysl Šťastný
  • 1,676
  • 2
  • 18
  • 39
  • Thanks .. I am trying to do this however, seems that I cannot call recursively rarndomNumber. `var previousNumber: UInt32?` – SNos Aug 08 '16 at 17:26
0

You said "I want to avoid ... two numbers next to each other" so I don't understand how 8 ,7 is wrong but 8, 9 is correct.

Anyhow, my answer answer is based on your example. Just send the previous value and loop until you get a satisfactory asnwer:

func randomNumber(minX:UInt32, maxX:UInt32, previousNumber: Int? = nil) -> Int {
    var result: Int

    repeat {
        result = Int((arc4random() % (maxX - minX + 1)) + minX)
    } while previousNumber == result || previousNumber == result + 1

    return result
}
let r1 = randomNumber(1, maxX: 3)
let r2 = randomNumber(1, maxX: 3, previousNumber: r1)

This will lead to an infinite loop when there's no number that can satisfy your conditions, for example:

randonNumber(1, maxX: 2, previousNumber: 2)

You should add a guard statement by working out the possibility mathematically and create a counter so that the repeat loop ends after, say 100 iterations.

Code Different
  • 90,614
  • 16
  • 144
  • 163