; 2017 - 2018 - 2 bomen

(define (versiering? tree)
  (and (pair? tree)
       (or (eq? (car tree) 'ster)
           (eq? (car tree) 'bal))))
(define (weight tree)
  (cond ((versiering? (car tree)) (cdar tree))
        ((null? tree) 0)
        (else (car tree))))

(define (lijst-van-versieringen? lijst)
  (define (list-and lijst)
    (if (not (null? lijst))
        (and (car lijst)
             (list-and (cdr lijst)))
        #t))
  (list-and (map versiering? lijst)))
  
  (define versiering '(((ster . 20) (bal . 10))
                     (((bal . 10) (bal . 10)) (ster . 20))
                     ((ster . 20) ((bal . 10)(ster . 20)(bal . 10)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ik probeer het hier om te zetten naar een familieboom, en ik krijg ongeveer iets, maar de 2 laatste takken van "versiering" worden ook (define (omzetten-naar-famtree tree)
  (cond ((versiering? tree) tree)
        ((null? tree) '())
        (else (append (list (+ (weight (omzetten-naar-famtree (car tree)))
                               (weight (omzetten-naar-famtree (cdr tree)))))
                      (list (omzetten-naar-famtree (car tree)))
                      (omzetten-naar-famtree (cdr tree))))))
;; Append is hier de foute keuze in de zin dat je bij een boom nooit echt append nodig hebt om 2 bomen samen te voegen. Enkel om subbomen samen te voegen heb je append nodig.
;; Als je bij deze oefening 2 bomen wilt samensmelten moet je de som maken van hun gewicht (hun car) en de append van hun cdr (de lijst van subbomen).

;; Verder kan je het jezelf makkelijker maken door eerst te denken aan je basis gevallen:
;; 1 element
;; invoer : '((ster . 20))
;; uitvoer: (20 ((ster . 20)))

;; geen elementen
;; invoer : '()
;; uitvoer: (0)

;; meerdere elementen
;; invoer : '((ster . 20) (bal . 30))
;; uitvoer: (50 ((ster . 20)) ((bal . 30)))

;; Hier merk je op dat elke bal in zijn eigen lijst zit.
(define (omzetten-naar-famtree tree)
  (cond
    ;;((versiering? tree) tree)
    ;;Hier moeten we dus een lijst van maken zodat het een boom wordt.
    ((versiering? tree) (list tree))
    ;;((null? tree) '())
    ;; het neutraal element is niet de lege lijst maar een lege boom!
    ((null? tree) (list 0))
    ;; De procedure die we nu schrijven (omzetten-naar..) is een functie die een familieboom genereert.
    ;; Het resultaat van omzetten van de car en omzetten van de cdr leveren dus een boom op.
    ;; Maar! We hebben hier een boom gemaakt van de car, en van de cdr. Dat wil zeggen dat we van de boom op basis van de car een subboom moeten maken van de boom
    ;; die we gekregen hebben op basis van de cdr.

    ;; Een boom kan ook volgende vormen hebben. Een boom met gewicht (<gewicht> <subbomen>*) ofwel ((<versiering> . <gewicht>)) in geval van een atom.
    ;; Dat wil dus zeggen dat de de boom van de car (carboom) eigenlijk aan de cdr van de cdrboom moet hangen (subboom van maken).
    ;; De car van de cdrboom is in elk geval toch een gewicht dus dat mogen we weggooien, want we moeten het herberekenen om er de carboom zijn gewicht bij te tellen.
    ;; We passen de gewichtsfunctie dus lichtjes aan zodat die in beide gevallen het gewicht teruggeeft (zie edit).
    (else (let* ((carboom (omzetten-naar-famtree (car tree)))
                 (cargewicht (gewicht carboom))
                 (cdrboom (omzetten-naar-famtree (cdr tree)))
                 (cdrgewicht (gewicht cdrboom)))

            
            (display (car cdrboom))
            (cons (+ cargewicht cdrgewicht) (cons carboom (cdr cdrboom)))))))
;      (else (append (list (+ (weight (omzetten-naar-famtree (car tree)))
;                             (weight (omzetten-naar-famtree (cdr tree)))))
;                    (list (omzetten-naar-famtree (car tree)))
;                    (omzetten-naar-famtree (cdr tree))))))


(omzetten-naar-famtree versiering)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; hier probeerde ik om het familieboompatroon van wederzijdse recursie te volgen, maar de oplossing laat veel vallen en doet totaal niet wat het (define (omzetten-nr-famtree tree)
  (define (omvormen tree)
    (cond ((versiering? tree) tree)
          ;   ((null? tree) '())                   ;; het neutraal element van een lege lijst is dus (list 0)!
          ;          ((lijst-van-versieringen? tree)
          ;           (list (apply + (map weight tree))
          ;                 tree))
          ;; Als je recursie hebt hoef je dit niet te doen!
          (else (omvormen-in (cdr tree)))))
  (define (omvormen-in tree)
    (cond ((null? tree) '())
          (else (list (omvormen (car tree))
                      (omvormen-in (cdr tree))))))
  (omvormen tree))
;        (else (list (+ (weight (omzetten-nr-famtree (car tree)))
;                  (weight (omzetten-nr-famtree (cdr tree))))
;               (omzetten-nr-famtree (car tree))
;               (omzetten-nr-famtree (cdr tree))))))