Gegebene Funktion in C++ umsetzen



  • Hallo,

    wir haben zur Aufgabe eine Funktion, welche sich als Bild hinter dem Link verbirgt, in C++ umzusetzen.

    http://v70.img-up.net/asf5mdl.png

    Zuerst sahs einfach aus -> Programm fertiggeschrieben -> Doch dann hat uns unsere Professorin ein Ergebnis zu einer Funktion mit Parametern gegeben.

    Von f(3, 6) soll das Endergebnis 33 lauten, bei uns kommt 64 raus.

    Unser Programm gibt nun etwas anderes aus, aber wir finden den Fehler einfach nicht und hoffen nun durch eure Hilfe dem Rätsel auf die Spur zu kommen. 🙂

    #include <iostream>
    #include <stdlib.h>
    
    using namespace std;
    
    int f(int x, int y, bool part)
    {
    	static int i = 0;
    
    	/* Bei Teilberechnung keine Erhoehung der Schritte */
    	if(!part)
    	{
    		i++;
    		cout << endl;
    	}
    
    	/* Einruecken */
    	for(int n = i*2; n > 0; n--)
    		cout << " ";
    
    	if(!part)
    		cout << "Schritt " << i << ": ";
    
    	/* Weitere Einrueckung bei Teilberechnungen ("Schritt x: " uebergehen ) */
    	if(part)
    		for(int j = 11; j > 0; j--)
    			cout << " ";
    
    	/* Weitere Einrueckung falls mehr als 10 Schritte gebraucht werden (Bei 100 auf Konsole eh kein Sinn) */
    	if(i > 10) 
    		cout << " ";
    
    	cout << "Aufruf von f(" << x << ", " << y << ")";
    
    	/* Bei Teilberechnung dies ausgeben */
    	if(part)
    		cout << " zur Teilberechnung ";
    
    	cout << endl;
    
    	/* Bedingungen */
    
    /********************************************
    Nur diese Zeilen sind von Bedeutung. 
    Der restliche obere Teil ist nur zur Ausgabe
    und nicht zur Berechnung.
    *********************************************/
    
    	if(y == 1)
    		return 2;
    	else if(x == 1 && y > 1)
    		return (y + 2);
    	else if(x > 1 && y > 1)
    	{
    		int yDec = y - 1;
    		int xDec = x - 1;
    		int fTmp = f(x, yDec, true);
    		cout << "ftmp: " << fTmp << "\n";
    		return f(xDec, fTmp, false);
    	}
    	else
    	{
    		cout << endl << "Fehler: Werte kleiner 1" << endl;
    		return -1;
    	}
    }
    
    int main(int argc, char *argv[])
    {
    	if(argc < 3)
    	{
    		cout << "Zu wenig Argumente uebergeben" << endl;
    		cout << "Aufruf: " << argv[0] << " x-Wert y-Wert" << endl;
    		return 0;
    	}
    
    	int xArg = atoi(argv[1]);
    	int yArg = atoi(argv[2]);
    
    	int erg = f(xArg, yArg, false);
    
    	if(erg > 0)
    		cout << endl << "Ergebnis: " << erg << endl;
    
    	return 0;
    }
    


  • Ich glaub du musst die Bedingungen nochmal einklammern, dh.

    if((x == 1) && (y > 1))



  • Ich fürchte der Fehler liegt darin, dass f(3,6) einfach mal tatsächlich 64 ist.



  • Das denken wir nämlich auch, aber wollten auf Nummer sicher gehen und Fehler in der Programmierung ausschließen.

    Danke schonmal.

    Vielleicht antwortet ja noch wer, aber ich glaub eine andere Antwort als
    > "Ist so richtig"
    gibt es nicht mehr.



  • Sogar in der Aufgabenstellung fehlt schon eine Klammer-zu. Das kann man ja gut als Argument nutzen 🙂

    /EDIT

    Ich habe grade mal eine BruteForce Suche gestartet. Für alle Werte von x und y im Bereich -50<x,y<99 {> geht natürlich nicht} habe ich die folgenden Eingaben gefunden, bei denen das Ergebnis 33 ist. Als Sicherheit habe ich während der Laufzeit zusätzlich y auf y<1000 eingeschränkt..

    f(1,31)=33
    f(2,30)=33
    f(3,28)=33
    f(4,24)=33
    f(5,16)=33

    Von einem "falsch Abgelesen" kann anscheinend nicht die Rede sein 😃



  • Sieht wie die Ackermann-Funktion aus.

    Ich habe grade mal eine BruteForce Suche gestartet. Für alle Werte von x und y im Bereich -50>x,y>99

    Werte fuer x < -50 sind voellig sinnlos. Dein ganzer Test scheint etwas unglaubwuerdig, wenn du alle Werte mit y < 1000 getestet hast. Fuer f(2,30) kommt bei mir beispielsweise 60 heraus.



  • Ja das mit Werten im negativen war sinnlos..

    Aber f(2,30) bleibt bei mir 33 auch beim durchsteppen..

    Die Einschränkung mit y<1000 war wichtig weil bei x=7 der y-Wert ans Ende des Datentypen gerannt ist.

    Werte habe ich bis x=99 und y=99 getestet.



  • x=99 und y=99

    Da es sich um eine Funktion aehnlich der Ackermann-Funktion handelt, glaube ich nicht, dass eine direkte Umsetzung innerhalb eines Tages die noetigen Rechenschritte abgearbeitet hat. Vielleicht ist deine Implementierung fehlerhaft. Meine Implementierung in Haskell sieht wie folgt aus:

    ack _ 1 = 2
    ack 1 n = n + 2
    ack k n = ack (k-1) (ack k (n-1))
    


  • Hat sich erledigt. War richtig, meine Professorin hatte sich verrechnet, kann ja mal vorkommen.

    Dankeschön



  • Mr. Edit schrieb:

    Ja das mit Werten im negativen war sinnlos..

    Aber f(2,30) bleibt bei mir 33 auch beim durchsteppen..

    Die Einschränkung mit y<1000 war wichtig weil bei x=7 der y-Wert ans Ende des Datentypen gerannt ist.

    Werte habe ich bis x=99 und y=99 getestet.

    Gut, dann

    • Ohne negative Werte
    • y<1000
    • Bereich von 1 bis 99.

    Ich krieg nur ack(1,31)=33 raus, sonsts nichts.

    Eines meiner ersten Haskellprogramme:

    ack :: Integral a => a -> a -> Maybe a
    ack _ 1 = Just 2
    ack 1 n = Just (n+2)
    ack k n
      | n > 1000 = Nothing
      | otherwise = case ack k (n-1) of
          Nothing -> Nothing
          Just n' -> ack (k-1) n'
    
    test :: Eq c => (a -> a -> c) -> c -> [a] -> [(a, a)]
    test f n r = [(x,y)|x<-r, y<-r, f x y==n]
    
    main = do
      let (n, r) = (33, [1..99])
      mapM_ (\x->putStrLn ("ack"++(show x)++"="++(show n))) $ test ack (Just n) r
    

Anmelden zum Antworten