微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ruby – 一线在斯威夫特生成强力球选择?

随着美国本周超过15亿美元的彩票,我在 Ruby中写了一个功能,让Powerball的选择.在 Powerball中,您可以从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需要更多的工作,因为Swift没有内置的随机播放方法在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)]
}

由于没有随机播放方法,它可以通过创建一个[Int],值范围为1 … 69.然后,它使用地图创建[(Int,Double)],包含数字的元组对数组和范围为0.0 ..< 1.0.然后使用Double值排序此数组,并使用第二个映射返回[Int],然后使用slice [0 ... 4]来提取前5个数字并排序sort()进行排序. 在第二行,它附加一个数字范围1 … 26.我尝试将其添加到第一行,但Swift给出了错误

Expression was too complex to be solved in reasonable time; consider
breaking up the expression into distinct sub-expressions.

任何人都可以建议如何将其变成一线功能?也许有一个更好的方法来选择从1 … 69的5个数字.

解决方法

为了其乐趣,Swift 3的非GameplayKit(长)单行,使用全局 sequence(state:next:)功能从可变状态数组生成随机元素,而不是重排数组(尽管数值数组的变化是5次,所以一些额外的复制操作在这里…)
let powerballNumbers = Array(sequence(state: Array(1...69),next: { 
    (s: inout [Int]) -> Int? in s.remove(at: Int(arc4random_uniform(UInt32(s.count))))})
    .prefix(5).sorted()) + [Int(arc4random_uniform(26) + 1)]

…分解为可读性.

(可能在将来的Swift版本)

如果type inference weren’t broken inout closure parameters(作为关闭的论据),我们可以将以上内容减少到:

let powerballNumbers = Array(sequence(state: Array(1...69),next: {
    $0.remove(at: Int(arc4random_uniform(UInt32($0.count)))) })
    .prefix(5).sorted()) + [Int(arc4random_uniform(26) + 1)]

如果我们也允许以下扩展名

extension Int {
    var rand: Int { return Int(arc4random_uniform(UInt32(exactly: self) ?? 0)) }
}

然后,我们可以继续减少一行:

let powerballNumbers = Array(sequence(state: Array(1...69),next: { $0.remove(at: $0.count.rand) }).prefix(5).sorted()) + [26.rand + 1]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐