Alle geraden Fibonacci Zahlen summieren



  • 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



  • Dravere schrieb:

    skullyan schrieb:

    1089154 ist mein Ergebnis. Stimmt das?

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

    Grüssli

    👍



  • skullyan schrieb:

    Dravere schrieb:

    skullyan schrieb:

    1089154 ist mein Ergebnis. Stimmt das?

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

    Grüssli

    👍

    Jetzt hast du das Ergebnis, aber den Weg nicht... hat's sich für dich gelohnt? 🙄



  • gelöscht



  • Da keine explizite Programmiersprache angegeben ist, und es bestimmt nur zufaellig in das C++-Forum gerutscht ist, poste ich mal meine Loesung in Haskell:

    fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
    main = do putStrLn $ show $ sum $ takeWhile (<4000000) $ filter even fibs
    


  • Und gerade wollte ich fragen, wo knivil mit seinem Haskell-Einzeiler bleibt.



  • Hach, sowas wollte ich schon immer mal schreiben. (riecht fast ein wenig undefiniert?)

    #include <iostream>
    int main(){int a=1,b=2,s=2;while((b=(a+=b*2)*2-b)<4e6)s+=b;std::cout<<s;}
    

  • Mod

    volkard schrieb:

    Hach, sowas wollte ich schon immer mal schreiben. (riecht fast ein wenig undefiniert?)

    #include <iostream>
    int main(){int a=1,b=2,s=2;while((b=(a+=b*2)*2-b)<4e6)s+=b;std::cout<<s;}
    

    Ich seh nichts undefiniertes.



  • @Dravere, knivil, volkard 👍

    volkard Du inspirierst mich. Als Freund und Förderer der for-Schleife würde ich schreiben:

    #include <iostream>
    #include <algorithm> // std::swap
    
    int main()
    {
        int sum = 0;
        for( int prev_even = 0, fibo_even = 2; fibo_even < 4E6; std::swap( prev_even += 4*fibo_even, fibo_even ) )
            sum += fibo_even;
        std::cout << sum << std::endl;
    }
    

    Gruß
    Werner


  • Mod

    Hier dann noch eine für die Sprache C typische Version 🤡 :

    #include <stdio.h>
    
    I_I(_, _0_, __,_3)??<return((_=(_0_+=_*_3)*_3-_)<4e6)?I_I(_,_0_,__+=_,_3):__;??>main(_)??<printf("%i",I_I(_+_,_,_+_,_+_));??>
    


  • *hust* da bekommt man ja Angst 😮



  • Dweb schrieb:

    *hust* da bekommt man ja Angst 😮

    Das ist ja auch so gedacht. 😉



  • Also ich mag solche Threads, und noch mehr die kreativen Vorschläge. 👍

    Da hats ja wirklich für jeden was dabei. 🙂



  • Nexus schrieb:

    Da hats ja wirklich für jeden was dabei. 🙂

    Draveres Version ist mein Favorit 😃
    (Nexus du kommst nicht zufälligerweise ausm Süden? "Da hats" statt "da gibts" kenn ich bisher nur ausm allemannischen Sprachraum...)


Anmelden zum Antworten