Swift로 난수 생성


92

난수를 생성해야합니다.

arc4random기능 과 기능이 더 이상 존재하지 않는 것 arc4random_uniform같습니다.

내가 가진 옵션은 arc4random_stir(), arc4random_buf(UnsafeMutablePointer<Void>, Int)하고 arc4random_addrandom(UnsafeMutablePointer<UInt8>, Int32).

함수에 대한 문서를 찾을 수 없으며 헤더 파일의 주석이 힌트를 제공하지 않습니다.


3
Xcode의 자동 완성이 방금 중단 된 것처럼 보입니다. 자동 완성없이 타이핑했고 컴파일되지 않았다고 맹세 할 수있었습니다. 지금 일하고 있습니다. @arsen에 의해 니스 참조
Big_Mac

1
arc4random_uniform을 사용할 수 있습니다. 언어의 기본 부분이 아닌 Foundation API의 일부이므로 파일 헤드에 "import Foundation"(또는 "import UIKit")이 있어야 사용할 수 있습니다.
Vince O'Sullivan

확률 = Int (arc4random_uniform (UInt32 (total))) – 자동 완성 기능이 깨 졌기 때문에 타이핑 불만이 구체적이지 않았습니다. 즉, 두 가지 다른 오류로 인한 캐스팅 불만이었습니다
bshirley

답변:


227

===== Swift 4.2 / Xcode 10 =====

let randomIntFrom0To10 = Int.random(in: 1..<10)
let randomFloat = Float.random(in: 0..<1)

// if you want to get a random element in an array
let greetings = ["hey", "hi", "hello", "hola"]
greetings.randomElement()

내부적으로 Swift는 arc4random_buf작업을 수행하는 데 사용 합니다.

===== 스위프트 4.1 / Xcode 9 =====

arc4random()0 에서 4 294 967 295 범위의 난수를 반환합니다.

drand48()0.0 에서 1.0 사이 의 난수를 반환합니다.

arc4random_uniform(N)0 에서 N-1 범위의 난수를 반환합니다.

예 :

arc4random() // => UInt32 = 2739058784
arc4random() // => UInt32 = 2672503239
arc4random() // => UInt32 = 3990537167
arc4random() // => UInt32 = 2516511476
arc4random() // => UInt32 = 3959558840

drand48() // => Double = 0.88642843322303122
drand48() // => Double = 0.015582849408328769
drand48() // => Double = 0.58409022031727176
drand48() // => Double = 0.15936862653180484
drand48() // => Double = 0.38371587480719427

arc4random_uniform(3) // => UInt32 = 0
arc4random_uniform(3) // => UInt32 = 1
arc4random_uniform(3) // => UInt32 = 0
arc4random_uniform(3) // => UInt32 = 1
arc4random_uniform(3) // => UInt32 = 2

arc4random_uniform ()arc4random() % upper_bound상한이 2의 거듭 제곱이 아닐 때 "모듈로 바이어스"를 피하기 때문에 같은 구조보다 권장 됩니다.


Float.random()현재 표시되어 베타 등 제공'Float' has no member 'random'
데일

22

시도해 볼 수도 있습니다.

let diceRoll = Int(arc4random_uniform(UInt32(6)))

작동하려면 "UInt32"를 추가해야했습니다.


1
이 함수를 찾아 보면 public func arc4random_uniform(_: UInt32) -> UInt32. 그래서 왜 매개 변수로 변환 UInt32합니까? 여기서 다른 일이 일어나고 있습니까?
Mark Moeykens

8

이 함수를 호출하고 최소 및 최대 범위를 제공하면 임의의 숫자를 얻을 수 있습니다.

예. randomNumber (MIN : 0, MAX : 10) 와 같이 0에서 9 사이의 숫자를 얻게됩니다 .

func randomNumber(MIN: Int, MAX: Int)-> Int{
    return Int(arc4random_uniform(UInt32(MAX-MIN)) + UInt32(MIN));
}

참고 :-항상 Integer 숫자가 출력됩니다.


1
내가 필요로 생각 : func randomNumber(MIN: Int, MAX: Int)-> Int{ return Int(arc4random_uniform(UInt32(MAX-MIN)) + UInt32(MIN)); }
Adahus

5

몇 가지 조사 후 나는 이것을 썼다.

import Foundation

struct Math {
   private static var seeded = false

   static func randomFractional() -> CGFloat {

      if !Math.seeded {
         let time = Int(NSDate().timeIntervalSinceReferenceDate)
         srand48(time)
         Math.seeded = true
      }

      return CGFloat(drand48())
   }
}

이제 Math.randomFraction()시드를 먼저 기억할 필요없이 난수 [0..1 []를 얻을 수 있습니다 . 이것이 누군가에게 도움이되기를 바랍니다 : o)


4

신속한 4.2 업데이트 :

let randomInt = Int.random(in: 1..<5)
let randomFloat = Float.random(in: 1..<10)
let randomDouble = Double.random(in: 1...100)
let randomCGFloat = CGFloat.random(in: 1...1000)

3

또 다른 옵션은 xorshift128plus 알고리즘 을 사용하는 것입니다 .

func xorshift128plus(seed0 : UInt64, _ seed1 : UInt64) -> () -> UInt64 {
    var state0 : UInt64 = seed0
    var state1 : UInt64 = seed1
    if state0 == 0 && state1 == 0 {
        state0 = 1 // both state variables cannot be 0
    }

    func rand() -> UInt64 {
        var s1 : UInt64 = state0
        let s0 : UInt64 = state1
        state0 = s0
        s1 ^= s1 << 23
        s1 ^= s1 >> 17
        s1 ^= s0
        s1 ^= s0 >> 26
        state1 = s1
        return UInt64.addWithOverflow(state0, state1).0
    }

    return rand
}

이 알고리즘의주기는 2 ^ 128-1 이며 BigCrush 테스트 스위트 의 모든 테스트를 통과합니다 . 이것은 장기간의 고품질 의사 난수 생성기 이지만 암호 학적으로 안전한 난수 생성기는 아닙니다 .

현재 시간이나 다른 임의의 엔트로피 소스에서 시드 할 수 있습니다. 예를 들어 from urand64()을 읽는 함수가 있다면 다음 과 같이 사용할 수 있습니다.UInt64/dev/urandom

let rand = xorshift128plus(urand64(), urand64())
for _ in 1...10 {
    print(rand())
}

1
let MAX : UInt32 = 9
let MIN : UInt32 = 1 
func randomNumber()
{
   var random_number = Int(arc4random_uniform(MAX) + MIN)
   print ("random = ", random_number);    
}

이 코드에 대한 설명을 제공하지 않는 이유는 무엇입니까?
개정

1

Swift 3에서 :

제한하기 위해 0 사이의 난수를 생성합니다.

let limit : UInt32 = 6
print("Random Number : \(arc4random_uniform(limit))")

그리고 i는 0 내지 N 개의 번호가 아니라, 5 내지 10의 난수를 생성 할 경우
리시

1
5 ~ 10 것이다에서 @Rishiarc4random_uniform(6) + 5
매트 르 플 뢰르

1

Int 확장으로 내 구현. 범위에서 난수를 생성합니다.from..<to

public extension Int {
    static func random(from: Int, to: Int) -> Int {
        guard to > from else {
            assertionFailure("Can not generate negative random numbers")
            return 0
        }
        return Int(arc4random_uniform(UInt32(to - from)) + UInt32(from))
    }
}

1

이것이 내가 2 개의 정수 사이에서 난수를 얻는 방법입니다!

func randomNumber(MIN: Int, MAX: Int)-> Int{
    var list : [Int] = []
    for i in MIN...MAX {
        list.append(i)
    }
    return list[Int(arc4random_uniform(UInt32(list.count)))]
}

용법:

print("My Random Number is: \(randomNumber(MIN:-10,MAX:10))")

1

또 다른 옵션은 GameKit의 GKMersenneTwisterRandomSource 를 사용하는 입니다. 문서는 다음과 같이 말합니다.

메르 센 트위스터 알고리즘을 기반으로 난수를 생성하는 결정 론적 의사 난수 소스입니다. 신뢰할 수있는 게임 플레이 메커니즘을 만드는 데 적합한 결정 론적 랜덤 소스입니다. Arc4 소스보다 약간 느리지 만 반복 시퀀스까지 더 긴 기간이 있다는 점에서 더 무작위 적입니다. 결정적이지만 이것은 암호화 무작위 소스가 아닙니다. 그러나 게임 플레이 데이터의 난독 화에는 적합합니다.

import GameKit

let minValue = 0
let maxValue = 100

var randomDistribution: GKRandomDistribution?
let randomSource = GKMersenneTwisterRandomSource()
randomDistribution = GKRandomDistribution(randomSource: randomSource, lowestValue: minValue, highestValue: maxValue)
let number = randomDistribution?.nextInt() ?? 0
print(number)

Apple의 샘플 코드에서 가져온 예 : https://github.com/carekit-apple/CareKit/blob/master/CareKitPrototypingTool/OCKPrototyper/CareKitPatient/RandomNumberGeneratorHelper.swift


1

파티에 늦었 어 🤩🎉

배열의 크기와 범위 선택을 즉석에서 변경할 수있는 기능을 사용하는 것이 가장 다양한 방법입니다. 지도를 사용할 수도 있으므로 매우 간결합니다. 모든 성능 테스트 / 벤치 마킹에 사용합니다.

elements다음의 숫자
만 포함 하는 배열의 항목 수입니다.0...max

func randArr(_ elements: Int, _ max: Int) -> [Int] {
        return (0..<elements).map{ _ in Int.random(in: 0...max) }
    }

Code Sense / Placeholder는 다음과 같습니다. randArr(elements: Int, max: Int)

내 배열의 10 개 요소는 0에서 1000까지입니다.

randArr(10, 1000) // [554, 8, 54, 87, 10, 33, 349, 888, 2, 77]

0

특정 비율로 사용할 수 있습니다.

let die = [1, 2, 3, 4, 5, 6]
 let firstRoll = die[Int(arc4random_uniform(UInt32(die.count)))]
 let secondRoll = die[Int(arc4random_uniform(UInt32(die.count)))]

0

난수 또는 임의의 문자열에 대해 Swift로 코드를 작성할 수 있습니다. :)

let quotes: NSArray = ["R", "A", "N", "D", "O", "M"]

      let randomNumber = arc4random_uniform(UInt32(quotes.count))
      let quoteString = quotes[Int(randomNumber)]
      print(quoteString)

무작위로 출력을 제공합니다.


0

일부 숫자가 반복된다는 것을 잊지 마십시오! 그래서 당신은 뭔가를해야합니다 ....

내 totalQuestions는 47 개였습니다.

func getRandomNumbers(totalQuestions:Int) -> NSMutableArray
{

    var arrayOfRandomQuestions: [Int] = []

    print("arraySizeRequired = 40")
    print("totalQuestions = \(totalQuestions)")

    //This will output a 40 random numbers between 0 and totalQuestions (47)
    while arrayOfRandomQuestions.count < 40
    {

        let limit: UInt32 = UInt32(totalQuestions)

        let theRandomNumber = (Int(arc4random_uniform(limit)))

            if arrayOfRandomQuestions.contains(theRandomNumber)
            {
                print("ping")

            }
            else
            {
            //item not found
                arrayOfRandomQuestions.append(theRandomNumber)
            }

    }

    print("Random Number set = \(arrayOfRandomQuestions)")
    print("arrayOutputCount = \(arrayOfRandomQuestions.count)")


    return arrayOfRandomQuestions as! NSMutableArray

}

-2

봐, 나는 같은 문제가 있었지만 함수를 전역 변수로 삽입했습니다.

같이

var RNumber = Int(arc4random_uniform(9)+1)

func GetCase(){

your code
}

분명히 이것은 효율적이지 않으므로 코드를 복사하여 함수에 붙여 넣어 재사용 할 수 있도록 한 다음 xcode는 var를 상수로 설정하여 내 코드가

func GetCase() {

let RNumber = Int(arc4random_uniform(9)+1)

   if categoria == 1 {
    }
}

내 코드의 일부이므로 xcode가 변경 불가능하고 초기화하는 것을 알려주지 만 어쨌든 앱을 빌드하고 그 조언은 단순히 사라집니다.

도움이 되길 바랍니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.