Bergervei/Der zerbrochene Stab

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Scheme</language>
<code id="509305a3583b9" 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 zufallszahl
  (lambda (a b)
    (+ a (random (- b a -1)))))
</code>

Ein Stab mit der Länge von einem Meter fällt vom Tisch und zerbricht millimetergenau in höchstens drei Teile.
Mit welcher Wahrscheinlichkeit lässt sich aus den Bruchstücken ein Dreieck legen?<br />
Simulieren Sie diesen Vorgang in jeweils einer echtrekursiven bzw. endständig rekursiven Prozedur.

== Dreieckprüfer ==

Im Abschnitt [[Grundlagen der funktionsorientierten Programmierung mit SCHEME/Bedingte Ausdrücke|Bedingte Ausdrücke]] haben wir bereits ein Prädikat entwickelt, dass die Konstruierbarkeit eines Dreieckes zu drei vorgegebenen Seitenlängen überprüft:

<code id="509305a358438">
(define konstruierbar?
  (lambda (a b c)
    ...))
</code>

<check>
(and (konstruierbar? 3 4 5) (not (konstruierbar? 2 7 2)) (not (konstruierbar? 9 3 6)))
</check>

<run id="509305a358508">
(konstruierbar? 3 4 5)
</run>

== Simulation ==

=== Bildschirmausgabe ===

Zunächst wollen wir mit einer geeigneten Testprozedur den Vorgang simulieren, ohne eine konkrete Auswertung vorzunehmen.
Mit der nachfolgenden Prozedur sollen zufällige Bruchstücke des Stabes generiert und angezeigt werden. Falls aus diesen Bruchstücken ein Dreieck gelegt werden kann, soll uns das angezeigt werden:

<code id="509305a35848d">
(define ausgabe
  (lambda (anz)
    (let* ([a ...] [b ...] [c (- 1000 a b)])
      (if (= anz 0)
          'ok
          (begin
            (display a) (display #\tab) (display b) (display #\tab) (display c) 
            (if (konstruierbar? a b c) (begin (display #\tab) (display "--> Dreieck!"))) 
            (newline)
            (ausgabe (- anz 1)))))))
</code>

'''Hinweis:'''

Mit dem Sprachelement <tt>let*</tt> können lokale Wertbindungen vereinbart werden, bei denen neu festzulegende Variablen auf bereits definierte Variablen zugreifen können.<br />

<run id="509305a358563">
(ausgabe 20)
</run>