PasteRack.org
Paste # 90157
2017-09-16 09:18:28

Fork as a new paste.

Paste viewed 44 times.


Embed:

combine-trees abstraction

#lang htdp/isl
(require 2htdp/image)

(define-struct dir (name sub-dirs images))
;; Dir is (make-dir String ListOfDir ListOfImage)
;; interp. An directory in the organizer, with a name, a list
;;         of sub-dirs and a list of images.

(define I1 (square 10 "solid" "red"))
(define I2 (square 12 "solid" "green"))
(define I3 (rectangle 13 14 "solid" "blue"))
(define D4 (make-dir "D4" empty (list I1 I2)))
(define D5 (make-dir "D5" empty (list I3)))
(define D6 (make-dir "D6" (list D4 D5) empty))

;
;                       D6
;                     /    \
;                    /      \
;                   D4      D5
;                 /    \     |
;                I1    I2    I3
;

; 
; PROBLEM A:
; 
; Design an abstract fold function for Dir called fold-dir. 
;

;; (String Y Z -> X) (X Y -> Y) (Image -> Z) Y Z Dir -> X
;; The abstract function for Dir.

;; Get all dir names as a list.
(check-expect (local
                [(define (c1 name rlod rloi) (cons name rlod))]
                (fold-dir c1 append cons empty empty D6))
              (list "D6" "D4" "D5"))

;; Get all images as a list.
(check-expect (local [(define (c1 name rlod rloi) (append rlod rloi))]
                (fold-dir c1 append cons empty empty D6))
              (list I1 I2 I3))

(define (fold-dir combdir comblod combloi bdir bloi d)
  (local [
          ;; Dir -> X
          (define (fn-for-dir d)
            (combdir (dir-name d)
                     (fn-for-lod (dir-sub-dirs d))
                     (fn-for-loi (dir-images d))))

          ;; ListOfDir -> Y
          (define (fn-for-lod lod)
            (cond [(empty? lod) bdir]
                  [else
                   (comblod (fn-for-dir (first lod))
                            (fn-for-lod (rest lod)))]))

          ;; Image -> Z
          (define (fn-for-loi loi)
            (cond [(empty? loi) bloi]
                  [else
                   (combloi (first loi)
                            (fn-for-loi (rest loi)))]))
          ]
    (fn-for-dir d)))


; 
; PROBLEM B:
; 
; Design a function that consumes a Dir and produces the number of 
; images in the directory and its sub-directories. 
; Use the fold-dir abstract function.
;

;; Dir -> Natural
;; Produce number of images in Dir and sub-dirs.
(check-expect  (local [(define (c1 name rlod rloi) (+ rlod rloi))
                       (define (c2 rdir rlod) (+ rdir rlod))
                       (define (c3 i rloi) (+ 1 rloi))]
                 (fold-dir c1 c2 c3 0 0 (make-dir "D0" empty empty)))
               0)

(check-expect  (local [(define (c1 name rlod rloi) (+ rlod rloi))
                       (define (c2 rdir rlod) (+ rdir rlod))
                       (define (c3 i rloi) (+ 1 rloi))]
                 (fold-dir c1 c2 c3 0 0 (make-dir "D0" empty (list I1 I2 I3 I1 I2))))
               5)

(check-expect  (local [(define (c1 name rlod rloi) (+ rlod rloi))
                       (define (c2 rdir rlod) (+ rdir rlod))
                       (define (c3 i rloi) (+ 1 rloi))]
                 (fold-dir c1 c2 c3 0 0 D6))
               3)


(define (count-images dir)
  (local [
          (define (c1 name rlod rloi)
            (+ rlod rloi))
          
          (define (c2 rdir rlod)
            (+ rdir rlod))

          (define (c3 img rloi)
            (+ 1 rloi))]
    (fold-dir c1 c2 c3 0 0 dir)))