Hilfe, Raetsel!



  • Hallo Community,

    ich hab vor kurzem mit einem Informatik-studium
    begonnen. wir lernen die C-Sprache und haben auch gleich
    einige Aufgaben bekommen die ich größtenteils auch bewältigen konnte.
    Mit einer komme ich jedoch gar nicht zurecht und zwar soll ich ein Raetsel erstellen...aber seht selbst.
    Habt ihr vielleicht irgendeinen schimmer was ich da machen könnte?

    Aufgabe 2 Raetsel
    Gegeben ist die folgende Ausgabe:
    a = 1, b = 1
    a = 1, b = 2
    a = 2, b = 2
    a = 1, b = 2
    a = 3, b = 2
    a = 3, b = 3
    a = 4, b = 3
    a = 3, b = 2
    a = 1, b = 2
    a = 1, b = 1
    Schreiben Sie ein C-Programm raetsel.c, das die obige Ausgabe erzeugt. Sie duerfen jedoch
    in Ihrem Programm nur
     4 mal den Wert der Variablen a aendern,
     3 mal den Wert der Variablen b aendern und
     zur Ausgabe die Anweisung printf("a = %i, b = %i\n", a,b); verwenden.

    Hinweis: Verwenden Sie in Ihrem Programm eine geeignete Blockstruktur, innerhalb derer
    die Variablen vereinbart werden.



  • Da ja offensichtlich a 6 mal und b 4 mal geändert wird, muss es eine Möglichkeit geben eine Änderung der Ausgabe herbeizuführen ohne die Variablen so häufig zu ändern. Danach musst du suchen. (Ich weiß die Lösung allerdings auch noch nicht)



  • Es könnte ja auch ein rekursiver Aufruf sein.
    Je nach dem Verhältnis von a zu b, wird rekursiv mit geänderten Paramtern aufgerufen (oder beendet).
    Davor, dahinter oder zwischendurch werden die Ausgaben gemacht.



  • Was auffällt ist, dass a nur 4 verschiedene Zustände und b nur 3 verschiedene Zustände hat. Danach wäre es einfach möglich. Das Problem entsteht erst durch die Reihenfolge.

    Mein erster Gedanke war alle Einsen bei a dann alle zweien bei a usw anzeigen zu lassen. Es ist bestimmt möglich z.B erst alles mit

    a = 1, b = 1
    a = 1, b = 1
    a = 1, b = 1
    a = 1, b = 1
    a = 1, b = 1
    a = 1, b = 1
    a = 1, b = 1
    a = 1, b = 1
    a = 1, b = 1
    a = 1, b = 1

    zu schreiben, und dann die Position in der die Console schreibt wieder hoch oder runter zu setzen und die stellen mit den entsprechenden Zahlenwerten zu überschreiben. z.B erst alle Einsen dann alle zweien usw.

    Das Problem was ich dann noch sehe ist die Koppelung der Ausgabe von a und b beim printf. Man müsste irgendwie geschickt hin und herspringen mit der Position der Ausgabe und nur Ersetzungen vornehmen wenn es nötig ist.

    Wenn man mit der Eins anfängt sind bei a nur 3 weitere Ziffern und bei b nur zwei weitere Ziffern vorhanden. Also wird eine Ersetzung jeweils für was anderes gebraucht, und das muss der entscheidende Trick sein. (Falls der Ansatz stimmt)

    Edit: Ja das mit der Rekursion vom Beitrag über mir könnte stimmen. Dann musst du nur Fallunterscheidungen einbauen wann gezeichnet werden soll. Das Problem bleibt aber die Koppelung der Ausgabe von a und b.



  • Hallo,

    sehr interessante Aufgabe, um mit Blöcken "zu spielen", der Hinweis zur Aufgabe deutet den Lösungsweg an, ich hätte eine vollständige Lösung zu bieten, aber vielleicht kommst du selber darauf, wenn du folgenden Teil meiner Lösung siehst (und dir die Ausgabe dazu ansiehst):

    #include <stdio.h>
    
    int main()
    {
    
            int a = 1;
            int b = 1;
            printf("a = %i, b = %i\n", a,b);
    
            {
                    int b = 2;
                    printf("a = %i, b = %i\n", a,b);
                    {    
                            int a = 2;
                            printf("a = %i, b = %i\n", a,b);
                    }
            }
    
            printf("a = %i, b = %i\n", a,b); 
            return 0;
    }
    

    MfG,

    Probe-Nutzer


  • Mod

    Uhh, das ist schwierig. Mir fällt keine portable Lösung ein, aber ich vermute, es soll auf folgendes hinaus laufen:
    Wir gucken die Wertepaare genau an. Es gibt nur folgende Paare:

    a b
    ---
    1 1
    1 2
    2 2
    3 2
    3 3
    4 3
    

    An sich kommen wir also mit den drei Änderungen für b und vier Änderungen für a aus. Dann passt aber die Reihenfolge nicht. Hier wäre jetzt wohl so etwas wie sprintf angesagt, mit dem wir die Ausgabe irgendwo zwischenspeichern können. Das ist aber laut Aufgabenstellung verboten. Daher behelfe ich mich damit, dass das Programm wohl in einer Konsole laufen soll und diese sich auch die Ausgabe merkt. Die Ansteuerung der Konsole ist dann aber plattformabhängig. Folgendes funktioniert in typischen Linuxterminals, die Cursorpositionierung habe ich abstrahiert, damit man sie anpassen kann:

    #include <stdio.h>
    
    #define ESC 27
    
    void line_up(unsigned how_many)
    {
      printf("%c[%uA", ESC, how_many);  // Steuercode für VT100-Terminal
    }
    
    void line_down(unsigned how_many)
    {
      printf("%c[%uB", ESC, how_many);  // Steuercode für VT100-Terminal
    }
    
    int main()
    {
      int a=1, b=1; // Erste Änderung von a und erste Änderung von b
      int i;
    
      // Zehn Zeilen füllen, später werden alle außer der ersten und der letzten überschrieben
      for (i = 0; i < 10; ++i)
       printf("a = %i, b = %i\n", a,b);
    
      b = 2;  // Zweite Änderung von b
    
      line_up(9);  // Zur zweiten Zeile
      printf("a = %i, b = %i\n", a,b);
      line_down(1); // Zur vierten Zeile
      printf("a = %i, b = %i\n", a,b);
      line_down(4); // Zur neunten Zeile
      printf("a = %i, b = %i\n", a,b);
    
      a = 2; // Zweite Änderung von a
    
      line_up(7); // Zur dritten Zeile
      printf("a = %i, b = %i\n", a,b);
    
      a = 3; // Dritte Änderung von a
    
      line_down(1); // Zur fünften Zeile
      printf("a = %i, b = %i\n", a,b);
      line_down(2); // Zur achten Zeile
      printf("a = %i, b = %i\n", a,b);
    
      b = 3; // Dritte Änderung von b
    
      line_up(3); // Zur sechsten Zeile
      printf("a = %i, b = %i\n", a,b);
    
      a= 4; // Vierte Änderung von a
      // Zeile sieben passt bereits
      printf("a = %i, b = %i\n", a,b);
    
      line_down(3); // Abschluss in der elften Zeile, damit es besser aussieht
    
      return 0;
    }
    


  • Achtung Spoiler:

    int main() 
    { 
    
    	int a = 1; 
    	int b = 1; 
    	printf("a = %i, b = %i\n", a,b); 
    	{ 
    		int b = 2; 
    		printf("a = %i, b = %i\n", a,b); 
    		{     
    			int a = 2; 
    			printf("a = %i, b = %i\n", a,b); 
    		} 
    		printf("a = %i, b = %i\n", a,b); 
    		{
    			int a = 3;
    			printf("a = %i, b = %i\n", a,b); 
    
    			{
    				int b = 3;
    				printf("a = %i, b = %i\n", a,b); 
    
    				{
    					int a = 4;
    					printf("a = %i, b = %i\n", a,b); 
    				}
    			}
    			printf("a = %i, b = %i\n", a,b);
    		}
    		printf("a = %i, b = %i\n", a,b); 
    	} 
    	printf("a = %i, b = %i\n", a,b); 
    }
    

  • Mod

    Oh, wahrscheinlich ist das tatsächlich so gemeint, ist jedenfalls viel schöner. Dann ist die Aufgabenstellung aber doof, da man nicht wirklich die Variablen ändert, sondern neue Symbole definiert, die die Variablen aus den äußeren Blöcken verdecken.



  • Das ist die Idee die ich hatte bevor ich den Ansatz von "Probe-Nutzer" gelesen habe:

    #include <stdio.h>
    #include <windows.h>
    
    void gotoxy( int x, int y )
    {
       COORD p = { x, y };
       SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), p );
    }
    
    void loesung()
    {
    
    	int a = 1; 
    	int b = 1; 
    	printf("a = %i, b = %i\n", a,b); 
    	gotoxy(0,9);
    	printf("a = %i, b = %i\n", a,b); 
    
    	b = 2; 
    	gotoxy(0,1);
    	printf("a = %i, b = %i\n", a,b); 
    	gotoxy(0,3);
    	printf("a = %i, b = %i\n", a,b); 
    	gotoxy(0,8);
    	printf("a = %i, b = %i\n", a,b); 
    	a = 2; 
    	gotoxy(0,2);
    	printf("a = %i, b = %i\n", a,b); 
    
    	a = 3;
    	gotoxy(0,4);
    	printf("a = %i, b = %i\n", a,b); 
    	gotoxy(0,7);
    	printf("a = %i, b = %i\n", a,b); 
    
    	b = 3;
    
    	gotoxy(0,5);
    	printf("a = %i, b = %i\n", a,b); 
    
    	a=4;
    	gotoxy(0,6);
    	printf("a = %i, b = %i\n", a,b); 
    
    }
    
    int main() 
    { 
    	loesung();	
    }
    


  • vielen Dank für eure Bemühungen!
    Ich weiss jetzt worauf Probenutzer hinauswill.
    Und wegen dem "mit den Blöcken spielen" erinner ich mich jetzt, dass wir noch
    am ende der letzten vorlesung darüber gesprochen haben ;).
    wenn man erstmal dahinter gekommen ist ist es sogar ziemlich einfach, man darf nur nicht zu kompliziert denken :D.
    Danke!


Anmelden zum Antworten