swift - ऐप्पल की स्विफ्ट भाषा में कोई यादृच्छिक संख्या कैसे उत्पन्न करता है?




random (14)

मुझे लगता है कि स्विफ्ट पुस्तक ने एक यादृच्छिक संख्या जेनरेटर के कार्यान्वयन प्रदान किए। क्या इस कार्यान्वयन को अपने स्वयं के कार्यक्रम में कॉपी और पेस्ट करने का सबसे अच्छा अभ्यास है? या क्या कोई पुस्तकालय है जो ऐसा करता है जिसे हम अब उपयोग कर सकते हैं?


arc4random_uniform() प्रयोग करें

उपयोग:

arc4random_uniform(someNumber: UInt32) -> UInt32

यह आपको कुछ संख्या 0 तक श्रेणी 0 में यादृच्छिक पूर्णांक देता है।

UInt32 लिए अधिकतम मान 4,294,967,295 है (यानी, 2^32 - 1 )।

उदाहरण:

  • सिक्का उछालो

    let flip = arc4random_uniform(2) // 0 or 1
    
  • पासा फेंकना

    let roll = arc4random_uniform(6) + 1 // 1...6
    
  • अक्टूबर में यादृच्छिक दिन

    let day = arc4random_uniform(31) + 1 // 1...31
    
  • 1 99 0 के दशक में यादृच्छिक वर्ष

    let year = 1990 + arc4random_uniform(10)
    

सामान्य फ़ॉर्म:

let number = min + arc4random_uniform(max - min + 1)

जहां number , max , और min UInt32

व्हाट अबाउट...

arc4random ()

आप arc4random() का उपयोग कर यादृच्छिक संख्या भी प्राप्त कर सकते हैं, जो 0 और 2 ^ 32-1 के बीच UInt32 उत्पन्न करता है। इस प्रकार 0 और x-1 बीच यादृच्छिक संख्या प्राप्त करने के लिए, आप इसे x विभाजित कर सकते हैं और शेष ले सकते हैं। या दूसरे शब्दों में, रिमेन्डर ऑपरेटर (%) का उपयोग करें:

let number = arc4random() % 5 // 0...4

हालांकि, यह मामूली मॉड्यूलो पूर्वाग्रह उत्पन्न करता है ( here और here भी देखें), इसलिए यही कारण है कि arc4random_uniform() की अनुशंसा की जाती है।

Int से कनवर्ट करना

आम तौर पर Int और UInt32 बीच कनवर्ट करने के लिए ऐसा कुछ करना ठीक होगा:

let number: Int = 10
let random = Int(arc4random_uniform(UInt32(number)))

समस्या यह है कि Int में 32 बिट सिस्टम पर -2,147,483,648...2,147,483,647 और 64 बिट सिस्टम पर -9,223,372,036,854,775,808...9,223,372,036,854,775,807 , -9,223,372,036,854,775,808...9,223,372,036,854,775,807 की एक श्रृंखला है। इसकी तुलना UInt32 रेंज 0...4,294,967,295UInt32 का U UInt32 है।

निम्नलिखित त्रुटियों पर विचार करें:

UInt32(-1) // negative numbers cause integer overflow error
UInt32(4294967296) // numbers greater than 4,294,967,295 cause integer overflow error

इसलिए आपको यह सुनिश्चित करने की ज़रूरत है कि आपके इनपुट पैरामीटर UInt32 रेंज के भीतर हैं और आपको उस सीमा के बाहर मौजूद आउटपुट की आवश्यकता नहीं है।


विवरण

एक्सकोड 9.1, स्विफ्ट 4

गणित उन्मुख समाधान (1)

import Foundation

class Random {

    subscript<T>(_ min: T, _ max: T) -> T where T : BinaryInteger {
        get {
            return rand(min-1, max+1)
        }
    }
}

let rand = Random()

func rand<T>(_ min: T, _ max: T) -> T where T : BinaryInteger {
    let _min = min + 1
    let difference = max - _min
    return T(arc4random_uniform(UInt32(difference))) + _min
}

समाधान का उपयोग (1)

let x = rand(-5, 5)       // x = [-4, -3, -2, -1, 0, 1, 2, 3, 4]
let x = rand[0, 10]       // x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

प्रोग्रामर उन्मुख समाधान (2)

यहां मठ उन्मुख समाधान (1) कोड जोड़ने के लिए मत भूलना

import Foundation

extension CountableRange where Bound : BinaryInteger {

    var random: Bound {
        return rand(lowerBound-1, upperBound)
    }
}

extension CountableClosedRange where Bound : BinaryInteger {

    var random: Bound {
        return rand[lowerBound, upperBound]
    }
}

समाधान का उपयोग (2)

let x = (-8..<2).random           // x = [-8, -7, -6, -5, -4, -3, -2, -1, 0, 1]
let x = (0..<10).random           // x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
let x = (-10 ... -2).random       // x = [-10, -9, -8, -7, -6, -5, -4, -3, -2]

पूर्ण नमूना

समाधान (1) और समाधान (2) कोड जोड़ने के लिए मत भूलना

private func generateRandNums(closure:()->(Int)) {

    var allNums = Set<Int>()
    for _ in 0..<100 {
        allNums.insert(closure())
    }
    print(allNums.sorted{ $0 < $1 })
}

generateRandNums {
    (-8..<2).random
}

generateRandNums {
    (0..<10).random
}

generateRandNums {
    (-10 ... -2).random
}

generateRandNums {
    rand(-5, 5)
}
generateRandNums {
    rand[0, 10]
}

नमूना परिणाम


10 (0-9) के बीच यादृच्छिक संख्या के लिए उदाहरण;

import UIKit

let randomNumber = Int(arc4random_uniform(10))

बहुत आसान कोड - सरल और छोटा।


आईओएस 9 के रूप में, आप विभिन्न गेमप्लेकिट कक्षाओं का उपयोग विभिन्न तरीकों से यादृच्छिक संख्या उत्पन्न करने के लिए कर सकते हैं।

आपके पास से चुनने के लिए चार स्रोत प्रकार हैं: एक सामान्य यादृच्छिक स्रोत (अज्ञात, सिस्टम को नीचे जो चुनता है उसे चुनने के लिए), रैखिक संयोग, एआरसी 4 और मेर्सन ट्विस्टर। ये यादृच्छिक इनट्स, फ्लोट्स और बूल उत्पन्न कर सकते हैं।

सबसे सरल स्तर पर, आप सिस्टम के अंतर्निहित यादृच्छिक स्रोत से यादृच्छिक संख्या उत्पन्न कर सकते हैं:

GKRandomSource.sharedRandom().nextInt()

इससे -2,147,483,648 और 2,147,483,647 के बीच एक संख्या उत्पन्न होती है। यदि आप 0 और ऊपरी बाउंड (अनन्य) के बीच की संख्या चाहते हैं तो आप इसका उपयोग करेंगे:

GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

गेमप्लेकिट में पासा के साथ काम करने के लिए निर्मित कुछ सुविधा निर्माता हैं। उदाहरण के लिए, आप इस तरह छः तरफा मर सकते हैं:

let d6 = GKRandomDistribution.d6()
d6.nextInt()

इसके अलावा आप GKShuffledDistribution जैसी चीज़ों का उपयोग करके यादृच्छिक वितरण को आकार दे सकते हैं। यह थोड़ा और समझाता है, लेकिन यदि आप रुचि रखते हैं तो आप गेमप्लेकिट यादृच्छिक संख्याओं पर अपना ट्यूटोरियल पढ़ सकते हैं


आप इसे वैसे ही कर सकते हैं जैसे आप सी में करेंगे:

let randomNumber = arc4random()

randomNumber टाइप UInt32 (एक 32-बिट हस्ताक्षरित पूर्णांक) के अनुमानित है


एक्सकोड के कुछ संस्करणों में arc4Random_uniform () के बिना (7.1 में यह चलता है लेकिन मेरे लिए स्वतः पूर्ण नहीं होता है)। आप इसके बजाय ऐसा कर सकते हैं।

0-5 से यादृच्छिक संख्या उत्पन्न करने के लिए। प्रथम

import GameplayKit

फिर

let diceRoll = GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

मैं मौजूदा उत्तरों में जोड़ना चाहता हूं कि स्विफ्ट बुक में यादृच्छिक संख्या जेनरेटर उदाहरण एक रैखिक संगठनात्मक जनरेटर (एलसीजी) है, यह एक गंभीर रूप से सीमित है और इसे छोटे उदाहरणों को छोड़ना नहीं चाहिए, जहां यादृच्छिकता की गुणवत्ता नहीं होती है बिल्कुल कोई फर्क नहीं पड़ता। और क्रिप्टोग्राफिक उद्देश्यों के लिए कभी भी एलसीजी का उपयोग नहीं किया जाना चाहिए

arc4random() बहुत बेहतर है और अधिकांश उद्देश्यों के लिए इसका उपयोग किया जा सकता है, लेकिन फिर क्रिप्टोग्राफिक उद्देश्यों के लिए उपयोग नहीं किया जाना चाहिए।

यदि आप कुछ ऐसा चाहते हैं जो क्रिप्टोग्राफ़िक रूप से सुरक्षित होने की गारंटी है, तो SecCopyRandomBytes() उपयोग करें। ध्यान दें कि यदि आप किसी चीज़ में यादृच्छिक संख्या जनरेटर बनाते हैं, तो कोई और क्रिप्टोग्राफिक उद्देश्यों (जैसे पासवर्ड, कुंजी या नमक पीढ़ी) के लिए SecCopyRandomBytes() उपयोग कर SecCopyRandomBytes() फिर भी SecCopyRandomBytes() का उपयोग करने पर विचार करना चाहिए, भले ही आपका जरूरत की जरूरत नहीं है।


मैं यादृच्छिक संख्या उत्पन्न करने के लिए इस कोड का उपयोग करता हूं:

//
//  FactModel.swift
//  Collection
//
//  Created by Ahmadreza Shamimi on 6/11/16.
//  Copyright © 2016 Ahmadreza Shamimi. All rights reserved.
//

import GameKit

struct FactModel {

    let fun  = ["I love swift","My name is Ahmadreza","I love coding" ,"I love PHP","My name is ALireza","I love Coding too"]


    func getRandomNumber() -> String {

        let randomNumber  = GKRandomSource.sharedRandom().nextIntWithUpperBound(fun.count)

        return fun[randomNumber]
    }
}

मैंने इस कोड का इस्तेमाल किया:

var k: Int = random() % 10;

यह विधि दी गई न्यूनतम और अधिकतम के बीच एक यादृच्छिक अंतर मान उत्पन्न करेगी

func randomInt(min: Int, max:Int) -> Int {
    return min + Int(arc4random_uniform(UInt32(max - min + 1)))
}

संपादित करें: स्विफ्ट 3.0 के लिए अपडेट किया गया

arc4random स्विफ्ट में अच्छी तरह से काम करता है, लेकिन मूल कार्य 32-बिट पूर्णांक प्रकार तक सीमित हैं ( Int आईफोन 5 एस और आधुनिक मैक पर 64-बिट है)। एक पूर्णांक शाब्दिक द्वारा व्यक्त किए जाने वाले प्रकार की एक यादृच्छिक संख्या के लिए एक सामान्य कार्य यहां दिया गया है:

public func arc4random<T: ExpressibleByIntegerLiteral>(_ type: T.Type) -> T {
    var r: T = 0
    arc4random_buf(&r, MemoryLayout<T>.size)
    return r
}

हम UInt64 का विस्तार करने के लिए इस नए जेनेरिक फ़ंक्शन का उपयोग कर सकते हैं, सीमा तर्क जोड़ सकते हैं और मॉड्यूलो पूर्वाग्रह को कम कर सकते हैं। (यह सीधे arc4random.c से उठाया जाता है)

public extension UInt64 {
    public static func random(lower: UInt64 = min, upper: UInt64 = max) -> UInt64 {
        var m: UInt64
        let u = upper - lower
        var r = arc4random(UInt64.self)

        if u > UInt64(Int64.max) {
            m = 1 + ~u
        } else {
            m = ((max - (u * 2)) + 1) % u
        }

        while r < m {
            r = arc4random(UInt64.self)
        }

        return (r % u) + lower
    }
}

इसके साथ ही हम ओवरफ्लो से निपटने वाले एक ही तर्क के लिए Int64 विस्तार कर सकते हैं:

public extension Int64 {
    public static func random(lower: Int64 = min, upper: Int64 = max) -> Int64 {
        let (s, overflow) = Int64.subtractWithOverflow(upper, lower)
        let u = overflow ? UInt64.max - UInt64(~s) : UInt64(s)
        let r = UInt64.random(upper: u)

        if r > UInt64(Int64.max)  {
            return Int64(r - (UInt64(~lower) + 1))
        } else {
            return Int64(r) + lower
        }
    }
}

परिवार को पूरा करने के लिए ...

private let _wordSize = __WORDSIZE

public extension UInt32 {
    public static func random(lower: UInt32 = min, upper: UInt32 = max) -> UInt32 {
        return arc4random_uniform(upper - lower) + lower
    }
}

public extension Int32 {
    public static func random(lower: Int32 = min, upper: Int32 = max) -> Int32 {
        let r = arc4random_uniform(UInt32(Int64(upper) - Int64(lower)))
        return Int32(Int64(r) + Int64(lower))
    }
}

public extension UInt {
    public static func random(lower: UInt = min, upper: UInt = max) -> UInt {
        switch (_wordSize) {
            case 32: return UInt(UInt32.random(UInt32(lower), upper: UInt32(upper)))
            case 64: return UInt(UInt64.random(UInt64(lower), upper: UInt64(upper)))
            default: return lower
        }
    }
}

public extension Int {
    public static func random(lower: Int = min, upper: Int = max) -> Int {
        switch (_wordSize) {
            case 32: return Int(Int32.random(Int32(lower), upper: Int32(upper)))
            case 64: return Int(Int64.random(Int64(lower), upper: Int64(upper)))
            default: return lower
        }
    }
}

आखिरकार, हम आखिरकार ऐसा कुछ कर सकते हैं:

let diceRoll = UInt64.random(lower: 1, upper: 7)

@ jstn का जवाब अच्छा है, लेकिन थोड़ा वर्बोज़ है। स्विफ्ट को प्रोटोकॉल उन्मुख भाषा के रूप में जाना जाता है, इसलिए हम प्रोटोकॉल एक्सटेंशन के लिए डिफ़ॉल्ट कार्यान्वयन जोड़कर, पूर्णांक परिवार में प्रत्येक वर्ग के लिए बॉयलरप्लेट कोड को लागू किए बिना एक ही परिणाम प्राप्त कर सकते हैं।

public extension ExpressibleByIntegerLiteral {
    public static func arc4random() -> Self {
        var r: Self = 0
        arc4random_buf(&r, MemoryLayout<Self>.size)
        return r
    }
}

अब हम कर सकते हैं:

let i = Int.arc4random()
let j = UInt32.arc4random()

और अन्य सभी पूर्णांक वर्ग ठीक हैं।


 let MAX : UInt32 = 9
 let MIN : UInt32 = 1

    func randomNumber()
{
    var random_number = Int(arc4random_uniform(MAX) + MIN)
    print ("random = ", random_number);
}

var randomNumber = Int(arc4random_uniform(UInt32(**5**)))

यहां 5 सुनिश्चित करेगा कि यादृच्छिक संख्या उत्पन्न होती है हालांकि शून्य से पांच तक। आप तदनुसार मूल्य निर्धारित कर सकते हैं।








random