Alle geraden Fibonacci Zahlen summieren



  • Wir haben die Aufgabe, alle geraden Fibonacci Zahlen zu summieren, die nicht größer als 4000000 sind und den Wert dann auszugeben.

    Ich habe folgendes versucht:

    #include <iostream>
    #include <windows.h>
    using namespace std;
    #define MAX 4000000
    int main()
    {
    	long help = 0;
        long s = 1, k = 1, p = 0;
        //cout << s << " " << k << " ";
        for(;;)
        {
            p = s + k;
            //cout << p << " ";
            k = s + p;
            //cout << k << " ";
            s = p + k;
            //cout << s << " ";
    		if (p > MAX || k > MAX || s > MAX)
    			break;
    
    		if(p % 2 == 0)
    		help += p;
    		if(k % 2 == 0)
    		help += k;		
    		if(s % 2 == 0)
    		help += s;
    		cout << help << "   ";
    		Sleep(12);
        }
    	cout << help;
        cin.get();
    }
    

    Nun bekomme ich nicht den richtigen Wert heraus. Kann mir jemand helfen?

    Danke.



  • Hast du dich denn selbst bemüht das Problem zu lösen? Klingt nicht danach. Wo liegt denn konkret das Problem? Schon einmal einen Debugger benutzt?



  • Janjan schrieb:

    Hast du dich denn selbst bemüht das Problem zu lösen? Klingt nicht danach. Wo liegt denn konkret das Problem? Schon einmal einen Debugger benutzt?

    Ich häng 4 Stunden dran. Ja, ich hab aber schon so einen Dickschädel, dass ich nicht mehr denken kann..

    EDIT: Ok, die Bedingung habe ich korrigiert. Aber der Rest bleibt mir schleierhaft.



  • Du würdest bei dem Code schon viel mehr durchblicken, wenn du statt s, k und p sinnvolle Bezeichner nehmen und deinen Code in Funktionen aufteilen würdest. Konsistente Einrückung wäre auch eine Idee.



  • Warum hast du keine separate Funktion für Fibonacci? Dann ist der Code viel einfacher...

    ~Stimmt der Wert, den ich hier bekomme? Ich mag solche Aufgaben 🤡~ EDIT: NVM 😃



  • /rant/ schrieb:

    ...

    Seit wann fängt die Fibonaccizahlenfolge mit "1, 2, 4, 7, 12, ..." an? 😃
    Und noch den in den Raum geworfen, ich würde statt sowas

    #define MAX 400000
    

    lieber eine konstante Variable in C++ nutzen

    const int MAX = 400000
    

    und diese dann Global nutzen. Weiß ja nicht wie das andere sehen 🙂



  • FreakY<3Cpp schrieb:

    /rant/ schrieb:

    ...

    Seit wann fängt die Fibonaccizahlenfolge "1, 2, 4, 7, 12, ..." an? 😃

    Nun, da ist wohl etwas zu viel Rekursion drin. Das passiert, wenn man in wenigen Minuten weg muss und trotzdem noch eine kleine Aufgabe schnell schnell lösen will^^



  • Nexus schrieb:

    Du würdest bei dem Code schon viel mehr durchblicken, wenn du statt s, k und p sinnvolle Bezeichner nehmen und deinen Code in Funktionen aufteilen würdest. Konsistente Einrückung wäre auch eine Idee.

    Stimmt, aber wie schaut denn jetzt die Lösung aus?



  • Wie wärs wenn du selbst darauf kommst? Berücksichtige mal die Tipps, die dir gegeben wurden und dann zeig nochmal was du hast. Ordentliche Variablennamen setzen, am besten eine Fibonaccifunktion (nicht unbedingt rekursiv, sondern besser iterativ, damit man weiß was abgeht) und richtige Klammersetzung + Einrückung und dann können wir mal weiterschauen.


  • Mod

    skullyan schrieb:

    Nexus schrieb:

    Du würdest bei dem Code schon viel mehr durchblicken, wenn du statt s, k und p sinnvolle Bezeichner nehmen und deinen Code in Funktionen aufteilen würdest. Konsistente Einrückung wäre auch eine Idee.

    Stimmt, aber wie schaut denn jetzt die Lösung aus?

    Versuch doch lieber noch mal von vorne anzufangen und dabei das was Nexus gesagt hat umzusetzen.



  • SeppJ schrieb:

    skullyan schrieb:

    Nexus schrieb:

    Du würdest bei dem Code schon viel mehr durchblicken, wenn du statt s, k und p sinnvolle Bezeichner nehmen und deinen Code in Funktionen aufteilen würdest. Konsistente Einrückung wäre auch eine Idee.

    Stimmt, aber wie schaut denn jetzt die Lösung aus?

    Versuch doch lieber noch mal von vorne anzufangen und dabei das was Nexus gesagt hat umzusetzen.

    Das bringt mir jetzt herzlich wenig, aber naja... Dann werde ich es wohl aufgeben müssen.



  • Oh mein Gott, wenn ich so ein Bullshit höre, krieg ich echt Magenkrämpfe. Erwartest du echt das du hier die Lösung hingespuckt bekommst und dann sagen kannst "Ich habe es geschafft"? Du machst das grad damit du es lernen kannst. Aber gut, bleib dumm.



  • Ich verstehe ehrlich gesagt dein Problem gar nicht, skullyan.

    Du fängst erstmal damit an eine Schleife zu schreiben, die Fibonnaci-Zahlen generiert, meinetwegen zu anfang noch eine Endlosschleife.
    Dann definierst du für diese Schleife eine passende Abbruchbedinung, welche in diesem Fall einfach wäre, dass die aktuelle Fibonacci-Zahl kleiner als 4000000 sein muss.
    Der nächste Schritt ist herauszufinden, ob die aktuelle Zahl gerade oder ungerade ist, dazu bietet sich der modulo-Operator an.
    Und schließlich brauchst du nur noch eine Summe, aller geraden Fibonnaci-Zahlen zu bilden.

    Bei welchem dieser Schritte hast du ein Problem?

    ...



  • Hallo,

    am besten du machst schonmal aus deiner for-Schleife eine while-Schleife.
    Dann kann auch der Abschnitt weg:

    if (p > MAX || k > MAX || s > MAX) 
                break;
    

    und schau dir noch einmal diesen Abschnitt an:

    if(p % 2 == 0) 
            help += p; 
            if(k % 2 == 0) 
            help += k;        
            if(s % 2 == 0) 
            help += s;
    


  • skullyan schrieb:

    Wir haben die Aufgabe, alle geraden Fibonacci Zahlen zu summieren, die nicht größer als 4000000 sind und den Wert dann auszugeben.

    ja das schreit doch geradezu nach einer abgefahrenen Lösung:

    #include <algorithm> // find_if
    #include <iostream>
    #include <numeric> // accumulate
    #include <boost/iterator/iterator_adaptor.hpp>
    #include <boost/iterator/filter_iterator.hpp> // make_filter_iterator
    #include <boost/lambda/lambda.hpp>
    
    template< typename T >
    class Fibonacci : public boost::iterator_adaptor< Fibonacci< T >, T, const T, boost::forward_traversal_tag, T >
    {
    public:
        explicit Fibonacci( const T& x = T(0), const T& prev = T(1) )
            : iterator_adaptor_( x ), m_prev( prev ) {}
        void increment()
        {
            const T fibo = base() + m_prev;
            m_prev = base();
            base_reference() = fibo;
        }
        T dereference() const { return base(); }
        static Fibonacci infinite() { return Fibonacci( T(-1), T(0) ); }
    private:
        T m_prev;
    };
    
    int main()
    {
        using namespace std;
        using namespace boost::lambda;
        const int N = 4000000;
        const Fibonacci< int > last = find_if( Fibonacci< int >(), Fibonacci< int >::infinite(), _1 > N );
        cout << "Die Summer aller geraden Fibonacci-Zahlen unter " << N << " ist " 
            << accumulate(  boost::make_filter_iterator( _1 % 2 == 0, Fibonacci< int >(), last ), 
                            boost::make_filter_iterator( _1 % 2 == 0, last,               last ), 0 ) << endl;
        return 0;
    }
    

    Gruß
    Werner



  • Werner Salomon mit seinen ownage Lösungen 😃



  • _) schrieb:

    Hallo,

    am besten du machst schonmal aus deiner for-Schleife eine while-Schleife.
    Dann kann auch der Abschnitt weg:

    if (p > MAX || k > MAX || s > MAX) 
                break;
    

    und schau dir noch einmal diesen Abschnitt an:

    if(p % 2 == 0) 
            help += p; 
            if(k % 2 == 0) 
            help += k;        
            if(s % 2 == 0) 
            help += s;
    

    Was soll daran falsch sein?

    Anscheinend reicht das hier:

    help += p;
    


  • skullyan schrieb:

    Nexus schrieb:

    Du würdest bei dem Code schon viel mehr durchblicken, wenn du statt s, k und p sinnvolle Bezeichner nehmen und deinen Code in Funktionen aufteilen würdest. Konsistente Einrückung wäre auch eine Idee.

    Stimmt, aber wie schaut denn jetzt die Lösung aus?

    Ziemlich schlechte Antwort.

    skullyan schrieb:

    Das bringt mir jetzt herzlich wenig, aber naja... Dann werde ich es wohl aufgeben müssen.

    Dann gib eben auf, wenn du nicht selbst nachdenken willst. Glaube aber nicht, dass du so Mitleid erregst. 👎



  • 1089154 ist mein Ergebnis. Stimmt das?


  • Administrator

    Werner Salomon schrieb:

    ja das schreit doch geradezu nach einer abgefahrenen Lösung:

    Stimmt, aber ich hätte jetzt eher zu sowas tendiert:

    #include <cstddef>
    #include <iostream>
    
    template<std::size_t N>
    struct Fibonacci
    {
        static std::size_t const RESULT = Fibonacci<N - 2>::RESULT + Fibonacci<N - 1>::RESULT;
    };
    
    template<>
    struct Fibonacci<0>
    {
        static std::size_t const RESULT = 0;
    };
    
    template<>
    struct Fibonacci<1>
    {
        static std::size_t const RESULT = 1;
    };
    
    template<bool CHECK, std::size_t N, std::size_t MAX_FIBONACCI>
    struct SumEvenFibonacciHelper
    {
    private:
        static std::size_t const FIBONACCI = Fibonacci<N>::RESULT;
        static std::size_t const NEXT_SUM = SumEvenFibonacciHelper<(FIBONACCI < MAX_FIBONACCI), N + 1, MAX_FIBONACCI>::RESULT;
    
    public:
        static std::size_t const RESULT = NEXT_SUM + (FIBONACCI & 1 ? 0 : FIBONACCI);
    };
    
    template<std::size_t N, std::size_t MAX_FIBONACCI>
    struct SumEvenFibonacciHelper<false, N, MAX_FIBONACCI>
    {
        static std::size_t const RESULT = 0;
    };
    
    template<std::size_t MAX_FIBONACCI>
    struct SumEvenFibonacci
    {
        static std::size_t const RESULT = SumEvenFibonacciHelper<true, 2, MAX_FIBONACCI>::RESULT;
    };
    
    int main() 
    {
        std::cout << SumEvenFibonacci<4000000>::RESULT << std::endl;
    
        return 0; 
    }
    

    Grüssli 😃


  • Administrator

    skullyan schrieb:

    1089154 ist mein Ergebnis. Stimmt das?

    Meine Lösung und die von Werner ergeben 4613732. 😉

    Grüssli


Anmelden zum Antworten