Fröhliche Zahlen



  • Sone schrieb:

    Aber du kannst es doch ganz einfach umschreiben... (soll ich?)

    Mir würde es helfen, wenn du sagst was für "Dummheiten" ich mache. Hab ich es jetzt richtig verstanden, dass man keinen Hilfsvektor benötigt?



  • Namal schrieb:

    Mir würde es helfen, wenn du sagst was für "Dummheiten" ich mache.

    Das ist dumm:

    Um es zu optimieren, soll das Programm bei einer Summe überprüfen ob es schon eine fröhliche Zahl ist oder eine unfröhliche Zahl ist, ansonsten mit dem überprüfen weitermachen.

    Kann in einer Endlos-Schleife enden!
    Und optimiert auch überhaupt nicht, weil sowieso bis 1 durchgerechnet werden muss.



  • Sone schrieb:

    Und optimiert auch überhaupt nicht, weil sowieso bis 1 durchgerechnet werden muss.

    Warum? Wenn man auf eine Summe trifft, die bereits fröhlich oder unfröhlich eingetragen ist, dann muss man nicht mehr weiter rechnen und kann die zu untersuchende Zahl gleich entsprechend setzen. Bis 1 soll er nur dann rechnen, solange keine der Summen markiert ist.



  • Hör nicht auf Sone :xmas1:



  • Namal schrieb:

    Sone schrieb:

    Und optimiert auch überhaupt nicht, weil sowieso bis 1 durchgerechnet werden muss.

    Warum? Wenn man auf eine Summe trifft, die bereits fröhlich oder unfröhlich eingetragen ist

    Ach, ich hab' ganz vergessen. Du benutzt ja eine Tabelle wo du alle einträgst... 💡
    Dann vergiss die beiden Bemerkungen.



  • Hab ich es jetzt richtig verstanden, dass man keinen Hilfsvektor benötigt?

    Ja. Versuch doch erstmal ohne. Schreib mein Funktionstemplate zu einer Funktion um (in dem du alle Type s durch einen integralen Typ deiner Wahl ersetzt) und mach in der Siebe Funktion eine einfache Schleife :xmas2:



  • Sone schrieb:

    template<typename Type>
    typename std::enable_if<std::is_integral<Type>::value, bool>::type isHappy(Type initial)
    {
        Type next,
             cur  = initial;
        for(;;)
        {
            next = 0;
            while(cur)
            {
                Type mod = cur % 10;
                next += mod * mod;
                cur /= 10;
            }
    
            if(next == 1)
                return true;
            if(next == initial)
                return false;
    
            cur = next;
        }
    }
    

    Ist das eigentlich so, dass der Zyklus immer mit dem initial Wert endet? Kommt 2 nicht ein den 4er Zyklus?



  • Ist das eigentlich so, dass der Zyklus immer mit dem initial Wert endet?

    ...
    Lies bitte den Wikipedia-Artikel.

    Kommt 2 nicht ein den 4er Zyklus?

    Ich verstehe nicht was du meinst. :xmas2:



  • Sone schrieb:

    Ist das eigentlich so, dass der Zyklus immer mit dem initial Wert endet?

    ...
    Lies bitte den Wikipedia-Artikel.

    Habe ich und besser verstanden als du.

    Kommt 2 nicht ein den 4er Zyklus?

    Ich verstehe nicht was du meinst. :xmas2:

    Endlosschleife bei isHappy(2) mit deinem Code.



  • SchokoladeMandeln schrieb:

    Sone schrieb:

    Ist das eigentlich so, dass der Zyklus immer mit dem initial Wert endet?

    ...
    Lies bitte den Wikipedia-Artikel.

    Habe ich und besser verstanden als du.

    Sry, ich hab zu schnell gelesen.
    Ja, du hast Recht. Ich muss aber nur eine Zeile ändern

    template<typename Type>
    typename std::enable_if<std::is_integral<Type>::value, bool>::type isHappy(Type cur)
    {
        Type next;
    
        for(;;)
        {
            next = 0;
            while(cur)
            {
                Type mod = cur % 10;
                next += mod * mod;
                cur /= 10;
            }
    
            if(next == 1)
                return true;
            if(next == 4)
                return false;
    
            cur = next;
        }
    }
    


  • Und jetzt noch mit Iteratoren!

    template<typename T,
             typename = typename std::enable_if<std::is_integral<T>::value>::type>
    T isHappy(T n)
    {
      for (;;) {
        n = std::sum(make_transform_iterator(digit_iterator(n), [](T t){return t*t;}),
                     make_transform_iterator(digit_iterator(0), [](T t){return t*t;}));
        if (n == 1) return true;
        if (n == 4) return false;
      }
    }
    


  • Haha, ja .. wenn man C++11 benutzen darf 🙄



  • Ich habe mir nicht die Mühe gemacht, Deinen Algorithmus, den Du programmiert hast zu verstehen, allerdings habe ich eine Vermutung, was Du versuchst und wie.

    Das wird so nicht funktionieren!

    Der std::vector von C++ hat eine bestimme Größe und eignet sich nur bedingt, für die Abbildung aller möglichen quadrierten und summierten Ergebnisse, d.h. wenn Du auf einen Vektor an Stelle zahlen2[summen[u]] zugreifst, muss auch gelten: summen[u] < zahlen2.size() . Entweder du vergrößerst Den Vector immer entsprechend, oder Du wählst einen anderen Container. Z.b. zwei std::sets für fröhlich/traurig.

    Ausserdem: niemand mag Magic-Numbers:
    const unsigned int happy = 1; 😉



  • @Furble Wurble, danke. Dass es nicht das Wahre ist, seh ich ein.

    Furble Wurble schrieb:

    muss auch gelten: summen[u] < zahlen2.size()

    Kann ich es nicht einfach durch

    for(int u=0;u<summen.size() && summen[u] < zahlen2.size();++u)
    

    vermeiden?

    Furble Wurble schrieb:

    Ausserdem: niemand mag Magic-Numbers:
    const unsigned int happy = 1; 😉

    ???

    @Sonne, jetzt habe ich deinen Code mehr oder weniger verstanden, allerdings ist es ja grad so, dass die schon untersuchten Zahlen dann immer wieder untersucht werden, das möchte ich ja irgendwie vermeiden.



  • Namal schrieb:

    @Sonne, jetzt habe ich deinen Code mehr oder weniger verstanden, allerdings ist es ja grad so, dass die schon untersuchten Zahlen dann immer wieder untersucht werden, das möchte ich ja irgendwie vermeiden.

    frag doch werner, ob er dir einen fröhlichen zahlen iterator baut. 😃
    http://www.c-plusplus.net/forum/311250



  • Furble Wurble schrieb:

    Ausserdem: niemand mag Magic-Numbers:
    const unsigned int happy = 1; 😉

    ???

    Er meint magische Zahlen.

    @Sonne, jetzt habe ich deinen Code mehr oder weniger verstanden, allerdings ist es ja grad so, dass die schon untersuchten Zahlen dann immer wieder untersucht werden, das möchte ich ja irgendwie vermeiden.

    premature optimization is the root of all evil



  • Ok, noch ein Versuch:

    de <iostream> 
    #include <vector> 
    #include <cmath> 
    #include <iomanip> 
    
    using namespace std; 
    
    vector <bool> Sieben (int n){
    	vector <bool> z(n,false);
    
    	z[1]=true;
    
    	for(int k=2;k<z.size();++k){
    
    	int sum=0; 
    
    		int d = k;
    		while(d){
    			int mod = d%10;
    			sum +=mod*mod;	
    			d/=10;
    		}
    
    		if(sum == 1) 
    			z[k]=true; 
    		if(sum == 4) 
    			z[k]= false;
    
    		d=sum;
    	}	
    
    return z;
    }
    
    void Ausgabe(const vector<bool> &z){ 
         int i=0; 
         for (int k=0;k<z.size();++k){              
             if(z[k]){ 
                     cout<<setw(5)<<k; 
                     ++i; 
                     if(i>9) 
                         { 
                             cout<<'\n'; 
                             i=0; 
                         }       
             } 
    
         }   
         cout<<'\n'; 
    } 
    
    int main(int argc,char *argv[]){
    
    	vector<bool> froh=Sieben(5000);
    	Ausgabe(froh);
    	return 0;
    }
    

    Diesmal werden mir aber nur die Zahlen mit 1 am Anfang ausgegeben :xmas2:
    Bin auch blöd, da gehört eine schleife drumrum.



  • vector <bool> Sieben (int n){
    	vector <bool> z(n,false);
    
    	z[1]=true;
    	z[4]=false;
    
    	for(int k=2;k<z.size();++k){
    		if(k==4) continue;
    
    		int sum=0; 
    		int d = k;
    		while(d!=1 || d!=4){	
    			while(d){
    				int mod = d%10;
    				sum +=mod*mod;	
    				d/=10;
    			}
    
    			if(sum == 1){ 
    				z[k]=true; 
    			}
    			if(sum == 4) 
    				z[k]= false;
    
    			d=sum;
    
    		}	
    	}	
    
    return z;
    }
    
    Kann mir bitte jemand sagen, warum das in einer Endlosschleife endet?
    


  • Namal schrieb:

    while(d!=1 || d!=4){
    


  • while(d!=1 && d!=4){
    

    So funktioniert es aber auch nicht 😕


Anmelden zum Antworten