2004-07-17 [長年日記]
λ. 素数リスト
RHG読書会後ジョナサンで mini Haskell Marathon と称して数人でコードを書き散らかしたが、その中に僕が書いたコードで素数のリストを以下のように定義するのがあった。
prime :: [Integer]
prime = 2 : [n | n <- [3..], f n]
where f n = all (\p -> n `mod` p /= 0)
(takeWhile (\p -> p <= g n) prime)
g = floor . sqrt . fromInteger
こいつが well-defined であることはさすがに自明ではないな。
考えてみると、3以上の任意の自然数nに対して、
floor(√n) < p < n を満たす素数pが存在すれば、
こいつが takeWhile (\p -> p <= g n)
に対する番兵になって
無限ループに陥らないはずだ。
- n=3 のとき
- floor(√n) = 1 < 2 < 3 = n
- n≧4 のとき
- 「ベルトランの仮説(Bertrand's postulate) 」 ∀n∈N. (n≧2 ⇒ ∃p∈N. Prime(p)∧(n < p < 2n)) から、 ある素数pが存在して floor(√n) < p < 2 floor(√n) で、 ここで 2 floor(√n) ≦ √n floor(√n) ≦ n なので、 floor(√n) < p < n 。
というわけで、問題なしと。
へー、ベルトランの仮説を使うアルゴリズムなんて初めて<br>見ました。<br>\p -> p < g n は \p -> p <= g n ですね?
これを示そうと色々とググっていたんですが、ベルトランの仮説というぴったりの定理を見つけた時には驚きました。自分のお遊びプログラムにそういった定理が関係していたと知るのは、なんだか感慨深いです。<br><br>> \p -> p < g n は \p -> p <= g n ですね? <br><br>あれ〜、どこで間違えたんだろう(^^; 直しときました。<br>ついでにベルトランの仮説の表現もリンク先に合わせてみました。