2021-04-25 14:57:17 +02:00
|
|
|
(load "shared/util.scm")
|
2020-12-16 18:05:38 +01:00
|
|
|
|
2020-12-17 22:34:24 +01:00
|
|
|
(display "\nex-3.12 - append!\n")
|
|
|
|
|
|
|
|
(define (append x y)
|
|
|
|
(if (null? x)
|
|
|
|
y
|
|
|
|
(cons (car x) (append (cdr x) y))))
|
|
|
|
|
|
|
|
(define (append! x y)
|
|
|
|
(set-cdr! (last-pair x) y)
|
|
|
|
x)
|
|
|
|
|
|
|
|
(define (last-pair x)
|
|
|
|
(if (null? (cdr x))
|
|
|
|
x
|
|
|
|
(last-pair (cdr x))))
|
|
|
|
|
|
|
|
(define x (list 'a 'b))
|
|
|
|
(define y (list 'c 'd))
|
|
|
|
(define z (append x y))
|
|
|
|
|
|
|
|
(assert z '(a b c d))
|
|
|
|
(assert (cdr x) '(b))
|
|
|
|
(define w (append! x y))
|
|
|
|
(assert w '(a b c d))
|
|
|
|
(assert (cdr x) '(b c d))
|
|
|
|
|
|
|
|
(display "\nex-3.13 - make cycle\n")
|
|
|
|
|
|
|
|
(define (make-cycle x)
|
|
|
|
(set-cdr! (last-pair x) x)
|
|
|
|
x)
|
|
|
|
|
|
|
|
(define z (make-cycle (list 'a 'b 'c)))
|
|
|
|
|
|
|
|
(display "[see comment]\n")
|
|
|
|
; infinite loop
|
|
|
|
; (last-pair z)
|
|
|
|
|
|
|
|
(display "\nex-3.14 - mystery\n")
|
|
|
|
|
|
|
|
; reverse
|
|
|
|
(define (mystery x)
|
|
|
|
(define (loop x y)
|
|
|
|
(if (null? x)
|
|
|
|
y
|
|
|
|
(let ((temp (cdr x)))
|
|
|
|
(set-cdr! x y)
|
|
|
|
(loop temp x))))
|
|
|
|
(loop x '()))
|
|
|
|
|
|
|
|
(define v (list 'a 'b 'c 'd))
|
|
|
|
(define w (mystery v))
|
|
|
|
|
|
|
|
(display v) (newline)
|
|
|
|
(display w) (newline)
|
|
|
|
|
|
|
|
(display "\nex-3.15\n")
|
|
|
|
|
|
|
|
(define x (list 'a 'b))
|
|
|
|
(define z1 (cons x x))
|
|
|
|
(define z2 (cons (list 'a 'b) (list 'a 'b)))
|
|
|
|
|
|
|
|
(define (set-to-wow! x)
|
|
|
|
(set-car! (car x) 'wow)
|
|
|
|
x)
|
|
|
|
|
|
|
|
(assert z1 '((a b) a b))
|
|
|
|
(set-to-wow! z1)
|
|
|
|
(assert z1 '((wow b) wow b))
|
|
|
|
(set-to-wow! z2)
|
|
|
|
(assert z2 '((wow b) a b))
|
|
|
|
|
|
|
|
|
|
|
|
(display "\nex-3.16 - count pairs\n")
|
|
|
|
|
|
|
|
(define (count-pairs x)
|
|
|
|
(if (not (pair? x))
|
|
|
|
0
|
|
|
|
(+ (count-pairs (car x))
|
|
|
|
(count-pairs (cdr x))
|
|
|
|
1)))
|
|
|
|
|
2020-12-18 16:49:15 +01:00
|
|
|
(define l3 '(1 2 3))
|
|
|
|
(assert (count-pairs l3) 3)
|
|
|
|
|
|
|
|
(define l4 '(1 2 3))
|
|
|
|
(set-car! l4 (last-pair l4))
|
|
|
|
(assert (count-pairs l4) 4)
|
|
|
|
|
|
|
|
(define l7p3 (cons 3 '()))
|
|
|
|
(define l7p2 (cons l7p3 l7p3))
|
|
|
|
(define l7p1 (cons l7p2 l7p2))
|
|
|
|
(define l7 l7p1)
|
|
|
|
(assert (count-pairs l7) 7)
|
|
|
|
|
|
|
|
(define ln '(1 2 3))
|
|
|
|
(set-car! (last-pair ln) ln)
|
|
|
|
;(count-pairs ln)
|
|
|
|
(display "[endless-loop]\n")
|
2020-12-17 22:34:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
(display "\nex-3.17 - count pairs improved\n")
|
|
|
|
|
2020-12-18 16:49:15 +01:00
|
|
|
(define (count-pairs x)
|
|
|
|
(define visited '())
|
|
|
|
(define (count-pairs-iter x)
|
|
|
|
(if (or (not (pair? x))
|
|
|
|
(contains x visited))
|
|
|
|
0
|
|
|
|
(begin
|
|
|
|
(set! visited (cons x visited))
|
|
|
|
(+ (count-pairs-iter (car x))
|
|
|
|
(count-pairs-iter (cdr x))
|
|
|
|
1))))
|
|
|
|
(count-pairs-iter x))
|
|
|
|
|
|
|
|
(assert (count-pairs l3) 3)
|
|
|
|
(assert (count-pairs l4) 3)
|
|
|
|
(assert (count-pairs l7) 3)
|
|
|
|
(assert (count-pairs ln) 3)
|
|
|
|
|
|
|
|
(display "\nex-3.18 - has cycle\n")
|
|
|
|
|
|
|
|
(define x (list 'a 'b 'c))
|
|
|
|
(define z (make-cycle (list 'a 'b 'c)))
|
2020-12-17 22:34:24 +01:00
|
|
|
|
2020-12-18 16:49:15 +01:00
|
|
|
(define (has-cycle? x)
|
|
|
|
(define (iter x visited)
|
|
|
|
(cond
|
|
|
|
((null? x) #f)
|
|
|
|
((contains x visited) #t)
|
|
|
|
(else
|
|
|
|
(iter (cdr x) (cons x visited)))))
|
|
|
|
(iter x '()))
|
|
|
|
|
|
|
|
(assert (has-cycle? x) #f)
|
|
|
|
(assert (has-cycle? l3) #f)
|
|
|
|
(assert (has-cycle? l4) #f)
|
|
|
|
(assert (has-cycle? l7) #f)
|
|
|
|
(assert (has-cycle? z) #t)
|
|
|
|
|
|
|
|
; ln contains a cycle in the sense that it lead to an endless-loop for
|
|
|
|
; count-pairs. However, this question tells us that the criterion for a cycle
|
|
|
|
; is whether cdr leads to an endless-loop. Consequently, I would say it is
|
|
|
|
; legit that we get #f here.
|
|
|
|
(assert (has-cycle? ln) #f)
|
|
|
|
|
|
|
|
(display "\nex-3.19 - has cycle with constant space\n")
|
|
|
|
|
|
|
|
(define x (list 'a 'b 'c))
|
|
|
|
|
|
|
|
(define (has-cycle? original-xs)
|
|
|
|
(define (find x xs)
|
|
|
|
(define (find-iter xs index)
|
|
|
|
(cond
|
|
|
|
((null? xs) 'notfound)
|
|
|
|
((eq? x (car xs)) index)
|
|
|
|
(else (find-iter (cdr xs) (inc index)))))
|
|
|
|
(find-iter xs 0))
|
|
|
|
|
|
|
|
(define (cycle-iter xs index)
|
|
|
|
(if (null? xs)
|
|
|
|
#f
|
|
|
|
(let ((find-index (find (car xs) original-xs)))
|
|
|
|
(if (or (eq? find-index 'notfound)
|
|
|
|
(= find-index index))
|
|
|
|
(cycle-iter (cdr xs) (inc index))
|
|
|
|
#t))))
|
|
|
|
(cycle-iter original-xs 0))
|
|
|
|
|
|
|
|
(assert (has-cycle? l7) #f)
|
|
|
|
(assert (has-cycle? z) #t)
|
|
|
|
|
|
|
|
(display "\nex-3.20\n")
|
2020-12-17 22:34:24 +01:00
|
|
|
|
2020-12-19 15:22:30 +01:00
|
|
|
(define (cons x y)
|
|
|
|
(define (set-x! v) (set! x v))
|
|
|
|
(define (set-y! v) (set! y v))
|
|
|
|
(define (dispatch m)
|
|
|
|
(cond ((eq? m 'car) x)
|
|
|
|
((eq? m 'cdr) y)
|
|
|
|
((eq? m 'set-car!) set-x!)
|
|
|
|
((eq? m 'set-cdr!) set-y!)
|
|
|
|
(else (error "Undefined operation -- CONS" m))))
|
|
|
|
dispatch)
|
|
|
|
|
|
|
|
(define (car z) (z 'car))
|
|
|
|
(define (cdr z) (z 'cdr))
|
|
|
|
|
|
|
|
(define (set-car! z new-value)
|
|
|
|
((z 'set-car!) new-value)
|
|
|
|
z)
|
|
|
|
|
|
|
|
(define (set-cdr! z new-value)
|
|
|
|
((z 'set-cdr!) new-value)
|
|
|
|
z)
|
|
|
|
|
|
|
|
(define x (cons 1 2))
|
|
|
|
(define z (cons x x))
|
|
|
|
(set-car! (cdr z) 17)
|
|
|
|
(assert (car x) 17)
|
|
|
|
|