10問目
http://projecteuler.net/index.php?section=problems&id=10
2百万未満の素数の和を求める。
7問目で書いたように、なかなか時間を短縮できず苦しんでいたのですが、何とか実用に耐えるレベルになりました。(コンパイル済みのコードで数秒)
素数の配列の表現がポイント。(他の人のパクリですけど:-P)
main = print $ euler010 2000000 euler010 :: Int -> Integer euler010 n = sum $ map toInteger $ takeWhile (< n) primes primes :: [Int] primes = 2 : filter isPrime [3..] isPrime :: Int -> Bool isPrime x = all ((/= 0) . mod x) $ takeWhile (<= (floor $ sqrt $ fromIntegral x)) primes
検証用に書いたJavaのコードも晒しときます。
import java.util.ArrayList; public class Euler010 { private int limit; private ArrayList<Integer> primes; private long sum = 0; public Euler010(int limit) { this.limit = limit; primes = new ArrayList<Integer>(limit / 3); } private long calc() { for(int i = 2; i < limit; i++) { if (isPrime(i)) { primes.add(i); sum += i; } } return sum; } private boolean isPrime(int i) { int max = (int)Math.sqrt((double)i); int j = 0; while (j < primes.size() && primes.get(j) <= max) { if (i % primes.get(j) == 0) { return false; } j++; } return true; } public static void main(String[] args) { Euler010 p = new Euler010(2000000); System.out.println(p.calc()); } }