Zahlenratespiel von Stroustrup
-
Hallo
Ich bin ein ganz frischer C++ Anfänger und Arbeite gerade B. Stroustrup's "Einführung in die Programmierung mit C++ (dt. Ausgabe)" durch.Ich hoffe jemand zu finden der die Übung auf Seite 153, Nr.4 seiner Meinung
nach erfolgreich gelöst hat und/oder jemand der mir evtl. einen "Wink mit dem Zaunpfahl" zur Codereduzierung geben kann. :pEs geht konkret um folgende Übung:
Schreiben Sie ein Programm für ein Zahlenratespiel. Der Benutzer denkt sich eine Zahl zwischen
1 und 100 und Ihr Programm stellt Fragen, um herauszufinden, wie die gesuchte Zahl lautet (z.B.
"Ist die gedachte Zahl kleiner als 50?"). Ihr Programm sollte in der Lage sein, die Zahl nach nur sieben
Fragen erfolgreich zu raten. Hinweis: Verwenden Sie die Operatoren < und <= sowie das if-else-Konstrukt.Hier stellt sich mir schon mal die Frage "zwischen 1-100"?. Also ist von 2 bis 99 gemeint?. Ich gehe davon aus das es schlecht übersetzt wurde oder mein Verständnis gerade Urlaub macht und nehme "von 1 bis 100".
Nach drei Tagen knuspern an der Aufgabe funktioniert es immerhin soweit das ich mit sieben oder weniger Fragen alles von 1-50 erraten kann. Das sind jetzt aber schon 500 Zeilen Code. Die restlichen 500 Zeilen Fleißarbeit der Zahlen 51-100 habe ich mir jetzt mal gespart da es ja im Prinzip funktioniert.
Mein Ansatz ist:
Ist die Zahl:
1-50/51-100
gerade/ungerade
und dann immer im Ausschlussverfahren die Hälfte der restlichen
mit "<=" herauszufiltern.Die Frage für mich ist, war das ganze eine Fleißaufgabe oder
gibt es doch noch eine Möglichkeit das ganze kürzer zu machen.
Da in dem Buch die "Funtktion" kurz angerissen wurde denke ich
man könnte zumindest die Ausgabe "Falsche eingabe" abkürzen.
Aber um das eigentliche if-else,else Konstrukt kommt man in dem
Umfang wohl nicht vorbei.Hier ist der Code:
/* Schreiben Sie ein Programm für ein Zahlenratespiel. Der Benutzer denkt sich eine Zahl zwischen 1 und 100 und Ihr Programm stellt Fragen, um herauszufinden, wie die gesuchte Zahl lautet (z.B. "Ist die gedachte Zahl kleiner als 50?"). Ihr Programm sollte in der Lage sein, die Zahl nach nur sieben Fragen erfolgreich zu raten. Hinweis: Verwenden Sie die Operatoren < und <= sowie das if-else-Konstrukt. */ #include "std_lib_facilities.h" // vorgefertigte Datei für das Buch int main() // C++-Programme beginnen mit der Ausführung von main { int zahl =0; char qst = 'n'; cout << "Ich bin der schlaue Computer, bitte denken Sie sich eine Zahl! \n"; cout << "1. Ist die Zahl zwischen 1 und 50 (j,n)\n"; cin >> qst; if (qst == 'j') { cout << "2. Ist die Zahl 1 bis 25?\n"; cin >> qst; // ----------------------------------------------------------------------------------------------- if (qst == 'j') // ist 1-25 { cout << "3. Ist die Zahl gerade?:\n"; cin >> qst; if (qst == 'j') // ist 2,4,6,8,10,12,14,16,18,20,22,24 { cout << "4. Ist die Zahl 12 oder kleiner?"; cin >> qst; if (qst == 'j') // ist 2,4,6,8,10,12 { cout << "5. Ist die Zahl 6 oder kleiner?"; cin >> qst; if (qst == 'j') // ist 2,4,6 { cout << "6. Ist die Zahl 4 oder kleiner?"; cin >> qst; if (qst == 'j') // ist 4,2 { cout << "7. Ist die Zahl 4 ?"; cin >> qst; if (qst == 'j') // ist 2 { cout << "Die Zahl ist 2!\n"; } else if (qst == 'n') // ist 4 { cout << "Die Zahl ist 4!\n"; } else cout << "Falsche Eingabe!"; } else if (qst == 'n') { cout << "Die Zahl ist 6!"; } else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // ist 8,10,12 { cout << "6. Ist die Zahl 10 oder kleiner?"; cin >> qst; if (qst == 'j') // ist 8,10 { cout << "7. Ist die Zahl 10?\n"; cin >> qst; if (qst == 'j') // ist 10 { cout << "Die Zahl ist 10!"; } else if (qst == 'n') // ist 8 { cout << "Die Zahl ist 8!\n"; } else cout << "Falsche Eingabe!"; } else if (qst == 'n') // ist 12 { cout << "Die Zahl ist 12!\n"; } else cout << "falsche Eingabe!"; } else cout << "falsche Eingabe!"; } else if (qst == 'n') // ist 14,16,18,20,22,24 { cout << "5. Ist die Zahl 18 oder kleiner?"; cin >> qst; if (qst == 'j') // ist 14,16,18 { cout << "6. Ist die Zahl 16 oder kleiner?\n"; cin >> qst; if (qst == 'j') // ist 14,16 { cout << "7. Ist die Zahl 16?\n"; cin >> qst; } else if (qst == 'n') { cout << "Die Zahl ist 18!\n"; } else cout << "Falsche Eingabe!"; } else if (qst == 'n') // ist 20,22,24 { cout << "6. Ist die Zahl 22 oder kleiner?\n"; cin >> qst; if (qst == 'j') // ist 20,22 { cout << "Ist die Zahl 22?\n"; cin >> qst; if (qst == 'j') { cout << "Die Zahl ist 22 !\n"; } else if (qst == 'n') { cout << "Die Zahl ist 20!\n"; } else cout << "Falsche Eingabe!"; } else if (qst == 'n') // ist 24 { cout << "Die Zahl ist 24!\n"; } else cout << "Falsche Eingabe!"; } else cout << "Falsche Eingabe!"; } else cout << "Falsche Eingabe!"; } // ------------------------------------------------------------------------------------------ else if (qst == 'n') // ist 1,3,5,7,9,11,13,15,17,19,21,23,25 { cout << "4. Ist die Zahl 13 oder kleiner?\n"; cin >> qst; if (qst == 'j') // ist 1,3,5,7,9,11,13 { cout << "5. Ist die Zahl 5 oder kleiner?\n"; cin >> qst; if (qst == 'j') // ist 1,3,5, { cout << "6. Ist die Zahl 3 oder kleiner?\n"; cin >> qst; if (qst == 'j') // ist 1,3 { cout << "7. Ist die Zahl 3 ?\n"; cin >> qst; if (qst == 'j') // ist 3 { cout << "Die Zahl ist 3! \n"; } else if (qst == 'n') { cout << "Die Zahl ist 1 !\n"; } else cout << "Falsche Eingabe!"; } else if (qst == 'n') // ist 5 { cout << "Die Zahl ist 5\n"; } else cout << "Falsche Eingabe!"; } else if (qst == 'n') // ist 7,9,11,13 { cout << "6. Ist die Zahl 7 oder 9?\n"; cin >> qst; if (qst == 'j') // ist 7,9 { cout << "7. Ist die Zahl 7 ?\n"; cin >> qst; if (qst == 'j') // ist 7 { cout << "Die Zahl ist 7 ! \n"; } else if (qst == 'n') // ist 9 { cout << "Die Zahl ist 9"; } else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // ist 11,13 { cout << "Ist die Zahl 11 ?\n"; cin >> qst; if (qst == 'j') // ist 11 { cout << "Die Zahl ist 11 ! \n"; } else if (qst == 'j') // ist 13 { cout << "Die Zahl ist 13 !\n"; } else cout << "Falsche Eingabe!\n"; } else cout << "Falsche Eingabe!\n"; } else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // ist 15,17,19,21,23,25 { cout << "5. Ist die Zahl 19 oder kleiner?\n"; cin >> qst; if (qst == 'j') // ist 15,17,19 { cout << "6. Ist die Zahl 17 oder kleiner?\n"; cin >> qst; if (qst == 'j') // ist 15,17 { cout << "6. Ist die Zahl 17?\n"; cin >> qst; if (qst == 'j') // ist 17 { cout << "Die Zahl ist 17! \n"; } else if (qst == 'n') // ist 15 { cout << "Die Zahl ist 15! \n"; } else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // ist 19 { cout << "Die Zahl ist 19!"; } else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // ist 21,23,25 { cout << "6. Ist die Zahl 23 oder kleiner?"; cin >> qst; if (qst == 'j') // ist 21,23 { cout << "7. Ist die Zahl 23? \n"; cin >> qst; if (qst == 'j') // ist 23 { cout << "Die Zahl ist 23! \n"; } else if (qst == 'n') // ist 21 { cout << "Die Zahl ist 21! \n"; } else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // ist 25 { cout << "Die Zahl ist 25!\n"; } else cout << "Falsche Eingabe!\n"; } else cout << "Falsche Eingabe!\n"; } else cout << "Falsche Eingabe!\n"; } } // --------------------------------------------------------------------------------------------- else if (qst == 'n') // ist 26-50 { cout << "3. Ist die Zahl gerade?:\n"; cin >> qst; if (qst == 'j') // ist 26,28,30,32,34,36,38,40,42,44,46,48,50 { cout << "4. Ist die Zahl 36 oder kleiner\n"; cin >> qst; if (qst == 'j') // ist 26,28,30,32,34,36 { cout << "5. Ist die Zahl 30 oder kleiner?\n"; cin >> qst; if (qst == 'j') // ist 26,28,30 { cout << "6. Ist die Zahl 28 oder kleiner?\n"; cin >> qst; if (qst == 'j') // ist 26,28 { cout << "7. Ist die Zahl 28?\n"; cin >> qst; if (qst == 'j') // ist 28 { cout << "Die Zahl ist 28! \n"; } else if (qst == 'n') // ist 26 { cout << "Die Zahl ist 26!\n"; } else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // ist 30 { cout << "Die Zahl ist 30\n"; } else cout << "Falsche Eingabe!\n"; } } else if (qst == 'n') // ist 38,40,42,44,46,48,50 { cout << "5. Ist die Zahl 42 oder kleiner?\n"; cin >> qst; if (qst == 'j') // ist 28,40,42 { cout << "6. Ist die Zahl 40 oder kleiner?\n"; cin >> qst; if (qst == 'j') // ist 28,40 { cout << "7. Ist die Zahl 40?\n"; cin >> qst; if (qst == 'j') // ist 40 { cout << "Die Zahl ist 40!\n"; } else if (qst == 'n') // ist 28 { cout << "Die Zahl ist 28!\n"; } else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // ist 42 { cout << "Die Zahl ist 42!\n"; } else cout << "Falsche Eingabe!\n"; } } else if (qst == 'n') // ist 44,46,48,50 { cout << "6. <=46 ?"; cin >> qst; if (qst == 'j') // 44,46 { cout << "7. 46?\n"; cin >> qst; if (qst == 'j') // ist 46 { cout << "Ist 46!\n"; } else if (qst == 'n') // ist 44 { cout << "Ist 44!\n"; } else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // ist 48,50 { cout << "6. 48?\n"; cin >> qst; if (qst == 'j') // ist 48 { cout << "Ist 48!\n"; } else if (qst == 'n') // ist 50 { cout << "Ist 50!\n"; } else cout << "Falsche Eingabe!\n"; } } else cout << "Falsche Eingabe!\n"; } // ----------------------------------------------------------------------------------- else if (qst == 'n') // ist 27,29,31,33,35,37,39,41,43,45,47,49 { cout << "4. <=37 ?\n"; cin >> qst; if (qst == 'j') // ist 27,29,31,33,35,37 { cout << "5. <=31 ?\n"; cin >> qst; if (qst == 'j') // ist 27,29,31 { cout << "6. <=29 ?\n"; cin >> qst; if (qst == 'j') // ist 27,29 { cout << "7. =29 ?"; cin >> qst; if (qst == 'j') // 29 { cout << "Ist 29!\n"; } else if (qst == 'n') // 27 { cout << "Ist 27!\n"; } } else if (qst == 'n') // 31 { } else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // ist 33,35,37 { cout << " <=35 ?\n"; cin >> qst; if (qst == 'j') // 33,35 { cout << " =35?\n"; cin >> qst; if (qst == 'j') // 35 { cout << " =35!\n"; } else if (qst == 'n') cout << " =33\n"; else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // 37 cout << " =37!\n"; else cout << "Falsche Eingabe!\n"; } else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // ist 39,41,43,45,47,49 { cout << " <=43 ?\n"; cin >> qst; if (qst == 'j') // 39,41,43 { cout << " <=41 ?\n"; cin >> qst; if (qst == 'j') // 39,41 { cout << " =41?\n"; cin >> qst; if (qst == 'j') // 41 cout << " =41!\n"; else if (qst == 'n') // 39 cout << " =39!\n"; else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // 43 cout << " =43!\n"; else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // 45,47,49 { cout << " <=47 ?\n"; cin >> qst; if (qst == 'j') // 45,47 { cout << " =47 ?\n"; cin >> qst; if (qst == 'j') // 47 cout << " =47!\n"; else if (qst == 'n') // 45 cout << " =45!\n"; else cout << "Falsche Eingabe!\n"; } else if (qst == 'n') // 49 cout << " =49!\n"; else cout << "Falsche Eingabe!\n"; } } else cout << "Falsche Eingabe!\n"; } else cout << "Falsche Eingabe!\n"; } else cout << "Falsche Eingabe!\n"; } //-------------------------------------------------------------------------------- else if (qst == 'n') // ist zwischen 50-100 { cout << "Ist die Zahl zwischen 50 und 75?\n"; cin >> qst; if (qst == 'j') // ist zwischen 50-75 { cout << "Ist die Zahl gerade?:\n"; cin >> qst; } else if (qst == 'n') // ist zwischen 75-100 { cout << "Ist die Zahl gerade?:\n"; cin >> qst; } else cout << "Falsche Eingabe!\n"; } else // TODO (astro#1#): test cout << "falsche Eingabe!"; return 0; }
-
Ich kenne das Buch nicht.
Waren noch keine Schleifen an der Reihe?
1. Du hast zwei (obere und untere) Grenzen (am Anfang 1 und 100).
2. Du berechnest die Mitte daraus.
3. Dann fragst du den Nutzer ob seine Zahl größer oder kleiner-gleich der Mitte ist.
4. Je nach Antwort, setzt du die obere oder untere Grenze auf die bisherige Mitte.
5. ist obere und untere Grenze gleich? Nein, dann weiter bei 2.
6. Fertig.
-
DirkB schrieb:
Waren noch keine Schleifen an der Reihe?
Doch, es wurde "while", "for" und "vector" schon angeschnitten.
Ich dachte halt nur if-else weil nichts anderes in der Aufgabe steht.
Ich kanns mir aber auch nicht Vorstellen das ich 1000 Zeilen schreiben soll.
Ich werde dein Vorschlag mal durchprobieren, danke erstmal.
-
Du kannst schon alles verwenden, das bereits behandelt wurde, es sei denn es wird explizit ausgeschlossen.
-
Marthog schrieb:
Du kannst schon alles verwenden, das bereits behandelt wurde, es sei denn es wird explizit ausgeschlossen.
Ok, danke.
-
#include <iostream> using namespace std; int main() { cout<<"[1,100]?"; char c;int i,l=1,u=100;cin>>i; while(i=l+(u-l)/2,u-l>1)cout<<l<<"<=x<="<<i<<"?",cin>>c,c=='y'?u=i:l=i+1; cout<<"x<"<<u<<'?';cout<<"x="<<(cin>>c,c=='y'?l:u)<<'\n'; }Jemand Lust auf Golf?

// edit: -6
// edit2: -20
// edit3: länge über alles ohne whitespace: 238
-
Bitte ma noch keine Komplettlösung posten bis ich eine habe, auch wenn ich den Ehrgeiz einiger Leute geweckt haben sollte! Ich guck da jetzt mal extra weg! Ich will erstmal für mich eine Lösung finden.

-
Die Lösung ist sowieso extrem unleserlich und kryptisch geschrieben.
Swordfish hat zum Code-Golf aufgerufen, das heißt, dass für fortgeschrittene triviale Programm so kurz und/oder kryptisch wie möglich zu schreiben, indem man sämtliche Tricks der Sprache ausnutzt.
-
Nicht auf Kürze, dafür aber auf Würze optimiert:
#include <stdio.h> char i;template<int I,int O>struct o{void L(){const int _=(I+O)>>1;printf(">%d?" ,_);scanf(" %c",&i);(i-0x6E)?o<_+1,O>().L():o<I,_>().L();}};template<>template< int _>struct o<_, _>{void L(){printf("=%d!\n",_);}};int main(){o<0,0x64>().L();}
-
omfg.
hib mir ne Stunde dann steig ich vielleicht durch 
// wenn nicht
'n'? ne, sorry, das ist ja nur noch gemein
-
Ich dachte zuerst wir sind im Taschenrechner-Thread und SeppJ hätte was erstaunliches erbracht.Einfachere Version, Fehlerfreiheit nicht garantiert:
#include <cstdio> template<int I,int O> void L() { const int _=(I+O) >> 1; if (I == O) return (void)printf("=%d!\n", _); printf(">%d?", _); char i; scanf(" %c", &i); if (i != 'n') return L<_+1,O>(); L<I,_>(); } int main() { L<0,100>(); }... und schon merkt man wie kaputt der Code tatsächlich ist.
-
Arcoth schrieb:
Einfachere Version, [...]
Tja, wenns darum ginge ...
-
Swordfish schrieb:
Arcoth schrieb:
Einfachere Version, [...]
Tja, wenns darum ginge ...
Dir ist schon klar dass das einfach SeppJ's code ist, aber auseinandergenommen und mit Leerraum versehen?
-
No-na?
-
Hier ist eine verständliche Version:
https://www.c-plusplus.net/forum/p2189560#2189560PS: Im Gegensatz zu diesen neumodischen Varianten mit den Schleifen (wer braucht die schon, wenn doch Templates Turing-vollständig sind :p ), macht meine Version genau das gleiche, was der Threadersteller im Originalbeitrag gezeigt hat (also eine ewig lange if-Kaskade) und sollte somit auch ungefähr den gleichen Maschinencode produzieren. Es ist bloß ein bisschen kompakter aufgeschrieben.
-
Oh man, ich bekomme es nicht gebacken. Was ich bis jetzt versucht habe:
#include "std_lib_facilities.h" // vorgefertigte Datei für das Buch int main() // C++-Programme beginnen mit der Ausführung von main { char qst = 'n'; int high = 100; int low = 1; int middle = 50; cout << "Ist die Zahl kleiner oder gleich " << middle << " ? (j,n)\n"; while (cin >> qst) { if (qst == 'j') { high = middle; middle = middle/2; cout << "high= " << high << endl; cout << "middle= " << middle << endl; cout << "Ist die Zahl kleiner oder gleich " << middle << " ? (j,n)" << endl; } else if (qst == 'n') { low = middle; middle = ((high-low)/2)+low; cout << "high= " << high << endl; cout << "middle= " << middle << endl; cout << "low= " << low << endl; cout << "Ist die Zahl kleiner oder gleich " << middle << " ? (j,n)" << endl; } else cout << "Falsche Eingabe!\n"; } return 0; }Ich komme nicht dahinter wie die Schleife merken soll wann die richtige Zahl
erraten wurde. Die Ausgabe von high/middle/low hab ich nur gemacht mit ich ne Ahnung davon bekomme was in der Schleife gerade passiert.
-
Nach diesem Verfahren suchst du die Zahl auf einem bestimmten Intervall.
Wann ist die Suche beendet? Wenn das Intervall nur noch eine Zahl enthaelt - naemlich die gesuchte.
Danach solltest du deine Schleife ausrichten.
-
So, jetzt funktioniert zumindest schon mal alles bis das Ergebnis erreicht wurde.
Was ist nun aber wenn die Zahl 50 oder 25 oder 37 ist. Dann wäre die Sache ja nach 1,2 und drei Fragen zu ende. Ist die Aufgabe so gemeint das beim erscheinen der richtigen Zahl die Sache erledigt ist oder soll das Programm explizit herausfinden das die 37 nun das Ergebnis ist und keine Weiteren Fragen mehr stellen
#include "std_lib_facilities.h" // vorgefertigte Datei für das Buch int main() // C++-Programme beginnen mit der Ausführung von main { char qst = 'n'; int high = 100; int low = 1; int middle = 50; cout << "kleiner oder gleich " << middle << " ? (j,n)\n"; while (cin >> qst) { if (qst == 'j') { high = (high+low)/2; middle =((high-low)/2)+low; } else if (qst == 'n') { low = (low+high)/2; middle = ((high-low)/2)+low; } else cout << "Falsche Eingabe!\n"; cout << "kleiner oder gleich " << middle << " ? (j,n)" << endl; } return 0; }
-
Hyde++ schrieb:
...Wenn das Intervall nur noch eine Zahl enthaelt - naemlich die gesuchte.
Danach solltest du deine Schleife ausrichten.Versteh ich nicht, die Zahl wird solange aus high und low "gemittelt" bis es die Zahl ist. Bei 50 also schon nach der ersten Frage. Wenn ich aber nur ja, nein Fragen darf wie soll ich dann der Schleife mitteilen nicht mehr zu fragen, falls das überhaupt die Aufgabenstellung ist.
-
pauledd schrieb:
Versteh ich nicht, die Zahl wird solange aus high und low "gemittelt" bis es die Zahl ist. Bei 50 also schon nach der ersten Frage.
Ja und? Die Frage ist doch "kleiner oder gleich". Und nicht "kleiner (k), gleich (e) oder größer (g)". Das Programm kann da noch nicht wissen, dass die Zahl erraten ist.
pauledd schrieb:
Wenn ich aber nur ja, nein Fragen darf wie soll ich dann der Schleife mitteilen nicht mehr zu fragen, falls das überhaupt die Aufgabenstellung ist.
Dann ist deine Abbruchbedingung nicht richtig.
Lies dir die Antworten mal richtig durch:Hyde++ schrieb:
...Wenn das Intervall nur noch eine Zahl enthaelt - naemlich die gesuchte.
Danach solltest du deine Schleife ausrichten.DirkB schrieb:
5. ist obere und untere Grenze gleich? Nein, dann weiter bei 2.
Da steht nichts von: Solange du eine gültige Eingabe bekommst, .....