#stream #scheme #racket #lazy-sequences
#поток #схема #ракетка #ленивые последовательности
Вопрос:
Я пытаюсь написать поток, который принимает в качестве аргументов бесконечный поток S
и два целых m
числа и n
, и возвращает поток, элементами которого являются элементы S
, кратные либо m
или n
.
К сожалению, мой поток работает только до тех пор, пока я не найду первое множественное число, тогда оно не продвинется дальше этого. Я вызываю cdr
при вызове потока, поэтому я не уверен, почему я не смотрю на следующий элемент.
(define stream-car car)
(define (stream-cdr s)
((cadr s)))
(define (divisible? n x)
(zero? (remainder n x)))
(define (stream-cons x s)
(list x (lambda () s)))
;should loop to find the next multiple in the parameter stream
(define (findnext s m n)
(if (or (divisible? (stream-car s) m)
(divisible? (stream-car s) n))
(stream-car s)
(findnext (stream-cdr s) m n)))
;this is my stream
(define (multiples s m n)
(let ((h (findnext s m n)))
;first need to make sure h is a multiple of
;either m or n, THEN create the list
(list h
(lambda ()
(multiples (stream-cdr s) m n)))))
;below is for testing
(define (even-nums-from n)
(list n
(lambda ()
(even-nums-from ( 2 n)))))
(define even-integers
(even-nums-from 0))
;test cases
(multiples even-integers 4 6);should be a stream with car = 0
(stream-car (multiples even-integers 4 6));should be 0
(stream-cdr (multiples even-integers 4 6));should be a stream with car = 4
(stream-car (stream-cdr (multiples even-integers 4 6))) ;should be 4
(stream-cdr (stream-cdr (multiples even-integers 4 6))) ;should be a stream
;starting with 6-not moving past when we find a multiple
(stream-car (stream-cdr (stream-cdr (multiples even-integers 4 6))))
;should be 6
Мой вывод для вышеуказанных тестов:
(list 0 (lambda () ...))
0
(list 4 (lambda () ...))
4
(list 4 (lambda () ...))
4
Я использую DrRacket (advanced student language) и просто не уверен, почему мой поток застрял на этом первом кратном (4). Я вызываю stream-cdr, когда снова вызываю кратные числа, поэтому я не понимаю, где я ошибаюсь. Любые идеи будут высоко оценены.
Ответ №1:
Решаемая проблема заключалась в том, что я не обновлял переданный поток, поскольку нашел следующий множественный. Ниже приведен исправленный код (где я теперь передаю поток с кратным в машине, который будет использоваться в моей multiples
функции):
;returns the stream with car a multiple of either m or n
(define (findnext s m n)
(cond ((divisible? (stream-car s) m) s)
((divisible? (stream-car s) n) s)
(else (findnext (stream-cdr s) m n))))
(define (multiples s m n)
(let ((h (findnext s m n))) ;h is now an updated stream
;with car a multiple of one of m or n
(list (stream-car h)
(lambda ()
(multiples (stream-cdr h) m n)))))