erstellt 24.01.99; überarbeitet 31.07.07, 20.0.08; übersetzt 13.11.12, überarbeitet 06.12.23, 20.02.24, 28.1.25; deutsche Übersetzung Heinrich Gailer


Kapitel 20 Programmieraufgaben

Aufgabe 1 — überlebende Setzlinge

Es ist Frühling und wir planen 10 Tomatensetzlinge einzupflanzen. Die Wahrscheinlichkeit, dass eine einzelne Pflanze überlebt ist 90%. Wie viele der 10 Pflanzen werden überleben?

Wir schreiben ein Programm, dass das simuliert. Wir brauchen eine Schleife mit 10 Loops (einen pro Pflanze). Für jede Pflanze werfen wir einen 10-seitigen Würfel. Wenn die gewürfelte Zahl zwischen 1 und 9 liegt, wird die Pflanze überleben.

Natürlich werden mehrere Programmdurchläufe unterschiedliche Ergebnisse produzieren. Wir starten das Programm ein paar Mal und kalkulieren die durchschnittliche Anzahl der Pflanzen, die die Saison überleben. Oder noch besser wir schreiben ein Programm, das den Durchschnitt der überlebenden Pflanzen für 100 simulierte Jahreszeiten berechnet.


Aufgabe 2 — Ratespiel

Wir schreiben ein Programm, dass ein Ratespiel implementiert. Das ist ein "klassisches" Programm, das häufig in den Anfangsklassen der Informatik gestellt wird.

Das Programm ermittelt eine Zufallszahl zwischen 1 und 10. Der Anwender bekommt jetzt 3 Versuche die Zahl zu erraten. Sobald der Anwender die richtige Zahl eingibt, gibt das Programm eine Gewinnmeldung aus und endet. Wenn der Anwender nach 3 Versuchen die richtige Zahl nicht erraten hat, gibt das Programm eine entsprechende Meldung aus und endet.

Wir verwenden die Methoden der Klasse Random. Hier sind zwei Probeläufe des Programms:

D:\>java Ratespiel

Ich denke an eine Zahl von 1 bis 10.
Sie haben 3 Versuche diese Zahl zu erraten.
Raten Sie:
Versuch: 1
2
Falsch
Versuch: 2
4
Falsch
Versuch: 3
7
Falsch
Die richtige Zahl war 9.
Sie haben das Spiel verloren.

D:\>java Ratespiel

Ich denke an eine Zahl von 1 bis 10.
Sie haben 3 Versuche diese Zahl zu erraten.
Raten Sie:
Versuch: 1
3
Falsch
Versuch: 2
5
RICHTIG!
Sie haben das Spiel gewonnen.

Zurück zum Inhaltsverzeichnis.


Aufgabe 3 — Verbessertes Ratespiel

Wir schreiben ein etwas komplizierteres Ratespiel. Das Programm ähnelt der Aufgabe 1, aber jetzt soll das Programm zusätzlich das Folgende ausgeben:

von der korrekten Antwort entfernt ist. Sobald der Anwender die richtige Zahl eingibt gibt das Programm eine Gewinnmeldung aus und endet:

D:\>java Ratespiel2

Ich denke an eine Zahl von 1 bis 10.
Sie haben 3 Versuche diese Zahl zu erraten.
Raten Sie:
1
kalt
5
RICHTIG!
Sie haben das Spiel gewonnen.


D:\>java Ratespiel2
Ich denke an eine Zahl von 1 bis 10.
Sie haben 3 Versuche diese Zahl zu erraten.
Raten Sie:
4
kalt
5
kalt
8
falsch
Die richtige Zahl war 9.
Sie haben das Spiel verloren.

D:\>java Ratespiel2
Ich denke an eine Zahl von 1 bis 10.
Sie haben 3 Versuche diese Zahl zu erraten.
Raten Sie:
4
hot
5
warm
3
RICHTIG!
Sie haben das Spiel gewonnen.

Die Methode Math.abs() könnte hier nützlich sein.

Zurück zum Inhaltsverzeichnis.


Aufgabe 4 — Weiter verbessertes Ratespiel

Wir schreiben eine noch bessere Version. Jetzt besteht das Spiel aus 10 "Runden", wobei jede Runde aus einem Spiel wie bei Aufgabe 2 besteht. Nach den 10 Runden gibt das Programm aus wie viele Runden gewonnen und wie viele verloren wurden.

Hier ist ein Probelauf:

D:\>java Ratespiel3

Runde 1:

Ich denke an eine Zahl von 1 bis 10.
Sie haben 3 Versuche diese Zahl zu erraten.
Raten Sie:
4
hot
5
RICHTIG!
Sie haben 1 von 1 Runde(n) gewonnen.

Runde 2:

Ich denke an eine Zahl von 1 bis 10.
Sie haben 3 Versuche diese Zahl zu erraten.
Raten Sie:
10
kalt
5
kalt
3
falsch
Die richtige Zahl war 1.
Sie haben 1 von 2 Runde(n) gewonnen.

. . .

Runde 10:

Ich denke an eine Zahl von 1 bis 10.
Sie haben 3 Versuche diese Zahl zu erraten.
Raten Sie:
1
kalt
6
warm
8
RICHTIG!
Sie haben 7 von 10 Runde(n) gewonnen.

Ihre Bewertung: Amateur.

D:\>

Zurück zum Inhaltsverzeichnis.


Aufgabe 5 — Passwort Generator

Diese Aufgabe basiert auf dem Programm PasswortGenerator in diesem Kapitel.

Um das Passwort zu verbessern editieren wir die Zeichenkette in auswahl, so dass sie mehr Ziffern enthält und erhöhen damit die Chancen, dass Ziffern ausgewählt werden. Wir tun das, indem wir einige Male "1234567890" an das Ende von auswahl anhängen. Es gibt keinen Grund warum auswahl nicht einzelne Zeichen mehrmals enthalten kann. Wenn wir Satzzeichen für die Passwörter haben wollten, können wir sie ebenfalls anhängen.

Eine weitere Verbesserung ist, dass ein Passwort mindestens 1 Ziffer enthalten muss. Es gibt mehrere Möglichkeiten das umzusetzen. Wir setzen nicht voraus, dass die erforderliche Ziffer in einem Passwort an einer festen Stelle steht.

Eine weitere Verbesserung ist die Regel, dass auf jeden Konsonanten ein Vokal folgen muss in der gleichen Groß- oder Kleinschreibung. Das macht das Passwort leichter merkbar. Natürlich kann es dann auch leichter erraten werden, besonders wenn ein Hacker weiss das diese Regel verwendet wird.

Zurück zum Inhaltsverzeichnis.


Aufgabe 6 — Passwort Cracker

Ein Passwort Generator kann auch als ein Passwort Cracker verwendet werden. Im Wesentlichen erzeugt dieser Generator Passwörter bis er eines findet, das funktioniert. (Das ist der Grund warum viele Applikationen ein Login nach dreimaliger Falscheingabe verweigern.)

Wir schreiben ein Programm, das den Anwender nach einem Passwort fragt. Der Anwender gibt ein Passwort ein (das kurz sein muss). Jetzt tun wir so, als ob das Passwort dem Rest des Programms nicht bekannt ist. Das Programm verwendet dann wiederholt den Passwort Generator bis ein zufällig erzeugtes Passwort mit dem vom Anwender eingegebenen Passwort übereinstimmt. Wir setzen voraus, dass das eingegebene Passwort aus 5 Zeichen oder weniger besteht (andererseits wird das Programm niemals enden). Das Programm gibt die Anzahl der Versuche um das Passwort zu finden aus. Hier sind ein paar Programmläufe:

D:\cai\>java PasswortCracker
Geben Sie ein "geheimes" Passwort ein:ant
Hier ist Ihr Passwort: ant
Es brauchte 2181892 Versuche um es zu raten

D:\cai\>java PasswortCracker
Geben Sie ein "geheimes" Passwort ein:rats
Hier ist Ihr Passwort: rats
Es brauchte 10956100 Versuche um es zu raten

D:\cai\>java PasswortCracker
Geben Sie ein "geheimes" Passwort ein:frog
Hier ist Ihr Passwort: frog
Es brauchte 91555945 Versuche um es zu raten

D:\cai\>java Passwor7Cracker
Geben Sie ein "geheimes" Passwort ein:moose
Hier ist Ihr Passwort: moose
Es brauchte 279530402 Versuche um es zu raten

Ein besseres Cracker Programm würde systematisch alle möglichen ein-buchstabigen, dann alle möglichen zwei-buchstabigen, dann alle möglichen drei-buchstabigen Passwörter usw. erzeugen. Aber dieses Programm wäre nur sehr schwer ohne Arrays zu schreiben (die in einem späteren Kapitel besprochen werden).

Zurück zum Inhaltsverzeichnis.


Aufgabe 7 — Durchschnitt einer Stichprobe

Der Durchschnitt von 1000 Ganzzahlen von 0 bis 100 ist 500. Die ganzen Zahlen 0 bis 499 liegen auf der einen Seite von 500 und die ganzen Zahlen 501 bis 1000 sind auf der anderen Seite. Der Durchschnitt einer Stichprobe von ganzen Zahlen, die zufällig aus dem Bereich [0,1000] ausgewählt wurden, sollte also etwa 500 betragen.

Wir schreiben ein Programm, das den Benutzer nach der Anzahl der Zahlen, N fragt und dann den Durchschnitt von N zufällig ausgewählten Integern aus dem Bereich von [0,1000] berechnet. Beachtet, dass sowohl die 0 als auch Tausend in dem Bereich enthalten sind. Wir berechnen den Durchschnitt als double-Wert. Natürlich werden wir jedes Mal, wenn wir das Programm für die gleiche Anzahl N ausführen, höchstwahrscheinlich ein anderes Ergebnis erhalten.

Wir führen das Programm für verschiedene Werte von N aus (und zwar mehrere Male für jedes N) und beobachten, wie nahe die Werte bei 500 liegen. Random kann die gleichen Werte mehr als einmal erzeugen, so dass sogar wenn N 1000 ist, der Durchschnitt nicht genau 500 betragen wird.

Zurück zum Inhaltsverzeichnis.


Aufgabe 8 — 1D Random Walk

Eine zufällige Bewegung in einem eindimensionalem Raum ist wo ein Teilchen bei x=0.0 startet und sich dann rechts oder links entlang der x-Achse zufällig bewegt. Beachtet, dass x negativ oder positiv (oder 0) sein kann. Stellt Euch eine Perle aufgefädelt an einer gespannten Schnur vor, die zufällig ihre Position innerhalb einer bestimmten Spanne ändert. Sie bewegt sich zufällig mal links, mal rechts, zufällig mal mehr, mal weniger.

Wir schreiben ein Programm, dass eine Variable x=0 initialisiert, die die Position der Perle repräsentiert. Dann werden x zufällige Beträge im Bereich (-1.0, +1.0) hinzugefügt. Das Programm endet nach einer bestimmten Anzahl von Iterationen. Wir werden die Methode nextDouble() von Random brauchen. Sie muss anpasst werden, um mit dem spezifizierten Bereich übereinzustimmen.

Wie weit entfernt von der Startposition ist x nach 100 Iterationen? 1000 Iterationen? Welche maximale Entfernung ist möglich) und wie wahrscheinlich ist das?


D:\cai\>java RandomWalkOneDim
Wie viele Iterationen?
100
Nach 100 Bewegungen ist x jetzt bei 1.1190381131949723

D:\cai\>java RandomWalkOneDim
Wie viele Iterationen?
1000
Nach 1000 Bewegungen ist x jetzt bei -0.4633309201402265

Wir ändern das Programm so, dass es so lange wiederholt wird, bis die Perle einen bestimmten Abstand (positiv oder negativ) vom Ursprung erreicht. Wir verwenden Math.abs(), um den Abstand zu bestimmen. Wenn Ihr einen großen Abstand wählt, kann es sein, dass Ihr das laufende Programm stoppen müsst, da der Abstand möglicherweise nie erreicht wird. (Auf Windows Systemen könnt Ihr das Programm mit Control-C im DOS-Fenster beenden).

Zurück zum Inhaltsverzeichnis.


Aufgabe 9 — 2D Random Walk

Bei einem zweidimensionalen Random Walk beginnt ein Teilchen bei X=0,0, Y=0,0 und bewegt sich dann in kleinen zufälligen Schritten in X und Y. Wir stellen uns eine verwirrte Ameise vor, die sich zufällig in einem zweidimensionalen Raum bewegt.

Wir schreiben ein Programm, das zwei Variablen X und Y, die die Position der Ameise darstellen, mit 0 initialisiert und dann wiederholt zufällige Werte im Bereich (-1.0, +1.0) zu jeder dieser Variablen addiert. Wir wählen zwei zufällige Werte, einen für X und einen für Y. Das Programm endet nach einer bestimmten Anzahl von Iterationen und gibt die Werte der Koordinaten und den endgültigen Abstand der Ameise vom Ursprung aus. Wir verwenden die Formel von Pythagoras, um den Abstand zu berechnen:

             _______
distance = \/X2 + Y2

Für dieses Programm sind viele Variationen möglich. Zum Beispiel das Zählen der Schritte, die nötig sind, um eine bestimmte Entfernung zu erreichen. Oder man implementiert zwei Ameisen, jede mit ihren eigenen Koordinaten, die beide bei (0, 0) beginnen und 1000 Schritte wandern. Wie weit sind die Ameisen voneinander entfernt? Wenn sich eine Ameise nicht bewegt, sind sie dann näher oder weiter voneinander entfernt, als wenn sie sich beide bewegen?

Natürlich, eine andere Variante wäre die Implementierung eines 3D Zufallslaufs mit den unabhängigen Variablen X, Y und Z. Wir stellen uns z.B. ein verwirrtes Glühwürmchen vor, das zufällig durch die Nacht flattert.

Zurück zum Inhaltsverzeichnis.


Aufgabe 10 — Quadratwurzel Spiel

Wir schreiben ein Programm, das ein Spiel für zwei Spieler implementiert. Der Computer ist der Punktezähler und die beiden Spieler sind Menschen. Jede Spielrunde beginnt damit, dass der Computer zufällig eine Zahl mit doppelter Genauigkeit zwischen 1,0 und etwas weniger als 100,0 auswählt. Jeder Spieler schätzt die Quadratwurzel der Zahl und gibt die Schätzung ein. Der Spieler, dessen Schätzung der richtigen Zahl am nächsten kommt, gewinnt die Runde. Die Spieler wechseln sich ab, wer in jeder Runde den Anfang macht. Das Spiel endet nach einer bestimmten Anzahl von Runden.

Wie viele Runden? 4
Name erster Spieler--> Dweezle
Name zweiter Spieler--> Moon Unit

Wie lautet die Quadratwurzel von 83.29097831183603 ?
Dweezle schaetzt: 9.1
Moon Unit schaetzt: 9.2
Die richtige Quadratwurzel ist: 9.126389116832353
Dweezle ist 0.026389116832353565 entfernt
Moon Unit ist 0.07361088316764608 entfernt
Dweezle gewinnt!

Was ist die Quadratwurzel aus 87.79346957866132 ?
Moon Unit schaetzt: 8.8
Dweezle schaetzt: 8.9
Die richtige Quadratwurzel ist: 9.36981694477866
Dweezle ist 0.46981694477866043 entfernt
Moon Unit ist 0.5698169447786601 entfernt
Dweezle gewinnt!

Was ist die Quadratwurzel aus 67.44682032701256 ?
Dweezle schaetzt: 8.2
Moon Unit schaetzt: 8.1
Die richtige Quadratwurzel ist: 8.212601313044033
Dweezle ist 0.012601313044033446 entfernt
Moon Unit ist 0.11260131304403309 entfernt
Dweezle gewinnt!

Was ist die Quadratwurzel aus 71.64725527288849 ?
Moon Unit schaetzt: 8.4
Dweezle schaetzt: 8.45
Die richtige Quadratwurzel: 8.464470170831042
Dweezle ist 0.01447017083104285 entfernt
Moon Unit ist 0.06447017083104178 entfernt
Dweezle gewinnt!

---- Endergebnis ----
Dweezle: 4 Moon Unit:  0

Wir rufen nach der Anzahl der Iterationen die Methode nextLine() von Scanner auf, um das Zeilen Endezeichen einzulesen. Danach werden die Spielernamen mit nextLine() eingelesen. Wir verwenden nextDouble() für die Schätzungen. Math.abs() und Math.sqrt() werden nützlich sein.

Zurück zum Inhaltsverzeichnis.


Aufgabe 9 — Pig ähnliches Würfelspiel

Das ist ein Würfelspiel ähnlich dem Spiel Pig (auch als Böse Eins bekannt), aber einfacher zu implementieren. Der Spieler spielt gegen den Computer.

  1. Spieler und Computer beginnen mit 0 Punkten.
  2. Der Gewinner ist der erste Spieler, der 100 Punkte oder mehr erreicht.
  3. In jeder Runde würfelt zuerst der Computer, dann der Spieler.
  4. Der Computer würfelt mit drei Würfeln und die Summe der Punkte wird zu seiner Punktzahl addiert.
  5. Zu Beginn des Zuges des Spielers wird eine Arbeitssumme auf 0 gesetzt.
  6. Dann würfelt der Spieler mit einem einzelnen Würfel so oft wie gewünscht.

In einem echten Pig-Spiel würde der Computer wiederholt einen einzelnen Würfel werfen (genau wie der Spieler) und mit Hilfe einer Strategie bestimmen, wann er aufhört.

Zurück zum Inhaltsverzeichnis.