Схема сита Эратосфена
Я искал в сети реализацию «Решета Эратосфена» в схеме, и, хотя я придумал много контента, ни один из них, похоже, не сделал это так, как мне нужно, чтобы это было сделано.
Проблема в том, что большинство алгоритмов используют либо статическое завершение, либо итерацию. Это в сочетании с моим незнанием языка заставило меня попросить всех вас о помощи.
Мне нужна реализация Sieve, которая принимает один аргумент (число для Sieve до), использует только рекурсию и имеет список «минусов» числа с#t
(правда) или#f
(ложный).
Таким образом, по сути, алгоритм будет выглядеть так:
Составьте список из 2-х чисел, каждый из которых начинается с trueРекурсивно пройти и пометить каждое число, которое делится на 2 ложныхЗатем переходите к следующему «истинному» числу в списке, пока только простые числа не останутся отмеченными как истинные.Вывести списокПример вывода:
> (Эрат-сито 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))
Если бы вы также могли иметь комментарии, подробно объясняющие код, это было бы очень полезно.
Спасибо!
REVISED::: Таким образом, я изучил немного схемы, чтобы далее объяснить мой вопрос ...
Это делает список.
(define (makeList n)
(if (> n 2)
(append (makeList (- n 1)) (list (cons n (and))))
(list (cons 2 (and)))))
Это возвращает список с каждым кратным делителя, помеченного как ложный.
(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))))
Теперь с этой функцией у меня проблемы, похоже, она должна работать, я трижды прошел ее вручную, но не могу понять, почему она не возвращает то, что мне нужно.
(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))))))
То, что я пытаюсь сделать, это, как следует из названия функции, вызывать кратные разметки для каждого числа, которое все еще помечено как истинное в списке. Итак, вы проходите в((3.#t)(4.#t)(5.#t))
а потом это вызываетmark-off-multiples
за 2 и возвращается(3.#t)(4.#f)(5.#t)
и вы добавляете(2.#t)
к этому. Затем он снова называет себя проходящим(3.#t)(4.#f)(5.#t)
и вызывает кратные разметки скорд возвращение списка(4.#f)(5.#t)
и продолжает идти по списку ...
Вывод, который я затем получаю, представляет собой список со всеми истинами.
Это, надеюсь, поможет вам лучше понять мое затруднительное положение.