12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- (define-module (hanoi-model))
- (define-public create-hanoi
- (λ (source spare dest)
- (list source spare dest)))
- (define-public rest-of-towers cdr)
- (define-public first-of-towers car)
- (define-public rest-of-disks cdr)
- (define-public first-of-disks car)
- (define-public first-tower first-of-towers)
- (define-public second-tower (λ (hanoi) (first-of-towers (rest-of-towers hanoi))))
- (define-public third-tower (λ (hanoi) (first-of-towers (rest-of-towers (rest-of-towers hanoi)))))
- (define-public create-tower
- (λ (id disk-sizes)
- "This is a procedure for creating a tower and assuring, that the tower has a
- valid stacking of disks."
- (let check-disk-sizes ([remaining-disks disk-sizes] [previous-disk-size -inf.0])
- (cond
- [(null? remaining-disks) (cons id disk-sizes)]
- [(> (first-of-disks remaining-disks) previous-disk-size)
- (check-disk-sizes (rest-of-disks remaining-disks) (first-of-disks remaining-disks))]
- [else
- (raise (cons 'invalid-disk-placement disk-sizes))]))))
- ;; A tower shall be a list whose first element is a symbol indicating the tower
- ;; position.
- (define-public tower-disks
- (λ (tower)
- (cdr tower)))
- (define-public tower-id
- (λ (tower)
- (car tower)))
- (define-public get-tower-basis
- (λ (tower)
- (let loop ([disks (tower-disks tower)])
- (cond
- [(null? disks)
- (error (list 'empty-disks tower))]
- [(null? (rest-of-disks disks))
- (first-of-disks disks)]
- [else
- (loop (rest-of-disks disks))]))))
- (define-public find-largest-disk
- (λ (tower)
- (get-tower-basis tower)))
- (define-public print-tower
- (λ (id hanoi)
- ((λ (towers)
- (if (not (null? towers))
- (display (simple-format #f "Tower: ~a\n" (first-of-towers towers)))
- (error (list 'tower-id-not-found id hanoi))))
- (filter (λ (tower) (eq? (tower-id tower) id))
- hanoi))))
- (define-public print-hanoi
- (λ (hanoi)
- (display (simple-format #f "Towers of Hanoi:\n"))
- (print-tower 'SO hanoi)
- (print-tower 'SP hanoi)
- (print-tower 'DE hanoi)))
- (define-public find-tower-by-id
- (λ (hanoi id)
- (cond
- [(null? hanoi)
- (error (list 'tower-id-not-found id hanoi))]
- [(eq? (tower-id (first-of-towers hanoi)) id)
- (first-of-towers hanoi)]
- [else
- (find-tower-by-id (rest-of-towers hanoi) id)])))
- (define-public take-disk
- (λ (tower)
- (first-of-disks tower)))
- (define-public take-disk-from-tower
- (λ (hanoi id)
- (take-disk (find-tower-by-id hanoi id))))
- (define-public remove-disk
- (λ (tower)
- (create-tower (tower-id tower)
- (rest-of-disks (tower-disks tower)))))
- (define-public stack-disks cons)
|