Bergervei/Würfeln

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Scheme</language>
== Zufallszahlen ==

Wir erzeugen zunächst einzelne Zufallszahlen.

<run id="4d5c21a49f528">
(randomint 100)
</run>

Dabei stellen wir fest: <tt>(randomint &lt;max&gt;)</tt> gibt eine Zufallszahl <math>z</math> zurück mit <math>0 \le z < max</math>.<br />
Vervollständigen Sie die nachfolgende nullstellige Prozedur, mit der das Würfeln einer Augenzahl <math>z</math> mit <math>1 \le z \le 6</math> simuliert werden kann:

<code id="4d5c21a49f340">
(define wuerfelzahl
  (lambda ()
    ...))
</code>

<code id="4d5c31f09e309" hidden>
(define wuerfelzahl?
  (lambda (proz anz)
    (letrec 
        ([element?
          (lambda (ls el)
            (cond
              [(null? ls) #f]
              [(= (car ls) el) #t]
              [else (element? (cdr ls) el)]))]
         [sammeln
          (lambda (ls anz)
            (if (= anz 0)
                ls
                (let ([z (eval (list proz))])
                  (case z
                    [(1 2 3 4 5 6) 
                     (if (element? ls z)
                         (sammeln ls (- anz 1))
                         (sammeln (cons z ls) (- anz 1)))]
                    [else #f]))))])
      (let ([ergebnis (sammeln () anz)])
        (and ergebnis (= (length ergebnis) 6))))))
</code>

<check>
(wuerfelzahl? wuerfelzahl 100)
</check>

<run id="4d5c21a49f58c">
(wuerfelzahl)
</run>

[[Bild:Wuerfel1.jpg|miniatur|Wurf mehrerer Würfel]]

== Würfeln mit mehreren Würfeln ==

Nun wollen wir 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 <math>1</math> erhöht. 
* Wiederhole die Simulation in der gewünschten (großen) Anzahl.

=== Implementation ===

<code id="4d5c28ef42206" 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="512fddd6d10f7">
(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 ") (display pos) (display ":") (display #\tab) (display (car ls))
                  (newline)
                  (ausgabe (cdr ls) (+ pos 1)))))]
         [maximum
          (lambda (ls pos maxpos)
            (if (null? (cdr ls))
                (begin
                  (display "Die Augenzahl ") (display maxpos) 
                  (display " ist mit der Anzahl ") (display (car ls)) (display " am häufigsten vertreten.")
                  (newline))
                (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="512fddd6d11e6">
(wuerfelausgabe 10 10000)
</run>

=== Aufgaben ===
<ol>
<li>
Übertragen Sie die Ergebnisse der Simulation mit 10 Würfeln in eine Tabellenkalkulation.
</li>
<li>
Untersuchen Sie mit geeigneten Methoden, welche Häufigkeitsverteilung der Augenzahlen vorliegen könnte.
</li>
</ol>