帝力何有於我哉

無職。汎用人型雑用兵器。型式番号: 高木 宏 ( Hiroshi Takagi )

2011年が連続した素数の合計であることはすごい!か?

2011年と素数

ツィッターで、2011年とは、次の11個の連続した素数の合計である。
2011 = 157 + 163 + 167 + 173 + 179 + 181 + 191 + 193 + 197 + 199 + 211
という話しを聞いた。

2011年は「セクシー素数」の年
http://wiredvision.jp/news/201101/2011010517.html

「すごい」は「美しい」か「めったにない」か

素数フリークな方には、「連続した素数の合計」というだけで、美しくてエクスタシーを感じてしまうものかもしれないが、一般人?な自分としては、どれだけ「めったにないか」、つまり「連続した素数の合計」である数(年号)は、AD1年から2011年までどれだけあったかをRubyで洗い出してみるか、ということに興味が出た。

要件定義

  • 1 〜 2011 について調べる
  • 二つ以上の連続した素数の合計である場合を選び出す

必要なもの

実装

めちゃくちゃべたべたやなあ〜。まあ、動けばいいや、という感じで。is_sum_of_contiguous_primes? は、テストを書いていないので、ちょとあやし〜。

class Fixnum
  def is_prime?
    return false if self == 1
    2.upto(self -1) do |i|
      if self % i == 0
        return false
      end
    end
    return true
  end

  def has_primes_lt_self
    primes = Array.new
    2.upto(self) do |i|
      if i.is_prime?
        primes << i
      end
    end
    primes
  end

  def is_sum_of_contiguous_primes?
    primes = self.has_primes_lt_self

    while primes.size > 0
      primes_for_sum = Array.new
      primes.each do |p|
        primes_for_sum << p
        sum = primes_for_sum.inject(:+)
        break if sum > self
        if sum == self && primes_for_sum.size > 1
          return primes_for_sum
        end
      end
      primes.shift
    end
    return false
  end
end

で、すごかったのか?

このメソッドを使って、以下のプログラムを書いた。タブ区切りで出力しているのは、リダイレクトした出力をExcel で眺めたから。

(2..2011).each do |year|
  if primes = year.is_sum_of_contiguous_primes?
    printf("%d\t", year)
    primes.each do |i|
      printf("%d\t", i)
    end
    puts("\n")
  end
end

結果、2年から2011年の間に、連続した素数の合計であった年号は、790個あった。40%近い出現確率だから、めずらしいとは言えないかも。最近の20年では他に、1993, 1994, 1995, 1998, 1999, 2002, 2006 がある。
特に1998年は、

1998 = 31 + 37 + 41 + 43 + 47 + 53 + 59 + 61 + 67 + 71 + 73 + 79 + 83 + 89 + 97 + 101 + 103 + 107 + 109 + 113 + 127 + 131 + 137 + 139

と24個の連続した素数の和になっている。これはすごいなぁ〜(笑