Bergervei/Glücksrad

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Scheme</language>
<code id="56411c02a4c0e" hidden>
;-- M. Hielscher / Chr. Wagenknecht --
(define random-maker
 (let* ((multiplier 48271)
        (modulus 21474836)
        (apply-congruence
         (lambda (current-seed)
           (let ((candidate (modulo (* current-seed multiplier) modulus)))
             (if (zero? candidate)
                 modulus
                 candidate))))
        (coerce
         (lambda (proposed-seed)
           (if (integer? proposed-seed)
               (- modulus (modulo proposed-seed modulus))
               19860617))))
 (lambda (initial-seed)
   (let ((seed (coerce initial-seed)))
     (lambda args
       (cond ((null? args)
              (set! seed (apply-congruence seed))
              (/ (- modulus seed) modulus))
             ((null? (cdr args))
              (let* ((proposed-top
                      (ceiling (abs (car args))))
                     (exact-top
                      (if (inexact? proposed-top)
                          (inexact->exact proposed-top)
                          proposed-top))
                     (top
                      (if (zero? exact-top)
                          1
                          exact-top)))
                (set! seed (apply-congruence seed))
                (inexact->exact (floor (* top (/ seed modulus))))))
             ((eq? (cadr args) 'reset)
              (set! seed (coerce (car args))))
             (else
              (display "random: unrecognized message")
              (newline))))))))

(require-library 'sisc/libs/srfi/srfi-19)
(import srfi-19)

(define random (random-maker (time-nanosecond (current-time))))

(define sortieren
  (lambda (ls)
    (letrec 
        ([streichen
          (lambda (el ls)
            (cond
              [(null? ls) ls]
              [(equal? el (car ls)) (cdr ls)]
              [else
               (cons (car ls) (streichen el (cdr ls)))]))]
         [sort
          (lambda (ls)
            (if (null? ls)
                ls
                (let ([z (apply min ls)])
                  (cons z (sort (streichen z ls))))))])
      (sort ls))))

(define eps 0.1)
</code>

<table border="0">
<tr valign="top">
<td>
Ein Glücksrad besteht aus 3 blauen, 4 gelben und 5 roten Feldern.<br /> 
Implementieren Sie eine nullstellige Prozedur, die das einmalige Drehen dieses Glücksrades simuliert und die entsprechende Farbe als Symbol zurückgibt.

<code id="5640c170dc70f">
(define gluecksrad
  (lambda ()
     ...)
</code>

<code id="56411c02a4c8d" hidden>
(define gluecksrad-test
  (lambda (n)
    (do ((i 1 (+ i 1))
         (ls '(0 0 0)
             (let ([farbe (gluecksrad)])
               (cond
                 [(eqv? farbe 'blau) (list (+ 1 (car ls)) (cadr ls) (caddr ls))]
                 [(eqv? farbe 'gelb) (list (car ls) (+ 1 (cadr ls)) (caddr ls))]
                 [else
                  (list (car ls) (cadr ls) (+ 1 (caddr ls)))]))))
      ((> i n) ls))))

(define gluecksrad-korrekt?
  (lambda (n)
    (let ([ls (sortieren (gluecksrad-test n))])
      (and (< (abs (- 1 (/ (car ls) n 3/12))) eps)
           (< (abs (- 1 (/ (cadr ls) n 4/12))) eps)
           (< (abs (- 1 (/ (caddr ls) n 5/12))) eps)))))
</code>

<check>
(gluecksrad-korrekt? 1000)
</check>

<run id="564113104ca16">
(gluecksrad)
</run>
</td>
<td>
[[Datei:Glücksrad1.jpg|miniatur||hochkant=0.8|Kommerzielles mehrfarbiges Glücksrad]]
</td>
</tr>
</table>

Um die Verteilung der Farben zu ermitteln, soll nun das Glücksrad mehrfach gedreht werden.<br /> 
Mit der nachfolgenden ''echt rekursiven Prozedur'' wird dieser Vorgang simuliert:

<code id="56411c02a4d04">
(define gluecksrad-drehen-rek
  (lambda (n)
    (if (= n 0)
        (list 0 0 0)
        (let ([farbe (gluecksrad)] [ls (gluecksrad-drehen-rek (- n 1))])
          (cond
            [(equal? farbe 'blau) (list (+ 1 (car ls)) (cadr ls) (caddr ls))]
            [(equal? farbe 'gelb) (list (car ls) (+ 1 (cadr ls)) (caddr ls))]
            [else
             (list (car ls) (cadr ls) (+ 1 (caddr ls)))])))))
</code> 

<run id="56411c02a4e52">
(gluecksrad-drehen-rek 1000)
</run>

Entwickeln Sie eine ''endständig rekursive Prozedur'', die gleiches leistet.

<code id="56411c02a4d6c">
(define gluecksrad-drehen-it
  (lambda (n)
    ...))
</code>

<code id="56411c02a4dd5" hidden>
(define gluecksrad-it-korrekt?
  (lambda (n)
    (let ([ls (sortieren (gluecksrad-drehen-it n))])
      (and (< (abs (- 1 (/ (car ls) n 3/12))) eps)
           (< (abs (- 1 (/ (cadr ls) n 4/12))) eps)
           (< (abs (- 1 (/ (caddr ls) n 5/12))) eps)))))
</code>

<check>
(gluecksrad-it-korrekt? 1000)
</check>

<run id="56411c02a4eb7">
(gluecksrad-drehen-it 1000)
</run>