Zahlenratespiel von Stroustrup
-
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, .....
-
DirkB schrieb:
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, .....
Dann ist bei mir leider wieder alles falsch. Die obere/untere Grenze wird bei mir nie gleich.
Ich fang nochmal von vorne an aber ich zweifel langsam was mein Abstraktionsvermögen angeht da die Aufgabe nun eigentlich Kindergarten ist und ich nach 3 Tagen immer noch nicht dahinter gestiegen bin.
-
Dann ist bei mir leider wieder alles falsch. Die obere/untere Grenze wird bei mir nie gleich.
Korrekt. Dazu nochmal genau ueberlegen, welche Ja/Nein-Fragen du stellst:
"Ist die Zahl kleiner oder gleich x?" Wenn du hier mit Nein anwortest, setzt du das untere Limit auf x.
Das bedeutet, die kleinste Zahl die deine zahl annehmen koennte, waere x.
Aber die Frage war kleiner ODER GLEICH. Wenn du hier mit nein antwortest, sagst du also, dass deine Zahl groesser als x ist. Du musst hier also low = middle + 1 setzen.Edit:
Lass dich nicht entmutigen! Um Programmieren zu lernen braucht man nun mal Zeit. Wenn C++ deine erste Sprache ist, wird es umso schwieriger. Ich habe auch mit c++ angefangen und habe Monate gebraucht, um ueberhaupt ein einfaches Programm zu schreiben, dass ohne Fehler kompiliert.
An der Aufgabe, die Binaerdarstellung einer Zahl zu erzeugen, bin ich voellig gescheitert.Wenn dich das interessiert, bleib dran. Am besten ist es, wenn du irgendwann mal ein echtes Projekt hast, dass du umsetzen kannst. Ich bin Elektrotechniker, hatte nur absolut rudimentaere Programmierkurse in Java und schreibe momentan meine Bachelorarbeit in c++. Das ist zwar kein Grossprojekt, aber es ist trotzdem ein schoenes Gefuehl, mal die Sachen, die man ueber die Jahre so liesst, wirklich anzuwenden. Hier im Forum mitlesen hilft auch schon einiges, da man manche Sachen, die man besser vermeiden sollte, die man besser nutzen sollte usw. unbewusst aufnimmt.
Zum abstrakten Denken: ueben, ueben, ueben. Das kommt leider nicht von irgendwo her, ich fand es als Programmierneuling eine sehr eigenartige Denkweise.
Heute helfe ich ab und zu meiner Schwester in Programmierhausaufgaben der Uni (meistens Python) und bin erstaunt, welche (vermeintlich einfachste) Konzepte ihr nicht klar sind. Das ist natuerlich nicht ihr Fehler, man neigt nur dazu, viel zu lernen und zu verinnerlichen, dass man vergisst, welche Probleme Schwierigkeiten bereiten.
Also: Kopf hoch!
-
Hyde++ schrieb:
Lass dich nicht entmutigen!
Nein, und danke

Hyde++ schrieb:
Zum abstrakten Denken: ueben, ueben, ueben.
Mach ich, zum Glück kann ich mir Zeit lassen und kann das einfach mal beiseite legen und dann nochmal neu rann. Aber bis jetzt hat das noch nicht "klick" gemacht.
Hyde++ schrieb:
Du musst hier also low = middle + 1 setzen.
Ok, das verstehe ich glaube ich. Weil ja im "ja" Fall 1-50 schon abgedekt
ist muss es dann bei "nein" 51-100 sein.
-
Ok ich glaube jetzt klappts. Das "+1" hat geholfen. Jetzt werden Unter/Obergrenze auch mal gleich.
#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; int runde =0; cout << "kleiner oder gleich " << middle << " ? (j,n)\n"; while (cin >> qst) { runde = runde+1; cout << "Frage= " << runde << endl; if (qst == 'j') { high = (high+low)/2; middle =((high-low)/2)+low; } else if (qst == 'n') { low = ((low+high)/2)+1; middle = ((high-low)/2)+low; } else cout << "Falsche Eingabe!\n"; cout << "high= " << high << endl; cout << "middle= " << middle << endl; cout << "low= " << low << endl; cout << "Runde= " << runde << endl; if (low != high) cout << "kleiner oder gleich " << middle << " ? (j,n)" << endl; else cout << "Die Zahl ist " << middle << endl; } return 0; }
-
Ich weiß nicht *kopfkratz* ist
cin >> qstwirklich eine gute Abbruchbedingung?
Warum überhaupt eine kopfgesteuertewhile(...){}-Schleife wenn die Werte für eine sinnvolle Abbruchbedingung erst nach Ausführung des Schleifenkörpers feststehen?
do{}while(...)
-
Swordfish schrieb:
Ich weiß nicht *kopfkratz* ist
cin >> qstwirklich eine gute Schleifenbedingung?Weiß ich leider auch nicht aber die Schleife wurde in dem Buch bis zu der Übung schon öfters so zur Demonstration verwendet, oder soll das ein "Wink" in Richtung Optimierung sein?

-
pauledd schrieb:
Swordfish schrieb:
Ich weiß nicht *kopfkratz* ist
cin >> qstwirklich eine gute Schleifenbedingung?Weiß ich leider auch nicht aber die Schleife wurde in dem Buch bis zu der Übung schon öfters so zur Demonstration verwendet,
Du weißt also garnicht, wann
cin >> qstzufalsewird?pauledd schrieb:
oder soll das ein "Wink" in Richtung Optimierung sein?

Nein. Ich will daß du über eine Abbruchbedingung nachdenkst, die
falsewird, wenn du die gedachte Zahl gefunden hast.