অ্যাপলের সুইফট ভাষায় কীভাবে একজন এলোমেলো নম্বর তৈরি করতে পারে?


443

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

উত্তর:


466

সুইফট 4.2+

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

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

7
আমাকে স্পষ্টরূপে ডারউইন আমদানি করতে হবে না
ফিননেচেনহেল্প

3
আমার খেলার মাঠের ফাইলে আমার ডারউইন আমদানি করা দরকার কারণ আমি অন্য কিছু আমদানি করছিলাম না।
ডোনালিয়া

সোলিকিউইডি: আরক 4 এর পরে অতিরিক্ত আন্ডারস্কোর বাদ দেওয়া, অর্থাত্ arc4random_uniform (5)।
আলী বিডলে

3
সতর্কতা : RC4 বা arc4 দেখানো হয়েছে হতে বিশুদ্ধ র্যান্ডম মান থেকে পার্থক্যসূচক । তাই যদিও arc4 (একটি স্ট্রিম সাইফার) শোনাচ্ছে ক্রিপ্টোগ্রাফি নিরাপদ, এটা আসলে নয়।
মার্টেন বোদেউইস

2
@ মার্টেনবোডওয়েস: আর এই উত্তরটির সাথে সরাসরি প্রাসঙ্গিক নয়, তবে আরক 4 ব্র্যান্ডম ম্যাকোস বা বিএসডিগুলিতে আরসি 4 সাইফারের নাম সত্ত্বেও বাস্তবে ব্যবহার করে না। এটি ম্যাকোসগুলিতে সিস্টেম-সরবরাহিত সিএসপিআরএনজি এবং বেশিরভাগ বিএসডি-তে চ্যাচ 20 ব্যবহার করে। সুইফ্টের ডিফল্ট আরএনজি (এই উত্তরে ব্যবহৃত হিসাবে) এটিকে ম্যাকওএসের প্রয়োগের বিশদ হিসাবে ডাকে, তবে প্রতিটি সমর্থিত প্ল্যাটফর্মে একটি উপযুক্ত অন্তর্নিহিত জেনারেটর ব্যবহার করে।
স্টিফেন ক্যানন

496

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

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

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


7
খুব সহজ. আমি এটা পছন্দ করি. ভোট দিন! তবে আসল পাশা নেই 0। আপনার কোড, diceRollহতে পারে 0। শুধু বলছি ...
এমকে সাফি

61
হ্যাঁ, আপনি সত্যিই চান Int(arc4random_uniform(6)+1)
মাইকেল ডারস্ট

5
সম্ভাব্যতা = আন্ত (arc4random_uniform (UInt32 (মোট))) - আমাকেও
ইউআইএনটি

4
চলুন এলোমেলো আইলআরএআরএই = = অন্তর্নির্মিত (arc4random_uniform (অ্যারে.কাউন্ট))
কুমারীও

পরামিতি, এন, প্রবেশ নিক্ষেপ করতে ভুলবেন না arc3random_uniform(n)একটি থেকে UInt32(n)আপনি যে ধরনের ইতিমধ্যে নয় একটি মান ব্যবহার করছেন।
ডেভ ফন্টেনট

117

সম্পাদনা: সুইফট 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)

এটা তোলে কম্পাইল করে না: var r = arc4random(UInt64)। আপনি এখানে মানে কি দয়া করে পরামর্শ?
ওসির

@ ওসির আমার জন্য জরিমানা সংকলন করেছেন ... এর অর্থ হল ফাংশনটি arc4random(প্রথম কোড ব্লকে সংজ্ঞায়িত) যুক্তির সাথে কল করুন UInt64যা এ Type
জেস্টন

Arc4random_buf (এবং তাই 64৪-বিট এক্সটেনশনের সবকটি) মডুলো পক্ষপাত্রে ভুগছে?
ম্যাথু সিমন

মডুলো পক্ষপাত কেবল তখনই খেলায় আসে যখন আপনি উপরের বাউন্ড যুক্ত করেন, সুতরাং এটি প্রয়োগ হয় না arc4random_buf। এই এক্সটেনশনের উদ্দেশ্য হ'ল arc4random_uniform-৪-বিট প্রকার বাদে (মডুলো পক্ষপাত প্রশমন) ঠিক কী করে।
jstn

ভাসা কার্যগুলি ব্যবহার করার সময়, আমি কীভাবে সম্ভাবনার পরিসরে উচ্চতর মানটি অন্তর্ভুক্ত করতে পারি? সুতরাং যাক আমি নীচের হিসাবে 0.0 এবং উপরের হিসাবে 1.0 করি 1.0 এই যুক্তি দিয়ে এটি আমাকে 0.99999999 পর্যন্ত 0.0 দেবে। তবে পরিবর্তে আমি সম্ভাবনার হিসাবে 1.0 টি অন্তর্ভুক্ত করতে চাই। আমি কীভাবে এটি অর্জন করতে পারি?
মোবাইলম্যান

80

সুইফট ৪.২ এর জন্য সম্পাদনা করুন

আমদানি করা সি ফাংশন arc4random_uniform () ব্যবহারের পরিবর্তে সুইফট ৪.২ থেকে শুরু করে আপনি এখন সুইফটের নিজস্ব নেটিভ ফাংশন ব্যবহার করতে পারেন।

// Generates integers starting with 0 up to, and including, 10
Int.random(in: 0 ... 10)

আপনি random(in:)অন্যান্য আদিম মানগুলির জন্যও এলোমেলো মান পেতে ব্যবহার করতে পারেন ; যেমন ইন্টার, ডাবল, ফ্লোট এবং এমনকি বুল।

সুইফ্ট সংস্করণ <4.2

এই পদ্ধতি Intপ্রদত্ত ন্যূনতম এবং সর্বাধিকের মধ্যে একটি এলোমেলো মান উত্পন্ন করবে

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

61

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

var k: Int = random() % 10;

20
আপনাকে প্রথমে srandom (UInt32 (সময় (নিল))) কল করতে হবে, অন্যথায় এটি সর্বদা একই সংখ্যা ক্রম ফিরে আসবে
Hola Soy Edu Feliz নাভিদাদ

3
আমি অ্যাপল ডকটি এলোমেলো () এ দু'বার পড়েছি কিন্তু এর ব্যবহারটি সংগ্রহ করতে পারিনি ... আমি আশা করি তারা কেবল উপরে এইরকম একটি সাধারণ কোড নমুনা অন্তর্ভুক্ত করে। "এলোমেলো () ফাংশনটি একটি লিনিয়ার, যোগমূলক প্রতিক্রিয়া, এলোমেলো সংখ্যা জেনারেটর ব্যবহার করে 31 লম্বা পূর্ণ সংখ্যার একটি ডিফল্ট টেবিল নিয়োগ করে 0 এটি 0 থেকে (2 31) -1 এর মধ্যে বিপরীতে সিউডো-এলোমেলো সংখ্যা প্রদান করে The এই এলোমেলো সংখ্যার জেনারেটরের সময়কাল খুব বড়, প্রায় 16 * ((2 31) -1) "" ... আপনাকে প্রচুর আপেল ধন্যবাদ ... আমি আমার পরবর্তী থিসিসে এটি উল্লেখ করতে ভুলবেন না।
nocarrier

1
এলোমেলো () কখনও কখনও আইপ্যাডগুলিতে হঠাৎ ক্রাশের দিকে পরিচালিত করে। যদি এটি হয় তবে উপরের থেকে arc4random_uniform (6) ব্যবহার করুন। আপনি যদি এলোমেলো () ব্যবহার করেন তবে আপনি শ্রেনডেমদেব () প্রিপেন্ড করে আরও এলোমেলো মান তৈরি করতে পারেন।
জ্যাকপিয়ার্স

1
আমি সংকলক ত্রুটির বার্তা পেয়েছি:random is unavailable in Swift: Use arc4random instead.
মাইক কেসকিনভ

1
এই সমাধানটির মডুলো পক্ষপাত রয়েছে: zuttobenkyou.wordpress.com/2012/10/18/…
rgov

33

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

আপনার চয়ন করতে চারটি উত্স প্রকার রয়েছে: একটি সাধারণ এলোমেলো উত্স (নাম না দিয়ে, এটি কী করে তা বেছে নেওয়ার জন্য সিস্টেমের কাছে), লিনিয়ার কংগ্র্যাশিয়াল, এআরসি 4 এবং মের্সেন টুইস্টার। এগুলি এলোমেলো ints, ভাসমান এবং bools উত্পাদন করতে পারে।

সহজ স্তরে আপনি সিস্টেমের অন্তর্নির্মিত এলোমেলো উত্স থেকে এলোমেলো সংখ্যা তৈরি করতে পারেন:

GKRandomSource.sharedRandom().nextInt()

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

GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

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

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

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


1
এই পরামর্শের জন্য ধন্যবাদ, এটি সেরা উত্তরগুলির মধ্যে একটি। এই ফাংশনগুলি ব্যবহার করার জন্য একটি যুক্ত করা দরকার import GameplayKit। সুইফট 3 সিনট্যাক্সটি পরিবর্তন করেছেGKRandomSource.sharedRandom().nextInt(upperBound: 6)
পেট্রসিন

7
এই কিটটি আমদানি করতে কতটা ভারী? আমি আমার কোডটি ফুটিয়ে তুলতে চাই না।
λαβέ.λαβέ

25

আপনি সি তে যেভাবে চান তেমনভাবে এটি করতে পারেন:

let randomNumber = arc4random()

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


12
সংযোজন: rand, arc4random, drand48এবং বন্ধুদের সব আছে Darwinমডিউল। আপনি যদি কোকো, ইউআইকিট বা ফাউন্ডেশন অ্যাপ্লিকেশন তৈরি করে থাকেন তবে এটি ইতিমধ্যে আপনার জন্য আমদানিকৃত import Darwin
রিক্সার

5
আরক 4 ব্র্যান্ডম () এর ফলাফলটি একটি ইন্টার-তে ফেলে দেওয়ার চেষ্টা করবেন না - এটি 64৪-বিট প্ল্যাটফর্মের ক্ষেত্রে দুর্দান্ত কাজ করবে, তবে একটি 32-বিট প্ল্যাটফর্মে, ইনটগুলি 32-বিট স্বাক্ষরিত, সুতরাং আপনি অপ্রত্যাশিত নেতিবাচক পাবেন নম্বর। এটি ইতিমধ্যে কয়েক জনকে ছড়িয়ে দিয়েছে, তাই আমি অনুভব করেছি যে আমি এটি এখানে উল্লেখ করব।
ম্যাট গিবসন

23

ব্যবহার arc4random_uniform()

ব্যবহার:

arc4random_uniform(someNumber: UInt32) -> UInt32

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

এর সর্বাধিক মান UInt324,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 এর দশকের এলোমেলো বছর year

    let year = 1990 + arc4random_uniform(10)

সাধারণ ফর্ম:

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

কোথায় number, maxএবং minহয় UInt32

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

arc4random ()

আপনি ব্যবহার করেও এলোমেলো নম্বর পেতে পারেন arc4random()যা UInt320 থেকে 2 ^ 32-1 এর মধ্যে উত্পাদন করে । এভাবে মধ্যে একটি র্যান্ডম সংখ্যা পেতে 0এবং x-1আপনি এটি দ্বারা বিভক্ত করতে xএবং বাকি নিতে। বা অন্য কথায়, রিমাইন্ডার অপারেটর (%) ব্যবহার করুন :

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

যাইহোক, এটি সামান্য মডুলো পক্ষপাত তৈরি করে ( এখানে এবং এখানেও দেখুন ), তাই এজন্যই arc4random_uniform()প্রস্তাবিত।

থেকে এবং থেকে রূপান্তর করা Int

সাধারণত এবং এর মধ্যে Intএবং পিছনে রূপান্তর করার জন্য এই জাতীয় কিছু করা ভাল UInt32:

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

সমস্যা নেই, যদিও, যে হয় Intএকটি পরিসীমা আছে -2,147,483,648...2,147,483,64732 বিট সিস্টেমে এবং একটি সীমার -9,223,372,036,854,775,808...9,223,372,036,854,775,80764 বিট সিস্টেমে। এর UInt32ব্যাপ্তির সাথে তুলনা করুন 0...4,294,967,295Uএর UInt32মানে স্বাক্ষরবিহীন

নিম্নলিখিত ত্রুটিগুলি বিবেচনা করুন:

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

সুতরাং আপনাকে কেবল নিশ্চিত হওয়া দরকার যে আপনার ইনপুট পরামিতিগুলি UInt32সীমার মধ্যে রয়েছে এবং আপনারও সেই পরিসরের বাইরে যে আউটপুট দরকার নেই।


19

10 (0-9) এর মধ্যে র্যান্ডম সংখ্যার উদাহরণ;

import UIKit

let randomNumber = Int(arc4random_uniform(10))

খুব সহজ কোড - সহজ এবং সংক্ষিপ্ত।


16

আমি কেবল rand()একটি এলোমেলো সিন্ট পেতে ব্যবহার করতে সক্ষম হয়েছি। আপনি এ জাতীয় কিছু ব্যবহার করে এটি একটি ইন্টার তৈরি করতে পারেন:

let myVar: Int = Int(rand())

আপনি আপনার পছন্দসই সি র্যান্ডম ফাংশনটি ব্যবহার করতে পারেন এবং প্রয়োজনে কেবল মানকে রূপান্তর করতে পারেন।


হ্যাঁ, ধরণের রূপান্তরটি অন্যথায় একটি জটিল ব্যবসা হতে পারে এবং এটির সাথে ইন্ট্রাস্ট্রাক্টরকে ডিল করা প্রকৃত ব্যথা সেভার।
Kzrbill

4
মনে রাখবেন যে আপনি র‌্যাণ্ড () ব্যবহারের আগে যদি শ্রেনড (...) (কেবল একবার কল করুন) কল না করেন তবে সংখ্যার ক্রমটি সর্বদা আপনার প্রোগ্রামের প্রতিটি সম্পাদনের মধ্যে ঠিক একই রকম হবে। আপনি যদি এটি না চান তবে arc4random ()
সোমগু

2
আপনি এটি ব্যবহার করতে পারতেন random(), যা Intপরিবর্তে পরিবর্তিত হয় UInt32- এবং @ সুমগুয়ের উল্লেখ করা মত, srandom(arc4random())এটি আপনার প্রোগ্রামের প্রতিটি সম্পাদনের জন্য আলাদা, এলোমেলোভাবে বীজ রয়েছে তা নিশ্চিত করার জন্য এটি ব্যবহার করার আগে একবারে কেবল কল করুন ।
brittlewis12

1
কেউ কি র‌্যান্ড () বনাম arc4random_uniform () এ মন্তব্য করতে পারে?
রুবেন মার্টিনেজ জুনিয়র

16

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

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

এবং অন্যান্য সমস্ত সংখ্যার ক্লাস ঠিক আছে।


11

ইন সুইফট 4.2 আপনি কল করে র্যান্ডম সংখ্যা তৈরি করতে পারেন random()যাই হোক না কেন সাংখ্যিক ধরনের চান তার উপর পদ্ধতি পরিসীমা আপনার সাথে কাজ করতে চান করে। উদাহরণস্বরূপ, এটি উভয় পক্ষের সমেত 1 থেকে 9 রেঞ্জের এলোমেলো সংখ্যা উত্পন্ন করে

let randInt = Int.random(in: 1..<10)

অন্যান্য প্রকারের সাথেও

let randFloat = Float.random(in: 1..<20)
let randDouble = Double.random(in: 1...30)
let randCGFloat = CGFloat.random(in: 1...40)

9

এখানে একটি লাইব্রেরি রয়েছে যা https://github.com/thellimist/SwiftRandom এ কাজটি ভাল করে

public extension Int {
    /// SwiftRandom extension
    public static func random(lower: Int = 0, _ upper: Int = 100) -> Int {
        return lower + Int(arc4random_uniform(UInt32(upper - lower + 1)))
    }
}

public extension Double {
    /// SwiftRandom extension
    public static func random(lower: Double = 0, _ upper: Double = 100) -> Double {
        return (Double(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
    }
}

public extension Float {
    /// SwiftRandom extension
    public static func random(lower: Float = 0, _ upper: Float = 100) -> Float {
        return (Float(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
    }
}

public extension CGFloat {
    /// SwiftRandom extension
    public static func random(lower: CGFloat = 0, _ upper: CGFloat = 1) -> CGFloat {
        return CGFloat(Float(arc4random()) / Float(UINT32_MAX)) * (upper - lower) + lower
    }
}


6

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

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

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


6

থেকে সুইফট 4.2

এপিআইগুলির একটি নতুন সেট রয়েছে:

let randomIntFrom0To10 = Int.random(in: 0 ..< 10)
let randomDouble = Double.random(in: 1 ... 10)
  • সমস্ত সংখ্যার ধরণের এখন random(in:)পদ্ধতি রয়েছে range

  • এটি এই ব্যাপ্তিতে সমানভাবে বিতরণ করা একটি সংখ্যা প্রদান করে।


টি এল; ডিআর

আচ্ছা, "ভাল" পুরানো পথে কী ভুল?

  1. আপনি আমদানিকৃত ব্যবহার করতে হবে সি API গুলি (তারা প্ল্যাটফর্মের মধ্যে ভিন্ন)

  2. এবং তাছাড়া...

যদি আমি আপনাকে বলি যে এলোমেলো যে এলোমেলো নয়?

যদি আপনি arc4random() (বাকি গণনা করতে) পছন্দ মতো ব্যবহার করেন arc4random() % aNumberতবে ফলাফলটি এবং এর মধ্যে অভিন্নভাবে বিতরণ করা হয় নামডুলো বায়াস নামে একটি সমস্যা রয়েছে ।0aNumber

মডুলো পক্ষপাতিত্ব

সাধারণত, ফাংশনটি ম্যাক্স0 এবং ম্যাক্সের মধ্যে একটি এলোমেলো সংখ্যা তৈরি করে (ধরণের ইত্যাদির উপর নির্ভর করে) । একটি দ্রুত, সহজ উদাহরণ বানাতে, আসুন আমরা সর্বোচ্চ সংখ্যাটি বলে থাকি 7এবং আপনি পরিসীমাটিতে একটি এলোমেলো সংখ্যার 0 ..< 2 (বা অন্তর [0, 3) এর বিষয়ে যত্নশীল হন যদি আপনি এটি পছন্দ করেন)

সম্ভাব্যতা পৃথক সংখ্যার জন্য আছেন:

  • 0: 3/8 = 37.5%
  • 1: 3/8 = 37.5%
  • 2: 2/8 = 25%

অন্য কথায়, আপনি 2 বা 1 এর চেয়ে 0 বা 1 দিয়ে শেষ হওয়ার সম্ভাবনা বেশি । অবশ্যই, মনে রাখবেন যে এটি অত্যন্ত সরল এবং ম্যাক্স সংখ্যাটি আরও বেশি, এটি আরও "ন্যায্য" করে তোলে।

এই সমস্যাটি SE-0202 - সুইফট 4.2র্যান্ডম একীকরণ দ্বারা সম্বোধন করা হয়েছে


5

এক্সকোডের কিছু সংস্করণে আরক 4 র‌্যান্ডম_উনিফর্ম () ছাড়াই (.1.১ এ এটি চালিত হয় তবে আমার জন্য স্বতঃপূরণ হয় না)। পরিবর্তে আপনি এটি করতে পারেন।

0-5 থেকে একটি এলোমেলো সংখ্যা তৈরি করতে। প্রথম

import GameplayKit

তারপর

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

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

এখানে 5 এটি নিশ্চিত করবে যে এলোমেলো সংখ্যাটি শূন্য থেকে চারটির মধ্যে উত্পন্ন হয়। আপনি সেই অনুযায়ী মান সেট করতে পারেন।


1
যদি আপনি 5 পাস করেন তবে এটি 5 থেকে 4 টি ফলাফল শূন্য থেকে চারে ফিরে আসবে। 0 ... 4
লিও ডাবাস

3

সুইফট 4.2

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

আরও @ সরকারী


2

নিম্নলিখিত কোডটি 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করে যে এলোমেলো সংখ্যা তৈরি করতে কতগুলি ব্যবহার করা হবে। শেষ লাইনটি পরিবর্তন করে [UInt8]করতে UInt16বা UInt32

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


আপনি চতুরতার সাথে Modulo দ্বারা প্রবর্তিত পক্ষপাত, এ জন্য +1 এড়ানো। আপনি পাঠকদের সতর্ক করতে পারেন আপনি এটি কেন করেছিলেন।
jww

এটি আকর্ষণীয়, আমি সত্যিই বিবেচনা করি নি যে এখানে মডুলো পক্ষপাতমূলক আচরণ হতে পারে। সম্ভবত একটি ছোট সংখ্যা পাওয়ার সম্ভাবনা বড় সংখ্যা পাওয়ার অনুরূপ নয় are
জাইফ্রাক্স

2

সুইফট 4.2

সুইফট ৪.২ স্ট্যান্ডার্ড লাইব্রেরিতে একটি নেটিভ এবং মোটামুটি পূর্ণ বৈশিষ্ট্যযুক্ত এলোমেলো সংখ্যার এপিআই অন্তর্ভুক্ত করেছে। ( সুইফট বিবর্তনের প্রস্তাব এসই -0202 )

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

সমস্ত সংখ্যার ধরণের স্থির র্যান্ডম থাকে (ইন :) যা পরিসীমা নেয় এবং প্রদত্ত পরিসরটিতে এলোমেলো নম্বর প্রদান করে


1

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

আইওএস, ম্যাকোস এবং টিভিওএসের জন্য আপনি এক্সকোডের কাঠামোর মধ্যে সিস্টেম-ব্যাপী র্যান্ডম উত্স ব্যবহার করতে পারেন 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)

0

আপনি এটির GeneratorOfমতো ব্যবহার করতে পারেন :

var fibs = ArraySlice([1, 1])
var fibGenerator = GeneratorOf{
    _ -> Int? in
    fibs.append(fibs.reduce(0, combine:+))
    return fibs.removeAtIndex(0)
}

println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())

3
ফিবোনাচি এলোমেলোভাবে কেমন?
নিকোলাই রুহে

হাই নিকোলাই, এই কোড ব্লকটি পুরানো সংস্করণ সুইফট 1.2। আপনি যদি নতুন সুইফট ২.০ চেষ্টা করেন। এটা কাজ হবে না।
দুরুল ডালকনাট

2
আমি বুঝতে পেরেছি, তবে তবুও এটি আমার কাছে ফাইবোনাকি জেনারেটরের মতো, এলোমেলো সংখ্যার মতো নয়, যেমন প্রশ্নে জিজ্ঞাসা করেছিল।
নিকোলাই রুহে

0

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

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

2
তাই আপনাকে স্বাগতম। কোডের উত্তরগুলি নিরুৎসাহিত করা হয় - কেন এই কোডটি প্রশ্নের উত্তর দেয় এবং এটি কীভাবে কাজ করে তা ব্যাখ্যা করার জন্য দয়া করে আপনার উত্তর সম্পাদনা করুন। আরও তথ্যের জন্য stackoverflow.com/help/how-to-answer দেখুন।
টিম ম্যালোন

2
আপনার উত্তরের আশেপাশে কিছু প্রসঙ্গ সরবরাহ করুন এবং স্ট্যাকওভারফ্লোতে স্বাগতম। :)
জোনাথন ইউস্টেস

0

বিস্তারিত

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

নমুনা ফলাফল

এখানে চিত্র বর্ণনা লিখুন


2
এই উত্তরটি বিষয় ছাড়াই is প্রশ্নটি ছিল কীভাবে একটি এলোমেলো সংখ্যা তৈরি করা যায়। কিভাবে এলোমেলো নম্বর লাইব্রেরি তৈরি করবেন তা নয়। Sheesh।
অ্যান্ড্রু পল সিমন্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.