欧拉计划 #35 - 圆素数
Project Euler #35 - Circular Primes
我正在尝试解决 Project Euler's problem #35 问题:
The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.
There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.
How many circular primes are there below one million?
为了解决问题,我在 Swift 中使用了以下代码:
let size = 1000000
func ESieve(x : Int) -> [Bool] {
var primes = [Bool](count: x + 1, repeatedValue: true)
primes[0] = false
primes[1] = false
for var i = 2; i < primes.count; i++ {
if !primes[i] {
continue
}
for (var j = 2*i; j < primes.count; j += i) {
primes[j] = false
}
}
return primes
}
let sieve = ESieve(size)
func getPrimes() -> [Int] {
var array = [Int]()
for (var i = 0; i < sieve.count; i++) {
if sieve[i] {
array.append(i)
}
}
return array
}
let primes = getPrimes()
func rotations(v : [Int]) -> [Int] {
var result = [Int]()
for (var i = 0; i < v.count; i++) {
var r = 0
for (var j = i; j < v.count + i; j++) {
r = 10*r + v[j % v.count]
}
result.append(r)
}
return result
}
func getArray(x : Int) -> [Int] {
var array = [Int]()
var i = x
while i > 0 {
array.append(i%10)
i /= 10
}
return array
}
func isAllPrime(v : [Int]) -> Bool {
for i in v {
if !sieve[i] {
return false
}
}
return true
}
var s = 0
for (var i = 0; i < primes.count; i++) {
var array = getArray(primes[i])
var perms = rotations(array)
if isAllPrime(perms) {
s++
}
}
println(s)
所有功能似乎都能正常使用。即使我将 size
设置为 100,我也得到了正确的圆素数 13 的正确结果,但最后我一直得到错误的结果,看不出问题出在哪里。
我不想剥夺您寻找 PE 解决方案的乐趣,因此
我只会给出一个提示:
检查 rotations(getArray(N))
的输出,其中数字 N
为 3
或更多数字。这不是您所期望的(但可以轻松修复)。
我以为马丁在他的回答中指出了你的问题,不过我认为在这种问题中效率也很重要。
我对改进代码的建议在你的埃拉托色尼筛法中,你可以通过更改以下行来改进它:
for i in 2..<primes.count
对于这个:
for (var i = 2; i * i <= primes.count; ++i)
以上改进仅进行不超过根的简单筛分n
。
你可以做更多的改进,但这取决于你,我强烈推荐你以下两篇编程竞赛中经验丰富的俄罗斯编码员的文章:
您必须翻译它才能阅读,因为它是俄语,但您可以使用 google 翻译器。
希望对你有所帮助。
一个提示。考虑一下如果您的起始质数在旋转之前包含数字“8”会发生什么。
我正在尝试解决 Project Euler's problem #35 问题:
The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.
There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.
How many circular primes are there below one million?
为了解决问题,我在 Swift 中使用了以下代码:
let size = 1000000
func ESieve(x : Int) -> [Bool] {
var primes = [Bool](count: x + 1, repeatedValue: true)
primes[0] = false
primes[1] = false
for var i = 2; i < primes.count; i++ {
if !primes[i] {
continue
}
for (var j = 2*i; j < primes.count; j += i) {
primes[j] = false
}
}
return primes
}
let sieve = ESieve(size)
func getPrimes() -> [Int] {
var array = [Int]()
for (var i = 0; i < sieve.count; i++) {
if sieve[i] {
array.append(i)
}
}
return array
}
let primes = getPrimes()
func rotations(v : [Int]) -> [Int] {
var result = [Int]()
for (var i = 0; i < v.count; i++) {
var r = 0
for (var j = i; j < v.count + i; j++) {
r = 10*r + v[j % v.count]
}
result.append(r)
}
return result
}
func getArray(x : Int) -> [Int] {
var array = [Int]()
var i = x
while i > 0 {
array.append(i%10)
i /= 10
}
return array
}
func isAllPrime(v : [Int]) -> Bool {
for i in v {
if !sieve[i] {
return false
}
}
return true
}
var s = 0
for (var i = 0; i < primes.count; i++) {
var array = getArray(primes[i])
var perms = rotations(array)
if isAllPrime(perms) {
s++
}
}
println(s)
所有功能似乎都能正常使用。即使我将 size
设置为 100,我也得到了正确的圆素数 13 的正确结果,但最后我一直得到错误的结果,看不出问题出在哪里。
我不想剥夺您寻找 PE 解决方案的乐趣,因此 我只会给出一个提示:
检查 rotations(getArray(N))
的输出,其中数字 N
为 3
或更多数字。这不是您所期望的(但可以轻松修复)。
我以为马丁在他的回答中指出了你的问题,不过我认为在这种问题中效率也很重要。
我对改进代码的建议在你的埃拉托色尼筛法中,你可以通过更改以下行来改进它:
for i in 2..<primes.count
对于这个:
for (var i = 2; i * i <= primes.count; ++i)
以上改进仅进行不超过根的简单筛分n
。
你可以做更多的改进,但这取决于你,我强烈推荐你以下两篇编程竞赛中经验丰富的俄罗斯编码员的文章:
您必须翻译它才能阅读,因为它是俄语,但您可以使用 google 翻译器。
希望对你有所帮助。
一个提示。考虑一下如果您的起始质数在旋转之前包含数字“8”会发生什么。