私はエラトステネスのふるいをスキームで実装するためにウェブを検索してきました、そして私はたくさんのコンテンツを思いついたけれども、それらのどれも私がそれをする必要があるようにそれを成し遂げたようには見えませんでした。
問題は、ほとんどのアルゴリズムが静的終了を使用するか、反復を使用することです。これは私の言語の知識の欠如と相まって、私はあなた方全員に助けを求めるようになりました。
1つの引数(Sieveまでの数値)を取り、再帰のみを使用し、#t
(true)または#f
(false)の数値の「短所」のリストを持つSieveの実装が必要です。
したがって、基本的にアルゴリズムは次のようになります。
- 2からリストを作成-入力された番号。各番号はtrueから始まります
- 再帰的に調べて、2で割り切れる各数値にfalseをマークします。
- 次に、素数だけがtrueとマークされるまで、リスト内の次の「true」番号に進みます。
- リストを出力する
出力例:
>(erat-sieve 20)
((2。#t)(3。#t)(4。#f)(5。#t)(6。#f)(7。#t)(8。#f)(9。#f)( 10。#f)(11。#t)(12。#f)(13。#t)(14。#f)(15。#f)(16。#f)(17。#t)(18。 #f)(19。#t)(20。#f))
コードを徹底的に説明するコメントもいただければ幸いです。
ありがとうございました!
改訂:::それで、私の質問をさらに説明するためのスキームを少し学びました...
これでリストが作成されます。
(define (makeList n)
(if (> n 2)
(append (makeList (- n 1)) (list (cons n (and))))
(list (cons 2 (and)))))
これにより、除数の各倍数がfalseとマークされたリストが返されます。
(define (mark-off-multiples numbers divisor)
(if (null? numbers)
'()
(append
(list (cons (car (car numbers))
(not (zero? (modulo (car (car numbers)) divisor)))))
(mark-off-multiples (cdr numbers) divisor))))
これは私が問題を抱えている関数です。動作するはずです。手動で3回実行しましたが、なぜ必要なものが返されないのかわかりません。
(define (call-mark-off-multiples-for-each-true-number numbers)
(if (null? numbers)
'()
(if (cdr (car numbers))
(append (list (car numbers))
(call-mark-off-multiples-for-each-true-number
(mark-off-multiples (cdr numbers) (car (car numbers)))))
(append (list (car numbers))
(call-mark-off-multiples-for-each-true-number
(cdr numbers))))))
私がやろうとしているのは、関数名が示すように、リストの下でまだtrueとマークされている番号ごとにmark-off-multiplesを呼び出すことです。したがって、パスしてから2を((3.#t)(4.#t)(5.#t))
呼び出しmark-off-multiples
て戻り(3.#t)(4.#f)(5.#t)
、それに追加(2.#t)
します。次に、それ自体が再び渡され(3.#t)(4.#f)(5.#t)
、マークオフ倍数が呼び出され、リストのcdrが返さ(4.#f)(5.#t)
れ、リストを下に移動し続けます...
次に返される出力は、すべてtrueのリストです。
これは、うまくいけば、私の苦境をよりよく理解するのに役立ちます。