summaryrefslogtreecommitdiff
path: root/coding-exercises/3/12.rkt
blob: 902cc12ba334638727bf510a2498fd210ba8e30a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#lang racket
;; 12
(require compatibility/mlist)
(define (last-pair x)
  (if (null? (mcdr x))
    x
    (last-pair (mcdr x))))
(define x (mlist 'a 'b))
(define y (mlist 'c 'd))
(define z (mappend x y))
x
(define w (mappend! x y))
x

;; 13
(define (make-cycle x)
  (set-mcdr! (last-pair x) x)
  x)
(define zp (make-cycle (mlist 'a 'b 'c)))
zp
;; last-pair would make an infinite loop

;; 14
;; The procedure reverses the list. And messes up the list that is bound in the global env
(define v (mlist 'a 'b 'c 'd))
(define (mystery x)
  (define (loop x y)
    (if (null? x)
      y
      (let ((temp (mcdr x)))
        (set-mcdr! x y)
        (loop temp x))))
  (loop x '()))
(define wp (mystery v))
v
wp

;; 15
;; 16
;; 17
(define (make-pair-counter)
  (define counted (list))
  (define (count-pairs x)
    (display counted)
    (if (or (not (pair? x))
            (memq x counted))
      0
      (begin
        (set! counted (cons x counted))
        (+ 1
           (count-pairs (car x))
           (count-pairs (cdr x))))))
  count-pairs)
((make-pair-counter) (list 'a 'b 'c))
(define bc (list 'b 'c))
((make-pair-counter) (cons bc bc))
((make-pair-counter) (cons bc (cdr bc)))
(define c (list 'c))
(define b (cons c c))
((make-pair-counter) (cons b b))

;; 18/19
;; This is actually only a valid way to check for cycles if the first pair in the list is also the state of the cycle.
;; A better way would be to check against all memory addresses in the list by hashing or counting.
(define (cycle? x)
  (define (iter v items)
    (cond ((null? items) false)
          ((eq? v items) true)
          (else (iter v (mcdr items)))))
  (iter x (mcdr x)))
(cycle? (mlist 'a 'b 'c))
(cycle? (make-cycle (mlist 'a 'b 'c)))
;; For 19 you need a famous trick with two pointers

;; 20