Grundlagen der funktionsorientierten Programmierung mit SCHEME/Würfeln mit mehreren Würfeln

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>SchemeJS</language>
[[Bild:Wuerfel1.jpg|miniatur|Wie wahrscheinlich ist es, mit 5 Würfeln die Augenzahl 15 zu werfen?]]

Wir wollen das gleichzeitige Werfen mehrerer Würfel simulieren. Dabei soll uns nur interessieren, ''wie oft'' die Summe aller Augenzahlen auftreten.<br />
Um signifikante Aussagen zu erhalten, muss diese Simulation in großer Anzahl wiederholt werden können.

== Lösungsidee ==

* Definiere eine Zählerliste, deren Startwerte Null sind.
* Die Position jedes Listenelements entspricht genau der Summe aller geworfenen Augenzahlen.
* Nach jedem Wurf wird die Summe aller Augenzahlen gebildet und der Wert des entsprechenden Listenelements um $1$ erhöht. 
* Wiederhole die Simulation in der gewünschten (großen) Anzahl.

== Implementation ==

<code id="4e7502f3c5964" hidden>
(define nr 1)
(define rand 50)
(define maxbreite (- 600 (* 2 rand)))
(define maxhoehe (- 400 (* 2 rand)))
(define canvas (eval (string->symbol (string-append "canvas" (number->string nr)))))
(define turtle (eval (string->symbol (string-append "turtle" (number->string nr)))))

(define minmax
  (lambda (ls)
    (letrec
        ([extremsuche
          (lambda (extrem ls op)
            (cond
              [(null? ls) extrem]
              [(op extrem (car ls)) (extremsuche (car ls) (cdr ls) op)]
              [else
               (extremsuche extrem (cdr ls) op)]))])
      (cons (extremsuche 0 ls >)
            (extremsuche 0 ls <)))))

(define balken
  (lambda (hoehe breite)
    (forward turtle breite) (left turtle 90)
    (forward turtle hoehe) (left turtle 90)
    (forward turtle breite) (left turtle 90)
    (forward turtle hoehe) (left turtle 90)
    (forward turtle breite)))

(define balkendiagramm
  (lambda (ls)
    (let* ([breite (/ maxbreite (length ls))] 
           [extremwerte (minmax ls)]
           [min (car extremwerte)] [max (cdr extremwerte)])
      (letrec
          ([zeichnen
            (lambda (min max ls)
              (if (null? ls)
                  'ok
                  (begin
                    (balken (round (* (/ (car ls) (- max min)) maxhoehe)) (round breite))
                    (zeichnen min max (cdr ls)))))])
        (clear canvas) 
        (hide turtle)
        (move turtle rand (+ rand (* (/ max (- max min)) maxhoehe))) (right turtle 90)
        (zeichnen min max ls)))))
</code>

<code id="5bb671b149170">
(define wuerfelzahl
  (lambda ()
    ...))

(define wuerfeln
  (lambda (wuerfel anz)
    (letrec
        ([startliste
          (lambda (pos)
            (if (= pos 0)
                ()
                (cons 0 (startliste (- pos 1)))))]
         [summe
          (lambda (wuerfel)
            (if (= wuerfel 0)
                0
                (+ (wuerfelzahl) (summe (- wuerfel 1)))))]         
         [poszaehlen
          (lambda (ls pos)
            (if (= pos 1) 
                (cons (+ 1 (car ls)) (cdr ls))
                (cons (car ls) (poszaehlen (cdr ls) (- pos 1)))))]
         [zaehlen
          (lambda (ls anz)
            (if (= anz 0)
                ls
                (let ([pos (- (summe wuerfel) wuerfel -1)])
                  (zaehlen (poszaehlen ls pos) (- anz 1)))))])
      (zaehlen (startliste (+ (* 5 wuerfel) 1)) anz))))

(define wuerfelausgabe
  (lambda (wuerfel anz)
    (letrec 
        ([ausgabe
          (lambda (ls pos)
            (if (not (null? ls))
                (begin
                  (display "Augenzahl " (number->string pos) ":" (string #\tab) (number->string (car ls)))
                  (ausgabe (cdr ls) (+ pos 1)))))]
         [maximum
          (lambda (ls pos maxpos)
            (if (null? (cdr ls))
                (display "Die Augenzahl " (number->string maxpos) " ist mit der Anzahl " 
                         (number->string (car ls)) " am häufigsten vertreten.")
                (if (> (car ls) (cadr ls))
                    (maximum (cons (car ls) (cddr ls)) (+ pos 1) maxpos)
                    (maximum (cdr ls) (+ pos 1) (+ pos 1)))))]        
         [ergebnis (wuerfeln wuerfel anz)])
      (ausgabe ergebnis wuerfel)
      (maximum ergebnis wuerfel wuerfel)
      (balkendiagramm ergebnis)
      'ok)))
</code>

<canvas w="600" h="400"></canvas>

<run id="5bbcb6c1e6aaf">
(wuerfelausgabe 5 10000)
</run>

Zurück zur [[Grundlagen der funktionsorientierten Programmierung mit SCHEME/Sequenzielle Suche|Sequenziellen Suche]].