素数を小さい方から6つ並べると 2, 3, 5, 7, 11, 13 であり, 6番目の素数は 13 である.
10 001 番目の素数を求めよ.
10 001 番目の素数を求めよ.
エラトステネスのふるいを使えば, 答えは求まりそうです.
- ベクターを用意して, すべての要素を#tにする.
- 配列の添字が2の倍数になっている要素に#fを設定する.もちろん, 2は#tのまま.
- 2より大きな範囲で最初に#tとなっている要素の添字を求める.これが次の素数になる.
- 見つけた素数について, 同様に#fを設定する.
- ベクターの長さの平方根まで処理をすれば終了.
方針に従い, エラトステネスのふるいを実装します.
(require srfi/1)
(define (sieve pv n)
(define (loop i)
(when (< i (vector-length pv))
(vector-set! pv i #f)
(loop (+ i n))))
(loop (+ n n)))
(define (find-prime pv start)
(cond ((<= (vector-length pv) start) #f)
((vector-ref pv start) start)
(else (find-prime pv (+ start 1)))))
(define (eratosthenes pv)
(define (loop n)
(when (and n (< n (sqrt (vector-length pv))))
(sieve pv n)
(loop (find-prime pv (+ n 1)))))
(loop 2))
(define (prime-vector n)
(let ((pv (make-vector (+ n 1) #t)))
(eratosthenes pv)
pv))
(define (prime-vect-to-list pv)
(define (loop ans n)
(if (< n (vector-length pv))
(let ((p (find-prime pv n)))
(if p
(loop (cons p ans) (+ p 1))
(reverse ans)))
(reverse ans)))
(loop () 2))
計算してみます.
ようこそ DrRacket, バージョン 5.3.3 [3m]. 言語: Pretty Big; memory limit: 512 MB. > (prime-vect-to-list (prime-vector 100)) (2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97) > (define pl (prime-vect-to-list (prime-vector 1000000))) > (length pl) 78498 > (list-ref pl 10000) 104743 >
0 件のコメント:
コメントを投稿