随着美国本周大量的15亿美元彩票,我在Ruby中编写了一个函数来制作强力球.在Powerball中,您可以从范围中选择5个数字1..69(没有重复项),并从该范围中选择1个数字1..26.
这就是我想出的:
def pball
Array(1..69).shuffle[0..4].sort + [rand(1..26)]
end
Run Code Online (Sandbox Code Playgroud)
它的工作原理是创建一个从1到69的整数数组,对该数组进行混洗,选择前5个数字,对它们进行排序,最后添加1到26之间的数字.
要在Swift中执行此操作需要更多的工作,因为Swift没有内置shuffle方法Array.
这是我的尝试:
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)]
}
Run Code Online (Sandbox Code Playgroud)
由于没有shuffle方法,因此可以通过[Int]在范围内创建with值来实现1...69.然后它map用于创建[(Int, Double)]一个元组对数组,其中包含数字和Double范围内的随机数0.0 ..< 1.0.然后,它使用Double值对此数组进行排序,并使用秒map返回[Int],然后使用切片[0...4]提取前5个数字并对sort()它们进行排序.
在第二行中,它在范围中附加一个数字1...26.我尝试将其添加到第一行,但Swift给出了错误:
表达太复杂,无法在合理的时间内解决; 考虑将表达式分解为不同的子表达式.
任何人都可以建议如何将其转换为1行功能?也许有更好的方法来选择5个数字1...69.
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]
Run Code Online (Sandbox Code Playgroud)
Swift 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]
Run Code Online (Sandbox Code Playgroud)
我没有发现"单线"概念非常引人注目.有些语言适合它; 别人不这样做.我建议给Swift一个shuffle方法开始:
extension Array {
mutating func shuffle () {
for var i = self.count - 1; i != 0; i-- {
let ix1 = i
let ix2 = Int(arc4random_uniform(UInt32(i+1)))
(self[ix1], self[ix2]) = (self[ix2], self[ix1])
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是由于我做了这个mutating,我们仍然需要不止一行来表达整个操作,因为我们必须var引用我们的起始数组:
var arr = Array(1...69)
(1...4).forEach {_ in arr.shuffle()}
let result = Array(arr[0..<5]) + [Int(arc4random_uniform(26)) + 1]
Run Code Online (Sandbox Code Playgroud)
如果你真的坚持单行,并且你不计算实现所需的代码shuffle,那么你可以通过定义shuffle更多这样的方式来实现它,尽管效率较低:
extension Array {
func shuffle () -> [Element] {
var arr = self
for var i = arr.count - 1; i != 0; i-- {
let ix1 = i
let ix2 = Int(arc4random_uniform(UInt32(i+1)))
(arr[ix1], arr[ix2]) = (arr[ix2], arr[ix1])
}
return arr
}
}
Run Code Online (Sandbox Code Playgroud)
这是你的单行:
let result = Array(1...69).shuffle().shuffle().shuffle().shuffle()[0..<5] + [Int(arc4random_uniform(26)) + 1]
Run Code Online (Sandbox Code Playgroud)
但是哎呀,我省略了你的排序.如果没有出现"太复杂"的错误,我不知道如何做到这一点; 为了解决这个问题,我不得不把它分成两行:
var result = Array(1...69).shuffle().shuffle().shuffle().shuffle()[0..<5].sort(<)
result.append(Int(arc4random_uniform(26)) + 1)
Run Code Online (Sandbox Code Playgroud)
Xcode 10 \xe2\x80\xa2 斯威夫特 4.2
\nSwift 现在添加了shuffled()和ClosedRange,random(in:)现在Int可以在一行中轻松完成此操作:
func pball() -> [Int] {\n return (1...69).shuffled().prefix(5).sorted() + [Int.random(in: 1...26)]\n}\nRun Code Online (Sandbox Code Playgroud)\n进一步修饰:
\n由于 的返回类型pball(),Int可以在方法调用中推断出random。另外,.prefix(5)也可以替换为[...4]. 最后,return可以从一行函数中省略:
func pball() -> [Int] {\n (1...69).shuffled()[...4].sorted() + [.random(in: 1...26)]\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
442 次 |
| 最近记录: |