In der zweiten praktischen Aufgabe aus den ersten Einsendeaufgaben für den Kurs der Einführung in die imperative Programmierung ging es darum ein Programm zu schreiben das folgende Aufgabenstellung erfüllt:
Das Programm soll einen Geldbetrag in Cent einlesen. Der Bereich reicht von 1 – 99 Cent, eine Prüfung darauf findet aber nicht statt. Der eingegebene Betrag soll dann so auf die im Umlauf befindlichen Geldmünzen (1, 2, 5, 10, 20, 50 Cent) aufgeteilt werden, sodass eine Kombination herauskommt, durch die man so wenig Münzen wie möglich für den Geldbetrag benötigt.
Eine Einschränkung für das Bestehen der Testfälle durch das Testsystem der FernUni besteht darin, dass das Programm nur eine einzige Zeile mit „write“ oder „writeln“ ausgeben darf. In der ausgegebenen Zeile muss dann die Anzahl der Münzen in absteigender Reihenfolge für 50, 20, 10, 5, 2, 1 Cent jeweils durch Leerzeichen getrennt erfolgen, beispielsweise so:
Eingabe: 83, Ausgabe: 1 1 1 0 1 1
Man muss die Programmreihenfolge so gestalten, dass zuerst die Anzahl der 50 Cent-Münzen, am einfachsten durch eine Division, bestimmt wird und dann der Restbetrag ermittelt und dasgleiche Verfahren für die übrigen Münzen immer wiederholt wird. Man kann sich das ganze vielleicht wie eine Art „Sieben“ vorstellen, wo man immer bei jedem Vorgang dann ein dichteres Sieb benutzt und man so nach und nach immer die kleineren Münzen auffängt.
Mein erster Entwurf war noch etwas „aufgeblasen“, da ich unnötigerweise if-Abfragen genutzt habe:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
program Muenze (input, output); { liest den Centbetrag bis 99 Cent ein und teilt ihn auf Münzen bis 50 Cent auf } var Betrag, Muenze50, Muenze20, Muenze10, Muenze5, Muenze2, Muenze1 : integer; begin readln (Betrag); if Betrag >= 50 then begin Muenze50 := Betrag div 50; Betrag := Betrag - (50 * Muenze50); end; if Betrag >= 20 then begin Muenze20 := Betrag div 20; Betrag := Betrag - (20 * Muenze20); end; if Betrag >= 10 then begin Muenze10 := Betrag div 10; Betrag := Betrag - (10 * Muenze10); end; if Betrag >= 5 then begin Muenze5 := Betrag div 5; Betrag := Betrag - (5 * Muenze5); end; if Betrag >= 2 then begin Muenze2 := Betrag div 2; Betrag := Betrag - (2 * Muenze2); end; if Betrag >= 1 then begin Muenze1 := Betrag div 1; Betrag := Betrag - (1 * Muenze1); end; writeln (Muenze50, ' ', Muenze20, ' ', Muenze10, ' ', Muenze5, ' ', Muenze2, ' ', Muenze1); end. { Muenzen } |
Diese ganzen if-Abfragen benötigt man aber gar nicht, da die jeweilige Berechnung zur Ermittlung der Münzen-Anzahl einfach immer ausgeführt werden kann, da durch den immer geminderten Restbetrag keinerlei Risiko besteht, dass etwas falsch berechnet wird. Wenn die Münzengröße nicht in den Restbetrag passt, kommt halt einfach eine Null raus.
Ebenso war die letzte Änderung der Variable „Betrag“ unnötig, da diese nach der Ermittlung der 1 Cent-Münzen ja nie wieder benötigt wird. Also kann man sich das sparen.
Die optimierte Version sieht so aus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
begin readln(Betrag); Muenze50 := Betrag div 50; Betrag := Betrag - 50 * Muenze50; Muenze20 := Betrag div 20; Betrag := Betrag - 20 * Muenze20; Muenze10 := Betrag div 10; Betrag := Betrag - 10 * Muenze10; Muenze5 := Betrag div 5; Betrag := Betrag - 5 * Muenze5; Muenze2 := Betrag div 2; Betrag := Betrag - 2 * Muenze2; Muenze1 := Betrag div 1; writeln (Muenze50, ' ', Muenze20, ' ', Muenze10, ' ', Muenze5, ' ', Muenze2, ' ', Muenze1); end. { Muenze } |
Wenn man die Ausgabe der Ergebniszeile länger als einen ganz kurzen Moment sehen will muss man noch den obligatorischen „readln“-Befehl am Ende des Programms einbauen. Für das Testsystem der FernUni ist dies nicht nötig.
Download der ersten Variante:
EA1_A5_Muenze.zip
Download der optimierten Variante:
EA1_A5_Muenze_optimiert.zip