Life Goes On

まあまあだけど楽しんでる方です

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());
    }

}