Генератор случайных чисел - arc4Random - Числа не могут совпадать

У меня есть генератор случайных чисел, использующий arc4Random и целые числа с тремя числами: number1, number2, number3 в диапазоне от 1 до 3. Ноль не допускается. Эта часть, которую я отсортировал из-за предыдущего запроса здесь, однако, когда нажата тестовая кнопка, я хочу убедиться, что случайные числа не совпадают, т.е. если число 1 отображает 2, то число 2 и число 3 не могут отображать 2 и т. д. Я попытался сделать это ниже, но должен быть более простой способ сделать это. Как это будет написано в коде, поскольку я изучаю Xcode всего около 6 недель? С Уважением. Дель Хиндс

@IBAction func testButtonPressed(sender: UIButton) {

var str = "Hello, playground"

var number1 = Int(arc4random() % UInt32(4))

if number1 == 0 {
number1 = 1
}

var number2 = Int(arc4random() % UInt32(4))

if number2 == 0 {
if number1 == 1 {
    number2 = 2
}
else if number1 == 2 {
    number2 = 3
}
else if number1 == 3 {
    number2 = 1
}
number2 = 1
}

label2TextLabel.text = "\(number2)"

var number3 = Int(arc4random() % UInt32(4))

if number3 == 0 {
if number2 == 1 {
    number3 = 2
}
else if number2 == 2 {
    number3 = 3
}
else if number2 == 3 {
    number3 = 1
}
number3 = 1
}

label3TextLabel.text = "\(number3)"

person Del Hinds    schedule 29.07.2015    source источник
comment
если вы просто генерируете в диапазоне 1-3 и не можете иметь повторы, просто создайте массив [1,2,3], перетасуйте его и бум - мгновенные неповторяющиеся случайные значения.   -  person Marc B    schedule 29.07.2015
comment
Привет Марк, Спасибо за ваш ответ. Не уверен, что понимаю ответ, но я буду работать над этим. Большое спасибо. Дел   -  person Del Hinds    schedule 29.07.2015


Ответы (3)


Если вы используете GameplayKit для iOS9, обратите внимание на GKShuffledDistribution.
Пример игровой площадки:

  import GameplayKit
  let distribution = GKShuffledDistribution(lowestValue: 1, highestValue: 3)
  for i in 1...36 {  // Do 12 groups of 3
      print(distribution.nextInt(), appendnewline: false)
      if i % 3 == 0 { print(" ", appendnewline: false ) }
   }

Пример результата: 213 132 321 312 213 132 132 123 132 231 132 123


Или рассмотрим GKRandomSource:

  import GameplayKit
  blocks : [AnyObject] = ["A","B","C"]
  for  _ in  1...5 {  // do 5 shuffles
     blocks = GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(blocks)
     print(blocks)
   }

Пример результата: [A, C, B] [B, C, A] [B, A, C] [C, A, B] [B, A, C]

Свифт 3:

GKShuffledDistribution — без реальных изменений, изменено использование печати.

  import GameplayKit
  let distribution = GKShuffledDistribution(lowestValue: 1, highestValue: 3)
  for i in 1...36 {
      print(distribution.nextInt(), terminator: "")
      if i % 3 == 0 { print(" ", terminator: "" ) }
  }

Версия использования GKRandomSource

  • Заменил AnyObject на Any
  • Теперь используйте arrayByShufflingObjects (в блоках)

дает

  import GameplayKit
  blocks : [Any] = ["A","B","C"]
  for  _ in  1...5 {  // do 5 shuffles
     blocks = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: blocks)
     print(blocks)
   }
person Refactor    schedule 29.07.2015
comment
Привет Рефакторинг, спасибо за ваши ответы. Это интересные варианты и спасибо за кодирование. Я посмотрю на них. Спасибо еще раз. Дел - person Del Hinds; 30.07.2015

Грубый способ сделать это - начать с массива возможного набора чисел {1, 2, 3} в вашем случае и несколько раз поменять местами случайные элементы в массиве, используя встроенный генератор случайных чисел.

Однако, если вы требуете, чтобы перетасовка обладала статистическим свойством, состоящим в том, что вероятность появления данного числа при условии, что оно еще не произошло, равна 1 / (оставшиеся числа), тогда используйте более строгую перетасовку Фишера-Йейтса.

person Bathsheba    schedule 29.07.2015
comment
Привет Вирсавия, Спасибо за ваш ответ. Не уверен, что понимаю ответ, но я буду работать над этим. Большое спасибо. Дел - person Del Hinds; 29.07.2015

Создайте массив (или набор) присвоенных номеров. При назначении нового номера проверьте, не находится ли он уже в массиве. Если да, то присвойте новый случайный номер. Повторение.

После присвоения номера добавьте его в массив. Проверьте, превышает ли размер массива диапазон разрешенных чисел или равен ему. Если количество случайных чисел исчерпано, выдайте ошибку и не позволяйте случайному назначению дополнительных чисел.

Если вы делаете это для больших наборов чисел, вы должны убедиться, что размер массива используемых чисел не превышает примерно половины размера диапазона назначаемых чисел.

Если вы делаете это для небольшого набора чисел, то было бы лучше добавить числа в диапазоне в массив и удалить их из массива по мере их назначения.

person Fennelouski    schedule 29.07.2015
comment
Привет Fennelouski, Спасибо за ваш ответ. Не уверен, что понимаю ответ, но я буду работать над этим. Большое спасибо. Дел - person Del Hinds; 29.07.2015