PfG 1999 - Beispielprogramme
Die Türme von Hanoi
(define other-peg
(lambda (peg-1 peg-2)
(- (- 6 peg-1) peg-2)))
(define hanoi
(lambda (n source-peg dest-peg)
(if (= n 0)
'()
(append
(hanoi (- n 1)
source-peg
(other-peg source-peg dest-peg))
(cons (cons source-peg dest-peg)
(hanoi (- n 1)
(other-peg source-peg dest-peg)
dest-peg))))))
Nim
(define play-nim
(lambda (game-state player)
(begin
(display-game-state game-state)
(cond ((over? game-state)
(announce-winner player))
((equal? player 'human)
(play-nim (human-move game-state) 'computer))
((equal? player 'computer)
(play-nim (computer-move game-state) 'human))
(else
(error "player wasn't human or computer:" player))))))
(define computer-move
(lambda (game-state)
(let ((pile (if (> (size-of-pile game-state 1) 0)
1
2)))
(begin
(display "I take 1 coin from pile ")
(display pile)
(newline)
(remove-coins-from-pile game-state 1 pile)))))
(define prompt
(lambda (prompt-string)
(begin
(newline)
(display prompt-string)
(newline)
(read))))
(define human-move
(lambda (game-state)
(let ((p (prompt "Which pile will you remove from?")))
(let ((n (prompt "How many coins do you want to remove?")))
(remove-coins-from-pile game-state n p)))))
(define over?
(lambda (game-state)
(= (total-size game-state) 0)))
(define announce-winner
(lambda (player)
(begin
(if (equal? player 'human)
(display "You lose. Better luck next time.")
(display "You win. Congratulations."))
(newline))))
(define make-game-state
(lambda (n m)
(cons n m)))
(define size-of-pile
(lambda (game-state pile-number)
(if (= pile-number 1)
(car game-state)
(cdr game-state))))
(define remove-coins-from-pile
(lambda (game-state num-coins pile-number)
(if (= pile-number 1)
(make-game-state (- (size-of-pile game-state 1)
num-coins)
(size-of-pile game-state 2))
(make-game-state (size-of-pile game-state 1)
(- (size-of-pile game-state 2)
num-coins)))))
(define display-game-state
(lambda (game-state)
(begin
(newline)
(display " Pile 1: ")
(display (size-of-pile game-state 1))
(newline)
(display " Pile 2: ")
(display (size-of-pile game-state 2))
(newline))))
(define total-size
(lambda (game-state)
(+ (size-of-pile game-state 1)
(size-of-pile game-state 2))))
(define error
(lambda (message thing)
(begin
(display message) (display " ") (display thing) (newline)
(/ 1 0))))
Sortierverfahren
;; Insertion sort
(define insertion-sort
(lambda (list)
(cond
((null? list) list)
((null? (cdr list)) list)
(else
(insert (car list) (insertion-sort (cdr list)))))))
(define insert
(lambda (number list)
(cond
((null? list) (cons number '()))
((< number (car list))
(cons number list))
(else
(cons (car list) (insert number (cdr list)))))))
(define insertion-sort-2
(lambda (list)
(insertion-sort-help list '())))
(define insertion-sort-help
(lambda (remaining sorted)
(if (null? remaining)
sorted
(insertion-sort-help (cdr remaining)
(insert (car remaining) sorted)))))
(define insert-2
(lambda (number list)
(insert-2-help number list '())))
(define insert-2-help
(lambda (number remaining reverse-result)
(cond
((null? remaining)
(reverse (cons number reverse-result)))
((< number (car remaining))
(append (reverse reverse-result)
(cons number remaining)))
(else
(insert-2-help number
(cdr remaining)
(cons (car remaining) reverse-result))))))
;; Bubble sort
(define bubble-sort
(lambda (list)
(bubble-sort-help list '() #t)))
(define bubble-sort-help
(lambda (remaining reverse-result sorted?)
(if (or (null? remaining)
(null? (cdr remaining)))
(let ((result (reverse (append remaining reverse-result))))
(if sorted?
result
(bubble-sort-help result '() #t)))
(let ((first (car remaining))
(second (car (cdr remaining)))
(rest (cdr (cdr remaining))))
(if (< first second)
(bubble-sort-help (cons second rest)
(cons first reverse-result)
#t)
(bubble-sort-help (cons first rest)
(cons second reverse-result)
#f))))))
;; Merge sort
(define merge-sort
(lambda (list)
(cond ((null? list)
'())
((null? (cdr list))
list)
(else
(merge (merge-sort (one-part list))
(merge-sort (the-other-part list)))))))
(define merge
(lambda (list1 list2)
(cond
((null? list1) list2)
((null? list2) list1)
((< (car list1) (car list2))
(cons (car list1) (merge (cdr list1) list2)))
((= (car list1) (car list2))
(cons (car list1) (merge (cdr list1) (cdr list2))))
(else
(cons (car list2) (merge list1 (cdr list2)))))))
(define odd-part
(lambda (list)
(if (null? list)
'()
(cons (car list) (even-part (cdr list))))))
(define even-part
(lambda (list)
(if (null? list)
'()
(odd-part (cdr list)))))
(define one-part odd-part)
(define the-other-part even-part)
;; Quicksort
(define (choose-pivot list)
(cons (car list) (cdr list)))
(define (split-list-around-pivot-help pivot list before after)
(cond
((null? list)
(cons before after))
((< (car list) pivot)
(split-list-around-pivot-help pivot (cdr list)
(cons (car list) before)
after))
(else
(split-list-around-pivot-help pivot (cdr list)
before
(cons (car list) after)))))
(define (split-list-around-pivot pivot list)
(split-list-around-pivot-help pivot list '() '()))
(define (quicksort list)
(if (or (null? list) (null? (cdr list)))
list
(let* ((p (choose-pivot list))
(pivot (car p))
(rest (cdr p)))
(let* ((p (split-list-around-pivot pivot rest))
(before (car p))
(after (cdr p)))
(append (quicksort before)
(cons pivot '())
(quicksort after))))))
;; Radix exchange
;; POSITION is from the back ...
(define (extract-digit position number)
(let ((truncate-head (remainder number (expt 10 (+ 1 position)))))
(quotient truncate-head (expt 10 position))))
(define (radix-sort list number-of-digits)
(if (= 0 number-of-digits)
list
(let ((digit-lists (make-vector 10 '())))
(radix-sort-collect list (- number-of-digits 1) digit-lists)
(radix-sort-digit-lists digit-lists (- number-of-digits 1))
(radix-sort-collect-digit-lists digit-lists))))
(define (radix-sort-collect list position digit-lists)
(if (null? list)
#f
(let ((digit (extract-digit position (car list))))
(vector-set! digit-lists digit
(cons (car list) (vector-ref digit-lists digit)))
(radix-sort-collect (cdr list) position digit-lists))))
(define (radix-sort-digit-lists digit-lists number-of-digits)
(radix-sort-digit-lists-help digit-lists number-of-digits 0))
(define (radix-sort-digit-lists-help
digit-lists number-of-digits index)
(if (= index 10)
#f
(begin
(vector-set! digit-lists index
(radix-sort (vector-ref digit-lists index)
number-of-digits))
(radix-sort-digit-lists-help digit-lists
number-of-digits
(+ 1 index)))))
(define (radix-sort-collect-digit-lists digit-lists)
(radix-sort-collect-digits-lists-help digit-lists 9 '()))
(define (radix-sort-collect-digit-lists-help digit-lists index result)
(if (< index 0)
result
(radix-sort-collect-digits-lists-help
digit-lists (- index 1)
(append (vector-ref digit-lists index) result))))
Michael Sperber [Mr. Preprocessor]
Last modified: Fri Jun 25 16:05:41 MST 1999