Zahlenraten



  • wenn ich "klug" wählen möchte, dann habe ich dass Problem, das ich für jede "Ja" ,"Nein" Möglichkeit 7 if verzweigungen einbauen muss, und wenn ich es mit einer Schleife versuche, dann muss ich wissen, was ich mit meiner Variablen machen muss um immer auf den Optimalen Mittelwert zu kommen.



  • Nein, warum das denn.
    Ich denke mir ne Zahl und du/der Rechner rätst/rät 50. Dann sage ich dir, dass meine Zahl größer ist.
    Welche Zahl solltest du dann nehmen?



  • Ich würde aber gerne direkt eine Rechnung haben, die Zahl immer in die nächste gebrauchte Zahl(je nach ja oder nein) umwandelt. Gibt es diese nicht?
    (PS: die nächste Zahl ist natürlich 75, so viel ist mir schon klar)


  • Mod

    Gringham schrieb:

    Ich würde aber gerne direkt eine Rechnung haben, die Zahl immer in die nächste gebrauchte Zahl(je nach ja oder nein) umwandelt. Gibt es diese nicht?
    (PS: die nächste Zahl ist natürlich 75, so viel ist mir schon klar)

    Und wie hast du die 75 ausgerechnet? Was hindert dich daran, diese Rechnung mit dem Computer zu machen?



  • Mit was musst du denn die 50 multiplizieren, damit du auf 75 kommst?



  • Wenn kleiner -> Zahl = Zahl / 2
    wenn größer -> Zahl = Zahl + Zahl / 2 // -- neee, das geht so nicht ....

    aber ...

    was machst Du, wenn ich mir 50 gemerkt habe und auf die Frage:
    'Ist Deine Zahl kleiner als 50?'
    die (dann richtige) Antwort 'Nein' gebe?



  • @Belli: Ich denke, diesen Fall werde ich nach der Lösung des Hauptproblems bedenken , ich denke ich werde es mit "<=" und ">=" rechnen

    @alle anderen, auf die 75 kommt man , wenn man die ,Mitte auszählt, also
    Zahl+(Zahl/2)

    aber alle Berechnungen für 75 verlieren sich bei der zweiten Runde, das ist mein Problem

    wenn man für Ja = Zahl/2 +Zahl%2 nimmt geht das zwar wenn man sich 1 denkt, aber wenn einmal ein Nein dabei ist geht es schon nicht mehr, dies ist mein Problem



  • #include <iostream>
    
    int main()
    {
    	short lobo, upbo, midd;
    	char answ;
    
    	std::cout << "Eingabe der Grenzen: ";
    	std::cin >> lobo >> upbo;
    
    	for(;;)
    	{
    		midd=(lobo+upbo) >> 1;
    
    		std::cout << "Ist " << midd << " die Zahl? (J/N) ";
    		std::cin >> answ;
    
    		if(answ=='J') break;
    
    		std::cout << "Liegt die Zahl unterhalb von " << midd << "? (J/N) ";
    		std::cin >> answ;
    
    		if(answ=='J') upbo=midd;
    		else lobo=midd;
    	}
    
    	return 0;
    
    }
    

    Würd ich jetzt mal so versuchen.


  • Mod

    Hier noch ein Klassiker in einer Neuauflage (wenn irgendjemand mein Original noch finden kann, dann würde mich ein Link dahin interessieren):

    #include <iostream>
    
    using namespace std;
    
    template <unsigned lower, unsigned upper> struct zahlenraten
    {
      void operator()()
      {
        const unsigned middle = (lower + upper) / 2;
        cout << "Liegt die Zahl oberhalb von " << middle << "(J/N)? ";
        char yesorno;
        cin >> yesorno;
        if (yesorno == 'n' or yesorno == 'N')
          zahlenraten<lower, middle>()();
        else
          zahlenraten<middle+1, upper>()();
      }
    };
    
    template<> template <unsigned number> struct zahlenraten<number, number>
    {
       void operator()()
      {
        cout << "Die Zahl lautet " << number << ".\n";
      } 
    };
    
    int main()
    {
      const unsigned lower = 0, upper = 10000;
      cout << "Denke dir eine Zahl zwischen " << lower << " und " << upper << ".\n";
      zahlenraten<lower, upper>()();
    }
    

    Compilieren für 0 bis 10000 braucht bei mir gut 4 Minuten (gcc 4.6, die O3-Optimierung macht das richtig langsam), ca. 1 GB RAM und das Programm ist hinterher gut 1 MB groß.



  • Ich bin mir relativ sicher, dass eure beiden Quelltexte Funktioneniern, aber leider verstehe ich sie nicht ganz, vermutlich, da ich bestimmet Themen noch nicht hatte sry...



  • Ich suche den Mittelwert zwischen den Grenzen, frage ob er die Lösung ist oder die Zahl darunter liegt, je nachdem lege ich die obere oder untere Grenze auf den Mittelwert und wiederhole das ganze.

    Zu beachten ist dass zahl >> 1 äquivalent einer Division durch 2 ist, hier werden alle bits nach rechts verschoben.


  • Mod

    Gringham schrieb:

    Ich bin mir relativ sicher, dass eure beiden Quelltexte Funktioneniern, aber leider verstehe ich sie nicht ganz, vermutlich, da ich bestimmet Themen noch nicht hatte sry...

    Meines ist auch eher eine Scherzlösung für Liebhaber. Aber was verstehst du denn an Thuruks Lösung nicht? Das sind doch nur eine Schleife, Vergleiche und Ausgaben. Einfacher wird dein Problem nicht zu lösen sein, es sei denn du rollst die Schleife von Hand ab (das macht mein Programm übrigens automatisch). Irritiert dich das for (;;) ? Das ist einfach eine for-Schleife mit leerem Kopf, die folglich endlos läuft*. finde ich selber nicht sehr elegant (das kann Thuruk auch schöner), aber mit dieser Info sollte klar sein, was passiert, oder?

    Oh, und er teilt durch 2, indem er um 1 Bit nach rechts verschiebt, anstatt /2 zu schreiben, weil das vor 35 Jahren mal schneller war und die Kids das heute immer noch cool finden 🕶 .

    *: Alter Programmiererscherz:

    #define ever (;;)
    
    // ...
    
    for ever
    {
      // ...
    }
    


  • Gringham schrieb:

    @Belli: Ich denke, diesen Fall werde ich nach der Lösung des Hauptproblems bedenken , ich denke ich werde es mit "<=" und ">=" rechnen

    @alle anderen, auf die 75 kommt man , wenn man die ,Mitte auszählt, also
    Zahl+(Zahl/2)

    aber alle Berechnungen für 75 verlieren sich bei der zweiten Runde, das ist mein Problem

    wenn man für Ja = Zahl/2 +Zahl%2 nimmt geht das zwar wenn man sich 1 denkt, aber wenn einmal ein Nein dabei ist geht es schon nicht mehr, dies ist mein Problem

    Es muss nichts zur Zahl addiert bzw. subtrahiert werden, sondern der Wert für Zahl verwendet werden, der in der Mitte zwischen den beiden Grenzen liegt, die du durch die Ja/Nein Fragen ermittelt hast.

    Min | Max | Mitte | Antwort
    0   | 100 |  50   | größer
    50  | 100 |  75   | kleiner
    50  | 75  |  62   | kleiner
    50  | 62  | ...
    


  • Ich kenne das Beispiel aus C++ von A bis Z

    Also : http://www.c-plusplus.net/forum/272350



  • Das Problem ist wohl, dass er mit einer einzigen Variablen (Zahl) nicht auskommt, weil mal die Unter- mal die Obergrenze verändert werden muss.
    Ich habe das nicht sofort bemerkt und deshalb versucht, ganz streng wie in der Frage formuliert, ausschließlich die beiden Fragezeichen sinnvoll zu ersetzen - aber vermutlich gibt es da keine (vernünftige) Lösung für.



  • Belli schrieb:

    Das Problem ist wohl, dass er mit einer einzigen Variablen (Zahl) nicht auskommt, weil mal die Unter- mal die Obergrenze verändert werden muss.
    Ich habe das nicht sofort bemerkt und deshalb versucht, ganz streng wie in der Frage formuliert, ausschließlich die beiden Fragezeichen sinnvoll zu ersetzen - aber vermutlich gibt es da keine (vernünftige) Lösung für.

    Man kann durchaus 2 short-Zahlen in einer int-Variablen speichern. 🙂



  • Belli schrieb:

    Das Problem ist wohl, dass er mit einer einzigen Variablen (Zahl) nicht auskommt, weil mal die Unter- mal die Obergrenze verändert werden muss.

    Er hat ja auch zwei Variabeln: Zahl und i, sowie zwei Konstanten: 1 und 100.



  • Ich habe nun Verstanden, worauf ihr hinauswolltet, danke,
    für all die große Hilfe
    (Ich schätze ich melde mich bald auch mal hier an)

    Gruß Gringham


Anmelden zum Antworten