Grundlagen der funktionsorientierten Programmierung mit SCHEME/Der zerbrochene Stab
Aus ProgrammingWiki
Wiki-Quelltext dieser Seite.
<language>SchemeJS</language>
<code id="5ba50e77db168" hidden>
(define eps 0.1)
</code>
Ein Stab mit der Länge von einem Meter fällt vom Tisch und zerbricht millimetergenau in höchstens drei Teile.<br />
Mit welcher Wahrscheinlichkeit lässt sich aus den Bruchstücken ein Dreieck legen?
== Dreieckprüfer ==
Im Abschnitt [[Grundlagen der funktionsorientierten Programmierung mit SCHEME/Bedingte Ausdrücke|Bedingte Ausdrücke]] haben wir bereits ein Prädikat entwickelt, das die Konstruierbarkeit eines Dreieckes zu drei vorgegebenen Seitenlängen überprüft:
<code id="5094596091009">
(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="5094596091248">
(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, erscheint ein entsprechender Bildschirmhinweis:
<code id="5ba50e77db1fe">
(define ausgabe
(lambda (anz)
(let* ([a ...] [b ...] [c (- 1000 a b)])
(if (= anz 0)
'ok
(begin
(if (konstruierbar? a b c)
(display a (string #\tab) b (string #\tab) c (string #\tab) "--> Dreieck!")
(display a (string #\tab) b (string #\tab) c))
(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="50945960912b0">
(ausgabe 20)
</run>
Nach dem erfolgreichen Test sollen nun die Ereignisse gezählt werden, in denen aus den Bruchstücken ein beliebiges Dreieck gelegt werden kann.
=== Echt rekursive Prozedur ===
<code id="50945960910de">
(define simulation-rek
(lambda (anz)
...))
</code>
<check>
(< (abs (- (/ (simulation-rek 1000) 1000) 0.191)) eps)
</check>
<run id="5094596091316">
(simulation-rek 100)
</run>
=== Endständig rekursive Prozedur ===
<code id="5094596091149">
(define simulation-it
(lambda (anz)
(simulation-help anz 0)))
(define simulation-help
(lambda (anz n)
...))
</code>
<check>
(< (abs (- (/ (simulation-it 1000) 1000) 0.191)) eps)
</check>
<run id="50945960913a2">
(simulation-it 100)
</run>
=== Relative Häufigkeit ===
Mit einer der beiden Implementationen kann nun die relative Häufigkeit bestimmt werden, die bei hinreichend großen Versuchszahlen zur Wahrscheinlichkeit konvergiert:
<code id="5ba50e77db28a">
(define haeufigkeit
(lambda (anz)
(/ (simulation-rek anz) anz)))
</code>
<run id="509459609140d">
(haeufigkeit 7550)
</run>
Zurück zu [[Grundlagen der funktionsorientierten Programmierung mit SCHEME/Echte und endständige Rekursionen|echten und endständigen Rekursionen]].