Umschütten (Simulationen)
Gegeben sind zwei Gefäße mit 15 bzw. 7 Liter Fassungsvermögen. Beide Gefäße sind anfänglich leer und weisen keinerlei Markierungen auf. Aus einem Brunnen kann beliebig oft Wasser nachgefüllt werden. Nun sollen 11 Liter mit diesen beiden Gefäßen abgemessen werden. Programmieren Sie nach folgendem Algorithmus eine Lösung, welche die Zwischenresultate und Zwischenschritte auch auf der Konsole ausgeben kann:
- Beide Gefäße leeren (sofern nicht schon geschehen).
- Solange keines der beiden Gefäße die gesuchte Menge (hier 11 Liter) aufweist, werden die folgenden drei Schritte ausgeführt. Wenn jedoch eines der beiden Gefäße (hier nur beim 15-Liter-Gefäß möglich) die gesuchte Menge enthält, wird das Programm mit einer Meldung "Heureka" und den Inhaltsangaben beider Gefäße abgebrochen.
- Ist das größere der beiden Gefäße randvoll (hier 15 Liter), so geben wir "Großes Gefäß leeren" aus, und wir geben den Inhalt der beiden Gefäße aus, nachdem der Inhalt des großen Gefäßes auf Null gesetzt wurde.
- Ist das kleinere der beiden Gefäße (hier 7 Liter) ganz leer, so wird es gefüllt. Ausgabe: "Fülle kleines Gefäß", und wieder geben wir den Inhalt beider Gefäße nach der Operation aus.
- Schütte den Inhalt des kleineren Gefäßes ins größere. Dabei wird nur so viel eingeschüttet, dass das größere Gefäß nicht überschwappt. Ausgabe auf der Konsole: "Schütte x Liter aus dem kleinen Gefäß ins große Gefäß." Danach soll abermals der neue Inhalt beider Gefäße ausgegeben werden.
Die Gefäße sollen durch Variable symbolisiert werden. Das Anzeigen der beiden Inhalte kommt so oft vor, dass sich eine Subroutine anbietet.
Zusatzaufgabe 1: Ergänzen Sie die Aufgabe so, dass die Gefäßgrößen und die Zielmenge vom Anwender eingegeben werden können. Beachten Sie, dass Sie mit einem Gefäß von 9 Litern und einem Gefäß von 6 Litern niemals eine Menge von 5 Litern abmessen können. Sie können jedoch Vielfache des größten gemeinsamen Teilers der beiden Gefäßgrößen erzielen.
Zusatzaufgabe 2: Falls Sie Apfelweinproblem bereits gelöst haben, können Sie nun untersuchen, welches der beiden Verfahren zur besseren Lösung kommt.
0 Kommentare
4 Lösung(en)
import java.util.Scanner;
public class Umschuetten {
public static void main(String[] args) {
new Umschuetten().top();
}
int fassungsvermoegenGross = 0;
int fassungsvermoegenKlein = 0;
int wasserInhaltGross = 0;
int wasserInhaltKlein = 0;
int suchMenge = 0;
int zaehler = 1;
int eingabe1 = 0;
int eingabe2 = 0;
void top() {
lesen();
leeren(); }
void lesen() {
einlesen();
zuweisen(); }
void zuweisen() {
if (eingabe1 < eingabe2) {
fassungsvermoegenGross = eingabe2;
fassungsvermoegenKlein = eingabe1; }
else {
fassungsvermoegenGross = eingabe1;
fassungsvermoegenKlein = eingabe2; }
}
void einlesen() {
Scanner sc = new Scanner(System.in);
System.out
.println("Bitte geben Sie das Fassungsvermögen des ersten Eimers ein: ");
eingabe1 = sc.nextInt();
System.out
.println("Bitte geben Sie das Fassungsvermögen des zweiten Eimers ein: ");
eingabe2 = sc.nextInt();
System.out.println("Bitte geben sie zu suchenden Wassergehalt ein: ");
suchMenge = sc.nextInt(); }
void leeren() {
while (wasserInhaltGross != suchMenge && wasserInhaltKlein != suchMenge) {
zaehler++;
System.out.println("Schritt: " + zaehler);
if (fassungsvermoegenGross == wasserInhaltGross) {
grossesGLeeren(); }
else if (0 == wasserInhaltKlein) {
kleinesGFuellen(); }
else if (fassungsvermoegenGross > wasserInhaltGross) {
umleeren(); }
literAngabe(); }
System.out.println("Heureka!!!"); }
void literAngabe() {
System.out.println("Zwischenstand: ");
System.out.println(" -> Kleineres Gefäß: " + wasserInhaltKlein + "l ");
System.out.println(" -> Grösseres Gefäß: " + wasserInhaltGross + "l \n"); }
void umleeren() {
int leereMengeGross = fassungsvermoegenGross - wasserInhaltGross;
if (wasserInhaltKlein >= leereMengeGross) {
wasserInhaltGross = fassungsvermoegenGross;
wasserInhaltKlein = wasserInhaltKlein - leereMengeGross;
anzeigeUmschuetten(leereMengeGross); }
else {
wasserInhaltGross = wasserInhaltGross + wasserInhaltKlein;
anzeigeUmschuetten(wasserInhaltKlein);
wasserInhaltKlein = 0; }
}
void anzeigeUmschuetten(int menge) {
System.out.println("Leere " + menge + " l Wasser in das größere Gefäß um... "); }
void kleinesGFuellen() {
wasserInhaltKlein = fassungsvermoegenKlein;
System.out.println("Kleineres Gefäß füllen... \n"); }
void grossesGLeeren() {
wasserInhaltGross = 0;
System.out.println("Größeres Gefäß leeren... \n"); }
}
# umschuett(gesuchte Menge, Fassungsvermoegen 1, Fassungsvermoegen 2)
def umschuett(ges_Menge, Fass_gr1, Fass_gr2):
if Fass_gr1 < Fass_gr2:
# Damit ist immer Fass_gr1 > Fass_gr2
umschuett(ges_Menge, Fass_gr2, Fass_gr1)
# beide Gefaesse leeren
F1=0
F2=0
while ((F1 != ges_Menge) & (F2 != ges_Menge)):
if F1 == Fass_gr1:
print "Grosses Gefaess leeren"
F1 =0
print "G1:\t"+str(F1)+"\tG2:\t"+str(F2)
if F2 == 0:
print "Fuelle kleines Gefaess"
F2 = Fass_gr2
print "G1:\t"+str(F1)+"\tG2:\t"+str(F2)
Kapa_F1 = Fass_gr1 - F1
if Kapa_F1-F2<0:
print "Schuette "+str(Kapa_F1)+" Liter aus dem Kleineren in das Grosse"
F2 = F2-Kapa_F1
F1 = F1+Kapa_F1
else:
print "Schuette "+str(F2)+" Liter aus dem Kleineren in das Grosse"
F1=F1+F2
F2=0
print "G1:\t"+str(F1)+"\tG2:\t"+str(F2)
print "Heureka"
umschuett(11,7,15)
public class Gefaess {
final int FASSUNGSVERMOEGEN;
private int aktuelleFuellmenge; // default = 0 Liter
public Gefaess(int fassungsvermoegen) { FASSUNGSVERMOEGEN = fassungsvermoegen; }
public void leeren() { aktuelleFuellmenge = 0; }
public void leeren(int liter) {
aktuelleFuellmenge = aktuelleFuellmenge - liter;
if(aktuelleFuellmenge < 0) {
System.out.println("Will mehr leeren als vorhanden!");
aktuelleFuellmenge = 0;
} }
public void fuellen() { aktuelleFuellmenge = FASSUNGSVERMOEGEN; }
public void fuellen(int liter) {
aktuelleFuellmenge = aktuelleFuellmenge + liter;
if(aktuelleFuellmenge > FASSUNGSVERMOEGEN) {
aktuelleFuellmenge = FASSUNGSVERMOEGEN;
System.out.println("Will mehr einfüllen als das Fassungsvermögen");
}
}
int getAktuelleFuellmenge() { return aktuelleFuellmenge; }
int getRestmenge() { return FASSUNGSVERMOEGEN - aktuelleFuellmenge; }
public boolean istLeer() { return 0 >= aktuelleFuellmenge; }
public boolean istRandvoll() { return FASSUNGSVERMOEGEN <= aktuelleFuellmenge; }
@Override
public String toString() { return aktuelleFuellmenge + " liter sind im " +
FASSUNGSVERMOEGEN + "-Gefäß" ;}
} // end of class Gefaess
///////////////////////////////////////////////////////////////////////////////
import java.util.Scanner;
/**
* Umschütten 10.19 "programmieren lernen"
* @author Philipp Gressly (phi AT gressly DOT ch)
*/
public class Hauptprogramm {
public static void main(String[] args) {
new Hauptprogramm().top();
}
Scanner sc = new Scanner(System.in);
private int einlesenInt(String frage) {
System.out.println("Bitte " + frage + " eingeben: ");
String eingabe = sc.nextLine();
return Integer.parseInt(eingabe);
}
void top() {
int schritte = 0;
Gefaess gefaessKlein = new Gefaess(einlesenInt("kleineres Fassungsvermögen"));
Gefaess gefaessGross = new Gefaess(einlesenInt("groesseres Fassungsvermögen"));
int soll = einlesenInt("Wie viel soll abgemessen werden?");
while(!gefunden(gefaessKlein, gefaessGross, soll)) {
schritte ++;
umschuettvorgang(gefaessKlein, gefaessGross);
}
System.out.println("Heureka");
System.out.println("gefunden in " + schritte + " Schritten.");
}
void umschuettvorgang(Gefaess gefaessKlein, Gefaess gefaessGross) {
// a)
if(gefaessGross.istRandvoll()) {
System.out.println("Großes Gefäß leeren.");
gefaessGross.leeren();
}
// b)
if(gefaessKlein.istLeer()) {
System.out.println("Kleines Gefäß fuellen");
gefaessKlein.fuellen();
}
// c);
kleinesLeerenGrossesFuellen(gefaessKlein, gefaessGross);
}
void kleinesLeerenGrossesFuellen(Gefaess gefaessKlein, Gefaess gefaessGross) {
int restMenge = gefaessGross.getRestmenge();
int umschuettMenge = Math.min(restMenge, gefaessKlein.getAktuelleFuellmenge());
gefaessKlein.leeren (umschuettMenge);
gefaessGross.fuellen(umschuettMenge);
schrittAusgeben(gefaessKlein, gefaessGross, umschuettMenge);
}
void schrittAusgeben(Gefaess gefaessKlein,
Gefaess gefaessGross,
int umschuettMenge) {
System.out.println("Schütte " + umschuettMenge + " von klein nach groß:");
System.out.println("Gefäße neu: " );
System.out.println(" klein : " + gefaessKlein);
System.out.println(" gross : " + gefaessGross);
}
private boolean gefunden(Gefaess g1, Gefaess g2, int soll) {
return g1.getAktuelleFuellmenge() == soll || g2.getAktuelleFuellmenge() == soll;
}
} // end of class Hauptprogramm
Lösung von: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)
function transpour(jug1, jug2, target) {
function Vessel(capacity) {
this.capacity = capacity;
this.content = 0;
}
let big = new Vessel(jug1),
sml = new Vessel(jug2);
function chkTarget() {
if (big.content == target || sml.content == target) {
console.log(`? ? ? ? ? ? !`);
return true;
}
return false;
}
function getContents() {
return `[ ${big.content} | ${sml.content} ]`;
}
function pour() {
let count = 0;
while ((sml.content > 0) && (big.content < big.capacity)) {
count++;
sml.content--;
big.content++;
}
return count;
}
let steps = 0;
// label
threeSteps:
while (!chkTarget()) {
// schritt 1
// großes gefäß leeren, falls es voll ist
if (big.content == big.capacity) {
big.content = 0;
console.log(`Leere großes Gefäß ................................ ${getContents()}`);
steps++;
}
if (chkTarget()) break threeSteps;
// schritt 2
// kleines gefäß füllen, falls es leer ist
if (sml.content == 0) {
sml.content = sml.capacity;
console.log(`Fülle kleines Gefäß ............................... ${getContents()}`);
steps++;
}
if (chkTarget()) break threeSteps;
// schritt 3
// das große gefäß aus dem kleinen füllen
console.log(`Schütte ${pour()} Liter aus dem kleinen Gefäß ins große ... ${getContents()}`);
steps++;
if (chkTarget()) break threeSteps;
if (confirm('Fortfahren?')) continue threeSteps;
else break threeSteps;
}
console.log(`${steps} Schritte ausgeführt.`)
}
// eingabemaske
document.write(`
<p><label>Großes Gefäß (l):</label><br>
<input type="number" id="big" value="15" min="1"></p>
<p><label>Kleines Gefäß (l):</label><br>
<input type="number" id="sml" value="7" min="1"></p>
<p><label>Zielmenge (l):</label><br>
<input type="number" id="tgt" value="11" min="1"></p>
<p><button id="go" onclick="go()">Los!</button></p>
`);
function go() {
let big = document.getElementById('big');
sml = document.getElementById('sml');
tgt = document.getElementById('tgt');
go = document.getElementById('go');
big.disabled = true; sml.disabled = true;
tgt.disabled = true; go.disabled = true;
transpour(big.value, sml.value, tgt.value);
} // lissalanda@gmx.at
Lösung von: Lisa Salander (Heidi-Klum-Gymnasium Bottrop)
Verifikation/Checksumme:
Bei Gefäßen mit 11 und 21 Litern und einer Suchmenge von 15 Litern sind mit diesem Algorithmus 27 Schritte notwendig.
Aktionen
Neue Lösung hinzufügen
Bewertung
Durchschnittliche Bewertung:
Meta
Zeit: | 1 |
Schwierigkeit: | k.A. |
Webcode: | dob2-r5tp |
Autor: | Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch) |