最も単純な解決策は、相互に再帰的な関数のペアです。
最初の関数は、すべての素数を生成します。
- 1 より大きいすべての自然数のリストから始めます。
- 素数でないすべての数を削除します。つまり、(それ自体以外に) 素因数を持たない数値です。下記参照。
2 番目の関数は、指定された数値の素因数n
を昇順で返します。
- すべての素数のリストを取得します (上記を参照)。
- の因数ではないすべての数を削除します
n
。
の最大の素因数n
は、2 番目の関数によって与えられる最後の数値です。
このアルゴリズムには、遅延リストまたは必要に応じた呼び出しのセマンティクスを備えた言語 (またはデータ構造) が必要です。
明確にするために、Haskellでの上記の(非効率的な)実装の1つを次に示します。
import Control.Monad
-- All the primes
primes = 2 : filter (ap (<=) (head . primeFactors)) [3,5..]
-- Gives the prime factors of its argument
primeFactors = factor primes
where factor [] n = []
factor xs@(p:ps) n =
if p*p > n then [n]
else let (d,r) = divMod n p in
if r == 0 then p : factor xs d
else factor ps n
-- Gives the largest prime factor of its argument
largestFactor = last . primeFactors
これを高速化するには、どの数値が の素数および/または因数であるかをより賢く検出するだけの問題ですn
が、アルゴリズムは同じままです。