swift - ওজন - স্টিভ জবস শিক্ষা




কিভাবে অ্যাপল এর সুইফ্ট ভাষা একটি র্যান্ডম সংখ্যা উৎপন্ন করে? (17)

আমি সুইফ্ট বই একটি র্যান্ডম সংখ্যা জেনারেটরের বাস্তবায়ন উপলব্ধ বুঝতে। নিজের প্রোগ্রামে এই বাস্তবায়ন কপি এবং পেস্ট করার সর্বোত্তম অনুশীলন? নাকি এমন লাইব্রেরি আছে যা আমরা এখন ব্যবহার করতে পারি?


সুইফ্ট 4.2, এক্সকোড 10.1

IOS, MacOS এবং TVOS এর জন্য আপনি Xcode এর ফ্রেমওয়ার্ক GameKit সিস্টেম-ওয়াইড র্যান্ডম উত্স ব্যবহার করতে পারেন। এখানে আপনি GKRandomSource ক্লাসটি তার sharedRandom() শ্রেণী পদ্ধতির সাথে খুঁজে পেতে পারেন:

import GameKit

let number: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

func randomGenerator() -> Int {
    let random = GKRandomSource.sharedRandom().nextInt(upperBound: number.count)
    return number[random]
}
randomGenerator()

অথবা কেবল একটি র্যান্ডমএলমেন্ট randomElement() পদ্ধতি ব্যবহার করুন যা সংগ্রহের একটি এলোমেলো উপাদান প্রদান করে:

let number: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

let randomNumber = number.randomElement()!
print(randomNumber)

arc4random_uniform() ব্যবহার করুন

ব্যবহার:

arc4random_uniform(someNumber: UInt32) -> UInt32

এটি আপনাকে পরিসীমা 0 থেকে someNumber - 1 র্যান্ডম পূর্ণসংখ্যা দেয় someNumber - 1

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
  • 1990 সালে র্যান্ডম বছর

    let year = 1990 + arc4random_uniform(10)

সাধারণ ফর্ম:

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

যেখানে number , max , এবং min UInt32

কি সম্পর্কে...

arc4random ()

আপনি 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 পরিসীমা -2,147,483,648...2,147,483,647 32 বিট সিস্টেমে -9,223,372,036,854,775,808...9,223,372,036,854,775,807 এবং 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,295 সাথে তুলনা করুন 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 পরিসরের মধ্যে রয়েছে এবং আপনি যে UInt32 বাইরের আউটপুটটির প্রয়োজন নেই 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)

এখানে Math Oriented সমাধান (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]
}

নমুনা ফলাফল


0 এবং n-1 এর মধ্যে একটি র্যান্ডম পূর্ণসংখ্যা জন্য arc4random_uniform(n) ব্যবহার করুন।

let diceRoll = Int(arc4random_uniform(6) + 1)

UInt32 ফলাফলটি কাস্ট করুন তাই আপনাকে স্পষ্টভাবে UInt32 (যা UInt32 - UInt32 বলে মনে হয়) হিসাবে আপনার UInt32 টাইপ করতে হবে না।


Xcode এর কিছু সংস্করণে arc4Random_uniform () ছাড়াই (7.1 এটি চালায় তবে আমার জন্য স্বতঃপূর্ণ হয় না)। আপনি পরিবর্তে এটি করতে পারেন।

0-5 থেকে একটি র্যান্ডম সংখ্যা উৎপন্ন করতে। প্রথম

import GameplayKit

তারপর

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

আইওএস 9 হিসাবে, আপনি বিভিন্ন উপায়ে এলোমেলো সংখ্যা জেনারেট করার জন্য গেম গেমপ্লেট ক্লাস ব্যবহার করতে পারেন।

আপনার কাছ থেকে চয়ন করার জন্য চারটি উত্স ধরন রয়েছে: একটি সাধারণ র্যান্ডম উত্স (নামহীন, এটি কী করে তা চয়ন করতে সিস্টেমের নিচে), রৈখিক সংগ্রাহক, এআরসি 4 এবং মারেয়েন টুইস্টার। এই র্যান্ডম ints, floats এবং bools উত্পন্ন করতে পারেন।

সর্বাধিক স্তরে, আপনি সিস্টেমের অন্তর্নির্মিত এলোমেলো উৎস থেকে একটি র্যান্ডম সংখ্যা তৈরি করতে পারেন:

GKRandomSource.sharedRandom().nextInt()

এটি ২,147,483,648 এবং ২147,483,647 এর মধ্যে একটি সংখ্যা তৈরি করে। যদি আপনি 0 এবং উচ্চতর সীমানা (একচেটিয়া) এর মধ্যে একটি সংখ্যা চান তবে আপনি এটি ব্যবহার করবেন:

GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

GameplayKit ডাইস সঙ্গে কাজ করতে নির্মিত কিছু সুবিধা কন্সট্রাক্টর আছে। উদাহরণস্বরূপ, আপনি এই রকম ছয়টি পার্শ্বযুক্ত মরতে পারেন:

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

প্লাস আপনি GKShuffledDistribution মত জিনিস ব্যবহার করে র্যান্ডম বিতরণ আকৃতি করতে পারেন। এটি আরো কিছু ব্যাখ্যা করে, তবে যদি আপনি আগ্রহী হন তবে আপনি GameplayKit র্যান্ডম সংখ্যাগুলিতে আমার টিউটোরিয়ালটি পড়তে পারেন।


আপনি এটা করতে পারেন একই ভাবে আপনি C:

let randomNumber = arc4random()

randomNumber টাইপ UInt32 (একটি 32 বিট স্বাক্ষরিত পূর্ণসংখ্যা) হতে অনুমিত হয়


আমি এই কোডটি ব্যবহার করেছি:

var k: Int = random() % 10;

আমি একটি র্যান্ডম সংখ্যা উৎপন্ন করতে এই কোডটি ব্যবহার করি:

//
//  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]
    }
}

আমি বিদ্যমান উত্তরগুলিতে যোগ করতে চাই যে সুইফ্ট বুকের র্যান্ডম নম্বর জেনারেটরের উদাহরণটি লিনিয়ার কনঙ্গ্রু জেনারেটর (এলসিজি), এটি একটি গুরুতর সীমিত এবং এটি অবশ্যই ছোট ছোট উদাহরণগুলি বাদ ছাড়াই না থাকা উচিত যেখানে র্যান্ডমেশনের গুণমান নেই সব ব্যাপার না। এবং একটি এলসিজি ক্রিপ্টোগ্রাফিক উদ্দেশ্য জন্য ব্যবহার করা উচিত নয়

arc4random() অনেক ভাল এবং বেশিরভাগ উদ্দেশ্যে ব্যবহার করা যেতে পারে, তবে আবার ক্রিপ্টোগ্রাফিক উদ্দেশ্যে ব্যবহার করা উচিত নয়।

যদি আপনি এমন কিছু চান যা ক্রিপ্টোগ্রাফিকভাবে নিরাপদ হতে নিশ্চিত থাকে তবে SecCopyRandomBytes() ব্যবহার করুন। মনে রাখবেন যে আপনি যদি কিছুতে একটি র্যান্ডম সংখ্যা জেনারেটর তৈরি করেন তবে অন্য কেউ এটি ক্রপট্রোগ্রাফিক উদ্দেশ্যে (যেমন পাসওয়ার্ড, কী বা লবণ প্রজন্মের) জন্য ব্যবহার করতে পারে (ভুল) শেষ করতে পারে, তারপরেও আপনি SecCopyRandomBytes() ব্যবহার SecCopyRandomBytes() বিবেচনা করতে পারেন, এমনকি যদি আপনার প্রয়োজন যে বেশ প্রয়োজন হয় না।


নিম্নলিখিত কোড 0 এবং 255 এর মধ্যে একটি নিরাপদ র্যান্ডম সংখ্যা তৈরি করবে:

extension UInt8 {
  public static var random: UInt8 {
    var number: UInt8 = 0
    _ = SecRandomCopyBytes(kSecRandomDefault, 1, &number)
    return number
  }
}

আপনি এটি এই মত কল:

print(UInt8.random)

বড় সংখ্যা জন্য এটি আরও জটিল হয়ে ওঠে।
এই আমি সঙ্গে আসতে পারে শ্রেষ্ঠ:

extension UInt16 {
  public static var random: UInt16 {
    let count = Int(UInt8.random % 2) + 1
    var numbers = [UInt8](repeating: 0, count: 2)
    _ = SecRandomCopyBytes(kSecRandomDefault, count, &numbers)
    return numbers.reversed().reduce(0) { $0 << 8 + UInt16($1) }
  }
}

extension UInt32 {
  public static var random: UInt32 {
    let count = Int(UInt8.random % 4) + 1
    var numbers = [UInt8](repeating: 0, count: 4)
    _ = SecRandomCopyBytes(kSecRandomDefault, count, &numbers)
    return numbers.reversed().reduce(0) { $0 << 8 + UInt32($1) }
  }
}

র্যান্ডম সংখ্যা তৈরি করতে কত UInt8 গুলি ব্যবহার করা হবে তা নির্ধারণ করতে এই পদ্ধতিগুলি একটি অতিরিক্ত র্যান্ডম নম্বর ব্যবহার করে। শেষ লাইন UInt16 বা UInt32[UInt8] রূপান্তরিত করে।

আমি জানি না যে শেষ দুইটি এখনও সত্যিকারের র্যান্ডম হিসাবে গণনা করে, তবে আপনি আপনার পছন্দগুলি এটিকে টিক্চ করতে পারেন :)


সম্পাদনা: সুইফ্ট 3.0 এর জন্য আপডেট করা হয়েছে

arc4random ভাল কাজ করে, তবে বেস ফাংশনগুলি 32-বিট পূর্ণসংখ্যাগুলির প্রকারে সীমিত (আইফোন 5S এবং আধুনিক ম্যাকগুলিতে 64-বিট হয়)। এখানে একটি পূর্ণাঙ্গ ফাংশন একটি র্যান্ডম সংখ্যার জন্য একটি পূর্ণসংখ্যা লিখিত দ্বারা প্রকাশযোগ্য:

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

UInt64 প্রসারিত করার জন্য আমরা এই নতুন জেনেরিক ফাংশনটি ব্যবহার করতে UInt64 , সীমানা আর্গুমেন্ট যোগ এবং মডিউল বায়াস UInt64 । (এই arc4random.c থেকে সরাসরি 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)

সুইফট 4.2

বিদায় বিদায় ফাউন্ডেশন সি আমদানি করতে lib arc4random_uniform()

// 1  
let digit = Int.random(in: 0..<10)

// 2
if let anotherDigit = (0..<10).randomElement() {
  print(anotherDigit)
} else {
  print("Empty range.")
}

// 3
let double = Double.random(in: 0..<1)
let float = Float.random(in: 0..<1)
let cgFloat = CGFloat.random(in: 0..<1)
let bool = Bool.random()
  1. আপনি রেঞ্জ থেকে র্যান্ডম সংখ্যা উৎপন্ন করতে র্যান্ডম (ইন :) ব্যবহার করুন।
  2. র্যান্ডম এলিটমেন্ট () পরিসীমা খালি হলে নিল ফেরত দেয়, তাই আপনি ফিরে আসা ইন্ট্র্যাপটি খালি করবেন? যদি সঙ্গে।
  3. আপনি র্যান্ডম (ইন :) ব্যবহার করে একটি র্যান্ডম ডাবল, ফ্লোট বা CGFloat এবং এলোমেলো () র্যান্ডম () একটি এলোমেলো Bool ফিরে।

আরো @ অফিসিয়াল


সুইফট 4.2

সুইফ্ট 4.2 স্ট্যান্ডার্ড লাইব্রেরীতে একটি নেটিভ এবং মোটামুটি পূর্ণ বৈশিষ্ট্যযুক্ত র্যান্ডম নম্বর API অন্তর্ভুক্ত করেছে। ( সুইফ্ট ইভোলিউশন প্রস্তাব এসই -020২ )

let intBetween0to9 = Int.random(in: 0...9) 
let doubleBetween0to1 = Double.random(in: 0...1)

সমস্ত সংখ্যা ধরনের স্ট্যাটিক random(in:) যা পরিসীমা নেয় এবং প্রদত্ত পরিসরে র্যান্ডম নম্বর প্রদান করে


@ জেএসটিএন এর উত্তর ভাল, কিন্তু একটু ক্রিয়াপদ। সুইফট একটি প্রোটোকল-ভিত্তিক ভাষা হিসাবে পরিচিত, তাই প্রোটোকল এক্সটেনশনটির জন্য ডিফল্ট বাস্তবায়ন যোগ করে, আমরা পূর্ণসংখ্যা পরিবারের প্রতিটি শ্রেণির জন্য বয়লারপ্লেট কোড প্রয়োগ না করেই একই ফলাফল অর্জন করতে পারি।

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()

এবং অন্যান্য সব পূর্ণসংখ্যা ক্লাস ঠিক আছে।


উচ্চমানের র্যান্ডম সংখ্যাগুলির জন্য আদর্শ লাইব্রেরি ফাংশন ব্যবহার করুন: arc4random() অথবা arc4random_uniform() , ঠিক যেমনটি Objective-C তে।

তারা Darwin মডিউলে রয়েছে, তাই আপনি যদি AppKit , UIKit , বা Foundation (যা এটি আপনার জন্য আমদানি করে) আমদানি না করে তবে আপনাকে import Darwin করতে হবে।

সুইফট 4.2

Xcode 10 দিয়ে প্রেরিত সুইফ্ট 4.2 অনেক ডাটা প্রকারের জন্য নতুন ব্যবহারযোগ্য র্যান্ডম ফাংশন প্রবর্তন করে। আপনি সংখ্যাসূচক ধরনের উপর random() পদ্ধতি কল করতে পারেন।

let randomInt = Int.random(in: 0..<6)
let randomDouble = Double.random(in: 2.71828...3.14159)
let randomBool = Bool.random()

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

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





random