gpt4 book ai didi

scheme - 通过高阶累积过程展平Scheme中的惰性列表的惰性列表

转载 作者:行者123 更新时间:2023-12-02 04:15:03 27 4
gpt4 key购买 nike

我正在尝试找到一种实现,它使用我编写的过程“interleave”和“lz-lst-accumulate”来展平惰性列表的惰性列表。这是到目前为止的代码:

(define lz-lst-accumulate
(lambda (op initial lz)
(if (empty? lz)
initial
(op (head lz)
(lambda() (lz-lst-accumulate op initial (tail lz)))))))

(define interleave
(lambda (lz1 lz2)
(if (empty? lz1)
(lz2)
(cons (head lz1)
(interleave (lz2) (lambda() (tail lz1)))))))

(define all-div-from-flattened
(lambda (lower)
(lz-lst-accumulate interleave '() (all-div-from lower))))

(define take
(lambda (lz-lst n)
(if (= n 0)
(list)
(cons (car lz-lst)
(take (tail lz-lst) (sub1 n))))))

(define head
(lambda (lz)
(car lz)))

(define tail
(lambda (lz-lst)
((cdr lz-lst))))

(define lz-lst-map
(lambda (f lz)
(if (empty? lz)
lz
(cons (f (head lz))
(lambda () (lz-lst-map f (tail lz)))))))

; Signature: all-div-from (low)
; Type: [Number -> Lazy-list]
; Purpose: return a lazy-list of lazy-lists. The nested lazy-lists
; correspond to the integers greater than lower in an
; increasing order. Each nested lazy-list is the list of
; all integers divisible by i for some i>=lower.
; Pre-conditions: low is an integer
; Tests: > (define lz3 (all-div-from 7))
; > (take lz3 3)
; '((7 . #<procedure>) (8 . #<procedure>) (9 . #<procedure>))
; > (take (head lz3) 3)
; '(7 14 21)
; > (take (head (tail lz3)) 3)
; '(8 16 24)

(define all-div-from
(lambda(lower)
(cons (lz-lst-map (lambda(x) (* x lower)) (div-from 1 1))
(lambda() (all-div-from (add1 lower))))))


; Signature: div-from (low int)
; Type: [[Number*Number]-> Lazy-list]
; Purpose: return the lazy-list of all integers that
; are larger than low and divisible by int
; Pre-conditions: int > low
; Tests: > (define lz1 (div-from 5 12))
; > (take lz1 3)
; '(12 24 36)
; > (define lz2 (div-from 7 10))
; > (take lz2 4)
; '(10 20 30 40)
(define div-from
(lambda (lower int)
(lz-lst-filter (lambda(x) (> x (- lower 1)))
(lz-lst-map (lambda(x) (* x int)) (integers-from 1)))))

(define integers-from
(lambda (n) (cons n
(lambda () (integers-from (+ 1 n))))))

(define lz-lst-filter
(lambda (p lz)
(cond ((empty? lz) lz)
((p (head lz))
(cons (head lz)
(lambda () (lz-lst-filter p (tail lz)))))
(else (lz-lst-filter p (tail lz))))))

过程all-div-from接收下限low并返回惰性列表的惰性列表。其中的每个惰性列表都是由 div-from 创建的,它接收下限 low 和整数 int > low,并且返回大于 low 且可被 int 整除的所有整数的惰性列表。

输入和正确输出的示例:

 > (take (all-div-from-flattened 7) 10)
'(7 8 14 9 21 16 28 10 35 24)

但是当我在解释器中尝试这一行时:

> (take (all-div-from-flattened 3) 3)

它进入无限循环。

我的实现必须使用 lz-lst-accumulateinterleaveall-div-from-flattend 过程。

关于如何使其发挥作用有什么建议吗?

最佳答案

您的interleave不产生惰性列表;它生成一个普通列表:它使用 cons有两个参数,第二个参数包含在 lambda 中。所以cons强制通过第二个参数,导致评估失控:

(define interleave
(lambda (lz1 dlz2) ; "delayed" lz2
(if (empty? lz1)
(dlz2)
(cons (head lz1)
; here:
(interleave (dlz2) (lambda () (tail lz1)))))))

(define lz-lst-accumulate
(lambda (op initial lz)
(if (empty? lz)
initial
(op (head lz)
(lambda () (lz-lst-accumulate op initial (tail lz)))))))

(all-div-from lower)产生正确的输出,( (lower . <proc1>) . <proc2> ) ,但是调用(lz-lst-accumulate interleave '() (all-div-from lower))减少为

(interleave [lower . <proc1>]
(lambda () (lz-lst-accumulate interleave '() (<proc2>))))

减少为

(cons lower 
(interleave (lz-lst-accumulate interleave '() (<proc2>))
(lambda () (<proc1>))))

虽然它必须减少

(cons lower 
(lambda () (interleave ....)))

生成一个惰性列表。

显而易见的(现在)解决方案是添加缺失的 lambda :

(define interleave
(lambda (lz1 lz2)
(if (empty? lz1)
(lz2)
(cons (head lz1)
(lambda () (interleave (lz2) (lambda() (tail lz1))))))))

现在它可以正确运行:

(take (all-div-from-flattened 7) 10)
;Value 12: (7 8 14 9 21 16 28 10 35 24)

<小时/>

你可以通过引入来大大简化你的代码

(define integers-from-by
(lambda (n d) (cons n
(lambda () (integers-from (+ n d) d)))))

那么,

;(define div-from
; (lambda (lower int)
; (lz-lst-filter (lambda(x) (> x (- lower 1)))
; (lz-lst-map (lambda(x) (* x int)) (integers-from 1)))))

(define mults-from-of ; n in [int, 2*int ..], n >= lower
(lambda (lower int)
(let ((x (* (quotient (+ lower (- int 1)) int) int)))
(integers-from-by x int))))

你也可以有

(define mults-above-of   ; n in [int, 2*int ..], n > lower
(lambda (lower int)
(let ((x (* (+ (quotient lower int) 1) int)))
(integers-from-by x int))))

下一步,

; (define all-div-from
; (lambda(lower)
; (cons (lz-lst-map (lambda(x) (* x lower)) (div-from 1 1))
; (lambda() (all-div-from (add1 lower))))))

(define all-mults-from
(lambda (lower)
(lz-lst-map (lambda (n) (mults-from-of n n))
; or just (integers-from-by n n)
(integers-from-by lower 1))))

如果您更改 interleave按顺序组合流,然后切换到 mults-above-ofall-mults-from定义,则(lz-lst-accumulate interleave-ordered '() (all-mults-from-above 2))将通过埃拉托色尼筛中的向上计数的方式按顺序定义所有合数的惰性列表。

从此,您只需再迈出一步,即可拥有自己的 lazy unbounded incremental sieve of Eratosthenes (在该页面上搜索“SiCp”)

另一备注:take应该进行调整以不强制流中的额外元素。更多 here .

关于scheme - 通过高阶累积过程展平Scheme中的惰性列表的惰性列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23405751/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com