Пока отвечая на недавний вопрос Я придумал следующий код, реализующий вариант решета Эратосфена, многократно отбрасывающий начальную последовательность 2...n, останавливаясь как можно раньше:
(define (sieve2 n)
(let ((ls (makelist n)))
(let loop ((ls ls)
(next (sievehelper2 ls n)))
(if (null? next)
ls
(cons (car ls)
(loop next (sievehelper2 ls n)))))))
(define (sievehelper2 list n)
(if (> (* (car list) (car list)) n)
'()
(filterfunc (not-divisible-by (car list))
list)))
(define filterfunc filter)
(define (not-divisible-by n)
(let ((m n)) ; the current multiple of n
(lambda (x)
(let ((ret (not (= x m))))
(if (>= x m) (set! m (+ m n)) #f)
ret))))
(define (makelist n)
(range 2 (+ 1 n)))
Однако запуск (sieve 50)
в Racket приводит к '(2 3 3 5 5 7 7 11 11 13 17 19 23 29 31 37 41 43 47)
.
В нем есть какая-то ошибка, что очевидно по результатам, и я не сразу вижу, где она. Это может быть либо какая-то глупая ошибка, которую я сделал, либо выражение какой-то фундаментальной несогласованности используемых алгоритмических частей, и я не могу сказать, что есть что.
Подскажите, что это за ошибка и как ее исправить?
Чтобы было ясно, я не прошу алгоритмических улучшений кода, я хочу вычислительную структуру, выраженную в нем, сохранить. Более того, задача, которую я увидел в связанном вопросе, заключалась в том, чтобы разработать отсутствующие функции - и изменить саму sieve
- при сохранении функции sievehelper
как указано, вплоть до некоторых незначительных изменений, как видно из этого код вопроса. Это также требование, которое я хотел бы указать в этом вопросе.
Меня также не устраивают два обращения к sievehelper2
в sieve2
. Возможно, исправление структуры кода каким-либо образом также устранит ошибку?