Techioz Blog

Swift でパワーボールのピックを生成するためのワンライナー?

概要

今週、米国で 50 億ドルの高額宝くじが行われたため、パワーボールの抽選を行う関数を Ruby で作成しました。パワーボールでは、1 ~ 69 の範囲から 5 つの数字 (重複なし) と、1 ~ 26 の範囲から 1 つの数字を選択します。

これが私が思いついたものです:

def pball
    Array(1..69).shuffle[0..4].sort + [rand(1..26)]
end

これは、1 から 69 までの整数の配列を作成し、その配列をシャッフルし、最初の 5 つの数値を選択し、それらを並べ替えて、最後に 1 から 26 までの数値を加算することで機能します。

Swift には Array に組み込みの shuffle メソッドがないため、これを Swift で行うにはもう少し手間がかかります。

これは私の試みでした:

func pball() -> [Int] {
    let arr = Array(1...69).map{($0, drand48())}.sort{$0.1 < $1.1}.map{$0.0}[0...4].sort()
    return arr + [Int(arc4random_uniform(26) + 1)]
}

shuffle メソッドがないため、1 ~ 69 の範囲の値を持つ [Int] を作成することで機能します。次に、map を使用して [(Int, Double)] を作成します。これは、数値と 0.0 ..< 1.0 の範囲のランダムな Double を含むタプル ペアの配列です。次に、Double 値を使用してこの配列を並べ替え、2 番目のマップを使用して [Int] に戻り、次にスライス [0…4] を使用して最初の 5 つの数値を抽出し、sort() を使用してそれらを並べ替えます。

2 行目には、1 ~ 26 の範囲の数値が追加されます。これを最初の行に追加しようとしましたが、Swift でエラーが発生しました。

これを 1 行の関数に変換する方法を誰かが提案できますか?おそらく、1 ~ 69 から 5 つの数字を選択するより良い方法があるかもしれません。

解決策

Xcode 8.3 • Swift 3.1

import GameKit 

var powerballNumbers: [Int] {
    return (GKRandomSource.sharedRandom().arrayByShufflingObjects(in: Array(1...69)) as! [Int])[0..<5].sorted() + [Int(arc4random_uniform(26) + 1)]
}

powerballNumbers   // [5, 9, 62, 65, 69, 2]

スイフト2.x

import GameKit 

var powerballNumbers: [Int] {
    return (GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(Array(1...69)) as! [Int])[0...4].sort() + [Int(arc4random_uniform(26).successor())]
}

powerballNumbers   // [21, 37, 39, 42, 65, 23]