【问题标题】:Project Euler #35 - Circular Primes欧拉计划 #35 - 圆形素数
【发布时间】:2015-04-14 13:57:45
【问题描述】:

我正在尝试解决Project Euler's problem #35 的问题:

数字 197 被称为圆素数,因为数字的所有旋转:197、971 和 719 本身都是素数。

100 以下的素数有 13 个:2、3、5、7、11、13、17、31、37、71、73、79 和 97。

一百万以下有多少个圆素数?

为了解决这个问题,我在 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 的正确结果和正确的循环素数,但最后我一直得到错误的结果,看不出问题出在哪里。

【问题讨论】:

  • 您可能还需要考虑,而不是使用 C 样式的 for 循环,而是使用 for...in 循环以及使用 mapreduce。这样做会使您的代码更容易理解,并有助于发现错误(尽管可能不是这个)。 Here's 使用这些技术的等效程序(有同样的问题)。
  • @AirspeedVelocity 感谢您的建议,作为来自 C 背景的人,我倾向于使用这种循环,但我肯定会考虑改用它。

标签: swift primes


【解决方案1】:

我不想剥夺您寻找 PE 解决方案的乐趣,因此 我只给出一个提示:

检查rotations(getArray(N)) 的输出中是否有数字N 与3 或更多位数。这不是您所期望的(但可以轻松修复)。

【讨论】:

    【解决方案2】:

    我认为Martin在他的回答中指出了你的问题,不过我认为在这类问题中效率也很重要。

    我对改进代码的建议是在您的 Eratosthenes 筛中,您可以通过更改以下行来改进它:

    for i in 2..<primes.count
    

    对于这个:

    for (var i = 2; i * i <= primes.count; ++i)
    

    以上改进只执行不超过rootn的简单筛选。

    你可以做更多的改进,但取决于你,我强烈推荐你在编程比赛中有经验的俄罗斯程序员的以下两篇文章:

    你必须翻译它才能阅读它,因为它是俄语,但你可以使用谷歌翻译。

    希望对你有所帮助。

    【讨论】:

    • 有一个专门的站点codereview.stackexchange.com 用于审查工作代码,因此如果 OP 修复了代码,他可能会将其发布在那里以进行可能的改进。
    【解决方案3】:

    一个提示。考虑一下如果您的起始素数在旋转之前包含数字“8”会发生什么。

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多