Problem 187
コンテンツ
http://projecteuler.net/index.php?section=problems&id=187
まぁ,関数型ではやりにくい.
とりあえず,javaで.
非常にシンプルな,ふるいを使ったアルゴリズム.
import java.util.Arrays; public class P187{ public static void main(String[] args){ int n = 100000000,c=; boolean[] prime = new boolean[n]; Arrays.fill(prime,true); for(int i=2,m=(int)Math.sqrt(n);i<m;i++) if(prime[i]) for(int j=i*i;j<n;j+=i) prime[j]=false; // sieve prime for(int i=2;i<n;i++){ if(prime[i]) continue; for(int j=2*i;j<n;j+=i)prime[j]=true; // sieve semiprime c++; } System.out.println(c); } }
あまり,速くない.
2回目のふるいの効率が良くない.
実は,公式が存在した.
import java.util.Arrays; public class P187_1{ public static void main(String[] args){ int n = 100000000, m=(int)Math.sqrt(n); boolean[] prime = new boolean[n/2+1]; Arrays.fill(prime,true); int[] pi = new int [n/2+1]; for(int i=2 ; i<n/2+1 ; i++) if(prime[i]){ if(i<m) for(int j = i*i ; j < n/2+1 ; j+=i) prime[j] = false; // sieve prime pi[i] = pi[i-1]+1; }else pi[i] = pi[i-1]; int count = ; for(int i=2 ;i <=m ;i++) if(prime[i]) count+=pi[n/i]-pi[i]+1; System.out.println(count); } }
同じアルゴリズムをhaskellで実装すると…
{-# LANGUAGE BangPatterns #-} import Control.Monad.ST (ST,runST) import Control.Monad (when) import Data.Array.ST (STUArray,newArray,readArray,writeArray) p187 n = do q <- newArray (2,div n 2) True :: ST s (STUArray s Int Bool) p <- newArray (1,div n 2) :: ST s (STUArray s Int Int) let m = floor.sqrt.fromIntegral $ n countP !i | i > div n 2 = return () | otherwise = do q_i <- readArray q i if q_i then do when (i<m) $ sieve i (i*i) readArray p (i-1) >>= writeArray p i.(1+) countP (i+1) else do readArray p (i-1) >>= writeArray p i countP (i+1) sieve !i !j | j > div n 2 = return () | otherwise = writeArray q j False >> sieve i (j+i) semiPrime !c !i | i > m = return c | otherwise = do q_i <- readArray q i if q_i then do p1 <- readArray p (div n i) p2 <- readArray p i semiPrime (c+p1-p2+1) (i+1) else semiPrime c (i+1) countP 2 semiPrime 2 main = print.runST $ p187 (10^8)
どうなんでしょうね?
全然,関数型らしくない.
作成者 Toru Mano
最終更新時刻 2023-01-01 (c70d5a1)