Gaucheã§ç´ æ°ã¹ããªã¼ã
ã¨ã©ãã¹ããã¹ã®ç¯©
(define (divisor? x y) (eqv? 0 (remainder x y))) (define-constant +primes+ (stream-cons 2 (stream-filter prime? (stream-iota -1 3 2)))) ;; (define (prime? n) ;; (not (stream-any (cut divisor? n <>) (stream-take-while (cute >= (sqrt n) <>) +primes+)))) (define (prime? n) (let1 limit (sqrt n) (let loop ((srm +primes+)) (let1 x (stream-car srm) (or (< limit x) (if (divisor? n x) #f (loop (stream-cdr srm)))))))) ;(time (stream-ref |+primes+| 10000)) ; real 0.868 ; user 0.840 ; sys 0.020 ; => 104743
stream-take-while ã使ã£ãç㯠5.132s ããã£ãï¼
Gaucheでエラトステネスの篩で素数ストリーム(世間一般のやつより速い) - Gemmaの日記 ã®ã¨æ¯è¼ãã¦ã¿ããï¼åããã®ã¯ 7.792s ããã£ãã®ã§ãã¡ãã®æ¹ã大åéãï¼
ã§ãããã Haskell ã«ç§»æ¤ã㦠Haskell çã§æ¯è¼ãã㨠0.179s 㨠0.123s ã§åããã®æ¹ãéãã£ãï¼
ã¨ãããï¼-O ã¤ãã¦ã³ã³ãã¤ã«ããã¨ã©ã¡ãã 0.104s ãããã§åãã«ãªã£ãâ¦
takeWhile ã使ã㨠0.695s ã¨é
ããªã£ã¦ããã®ã -O ä»ãã§ã¯ 0.078s ã¨ä¸çªéããªã£ãï¼
Haskellã®takeWhileå±éç
primes = 2 : filter isPrime [3,5..] {- isPrime n = not $ any (isDivisor n) $ takeWhile (limit >=) primes where limit = floor $ sqrt $ fromIntegral n -} isPrime n = loop primes where loop (x:xs) | limit < x = True | isDivisor n x = False | otherwise = loop xs where limit = floor $ sqrt $ fromIntegral n isDivisor n m = rem n m == 0 main = print $ primes !! 10000