indexieren:



  • Das ist der bisher beste Troll... chapeau!



  • @out

    Das Teil, was Du schreibst, hatte ich auch schon. Es ist nur der Kern der Aufgabe, aber nicht vollständig erfasst. Gib in Dein Tool mal die Zahl 100 als Spiegelzahl ein, so wirst Du die Kette erblicken.

    Ich wollte die Kette in Map einlesen lassen, und zwar deshalb, weil im Allgemeinen vor Beginn der Kette noch ein paar nicht dazugehörende Zahlen kommen. Mich interessiert aber zb. nur die Kettenlänge. Ich wollte das Problem über Map lösen, denn nur so kann man die Zahlen erfassen, die mindestens 2 x vorkommen, und damit zur Kette gehören.

    Der nächste Schwierigkeitsgrad ist dann, daß manche zahlen 2 und 3 oder 4 verschiedene Ketten produzieren ... aber Schritt für Schritt, ich wollte das selber machen.

    (das nächste Mal nehme ich mein Buch mit, ... vielen Dank für die bisherige Hilfe ...



  • #include <cstdlib>
    #include <iostream>
    #include <map>
    using namespace std;
    
    int main()
    {
        map<int,unsigned> vorkommen;
        for(int zahl=1, faktor=2, spiegelzahl=100;;)
        {
            //cout << "Zahl = " << zahl;
            zahl *= faktor;
            zahl  = abs( spiegelzahl-zahl );
           // cout << " und Abstand = " << zahl << '\n';
    
            if( ++vorkommen[zahl] == 3 )
                {
    
                for(map<int,unsigned>::iterator it=vorkommen.begin(); it!=vorkommen.end(); ++it)
                    {
                    cout << it->first << " ist " << it->second << " x vorhanden" << '\n';
                    }
                break;
                    }
        }
    }
    

    jetzt wollte ich von dieser Liste nur die Zahlen, die genau 2 x vorkommen auslesen lassen. und in einen extra Speicher tun, wobei die erste Zahl, die 3 x vorkommt, die Abbruchbedinmgung auch in der Liste sein müsste, weil sie zur Kette gehört ...



  • Dann musst du die Liste auf ==2 vergleichen, nach der for-Schleife. Am Rest ändert sich ja nichts. Du kannst auch mal die komplette Aufgabenstellung posten.



  • brak schrieb:

    Der nächste Schwierigkeitsgrad ist dann, daß manche zahlen 2 und 3 oder 4 verschiedene Ketten produzieren ... aber Schritt für Schritt, ich wollte das selber machen.

    Versteh' ich nicht.
    Wie soll das gehen?
    In dem Loop ist ja nur die Zahl selbst variabel, und die Zahl selbst ist auch das was betrachtet wird?
    Wie kann es da "verschiedene Zyklen" geben?
    Das geht doch schon rein theoretisch nicht.

    Ansonsten sollte das recht einfach sein: in jedem Durchlauf machst du einen Eintrag in die map:
    map[zahl] = durchlaufsnummer;

    Davor guckst du ob es schon einen Eintrag für "zahl" gibt. Wenn ja kannst du aus der aktuellen Durchlaufsnummer und der in der Map eingetragenen die Zyklenlänge errechnen.
    Viel einfacher geht's nicht 😉



  • Das geht doch schon rein theoretisch nicht.

    .. doch doch, die Ausgangszahl ist doch immer verschieden ....

    out schrieb:

    Dann musst du die Liste auf ==2 vergleichen, nach der for-Schleife. Am Rest ändert sich ja nichts. Du kannst auch mal die komplette Aufgabenstellung posten.

    hatt ich schon gemacht, und zwar so:

    if( ++vorkommen[zahl] == 3 )
                {
                        for(map<int,unsigned>::iterator it=vorkommen.begin(); it!=vorkommen.end(); ++it)
                        {
                            if (it->second>=2)
                            {
                            cout << it->first << "; ";
                            }
                        }
                    cout<<"ist die Serie von SZ= "<<spiegelzahl<<" ";
                break;
    

    Es funktioniert jedenfalls,...:-)

    Was ich nicht versteh, ist Deine For Schleife in Zeile 9.

    Es gibt übrigens keine Aufgabenstellung. Ich forsche auf privater Basis nur ein bisschen im Zahlenraum rum .... Mach ich im Urlaub immer.

    Jetzt will ich die Spiegelzahl erhöhen und für jede Spiegelzahl Variable Zahl von 1 bis zur halben Spiegelzahl durchrattern lassen. Dabei sieht man, wieviel verschiedene* Ketten ein und dieselbe Spiegelzahl produziert.

    *verschieden nicht im Sinne der Eintrittszahl, oder Abfolge sondern im Sinne von gänzlich anderem Zahlenbestand



  • Warum funktioniert die auskommentierte vorgestzte fortschleife von Zeile 11 nicht, die das For in Zeile 14 beeinflusst?

    #include <cstdlib>
    #include <iostream>
    #include <map>
    using namespace std;
    
    int zehler;
    int spiegelzahl;
    int main()
    {
        map<int,unsigned> vorkommen;
       //for ( zehler=1;zehler=50; zehler++)
         //  {
           //cout<<"zehler="<<zehler<<"";
             for(int zahl=zehler, faktor=2, spiegelzahl=100;;)
            {
                //   cout << "Zahl = " << zahl;
                zahl *= faktor;
                zahl  = abs( spiegelzahl-zahl );
                // cout << " und Abstand = " << zahl << '\n';
    
                if( ++vorkommen[zahl] == 3 )
                {
    
                        for(map<int,unsigned>::iterator it=vorkommen.begin(); it!=vorkommen.end(); ++it)
                        {
                            if (it->second>=2)
                            {
                            cout << it->first << "; ";
                            }
    
                        }
                    cout<<"ist die Serie von SZ= "<<spiegelzahl<<" ";
                break;
    
                }
    
            }
       // }
    }
    


  • Was funktioniert da net? compilieren tuts.

    Wieso verstehst du die eine for-Schleife von mir nicht? Kann es sein, dass es bei der an den Grundlagen der Grundlagen sehr hapert? 😃


  • Mod

    Schau dir mal die Abbruchbedingung an.



  • out schrieb:

    Was funktioniert da net? compilieren tuts.

    ich meine, wenn man wieder einkommentiert ....

    out schrieb:

    Wieso verstehst du die eine for-Schleife von mir nicht?

    Warum tust Du die drei Initialisierungen, die ich normalerweise vor main anbringen würde, in die erste Abteilung von for?

    out schrieb:

    Kann es sein, dass es bei der an den Grundlagen der Grundlagen sehr hapert? 😃

    Kann schon sein, hab nie ne Computerschule besucht und mir erst letztes Jahr nen Buch gekauft, was jetzt auch nicht unglücklicherweise zuhause liegt ... außerdem bin ich kein Schnellmerker und auch sonst nicht so helle ...



  • Ich forsche mal mit im Zahelraum 😃

    #include <iostream>
    #include <cstdlib>
    #include <map>
    #include <string>
    #include <sstream>
    #include <vector>
    using namespace std;
    
    string int_to_string( int zahl )
    {
    	ostringstream oss;
    	oss << zahl;
    	return oss.str();
    }
    
    struct kette
    {
    	int zahl;
    	int faktor;
    	int spiegelzahl;
    	string k;
    };
    
    kette mach_kette( int zahl, int faktor, int spiegelzahl )
    {
    	kette k = { zahl, faktor, spiegelzahl };
        for(map<int,unsigned> vorkommen;;)
        {
            zahl *= faktor;
            zahl  = abs( spiegelzahl-zahl );
    
            k.k += int_to_string( zahl );
    
            if( ++vorkommen[zahl] == 3 )
                break;
        }
        return k;
    }
    
    int main()
    {
    	map< string,vector<kette> > zahlenspiel;
    	for(int zahl=1; zahl!=10; ++zahl)
    	{
    		for(int faktor=1; faktor!=3; ++faktor)
    		{
    			for(int spiegelzahl=10; spiegelzahl!=15; ++spiegelzahl)
    			{
    				kette k = mach_kette( zahl, faktor, spiegelzahl );
    				zahlenspiel[k.k].push_back( k );
    			}
    		}
    	}
    
    	for(map< string,vector<kette> >::iterator it=zahlenspiel.begin(); it!=zahlenspiel.end(); ++it)
    	{
    		vector<kette>& vec = it->second;
    		for(vector<kette>::iterator itk=vec.begin(); itk!=vec.end(); ++itk)
    		{
    			cout << "Kette=" << itk->k << "  Z=" << itk->zahl << "  F=" << itk->faktor << "  SZ=" << itk->spiegelzahl << '\n';
    		}
    		cout << '\n';
    	}
    }
    

    Wie findest das? Ich hab nur keine Ahnung, ob das immer terminiert 😃

    brak schrieb:

    Warum tust Du die drei Initialisierungen, die ich normalerweise vor main anbringen würde, in die erste Abteilung von for?

    Variablen kommen da hin, wo man sie brauch. Das was du machst war der Stil der 80er Jahre, schon uralt.



  • Danke, OUT, das scheint es zu sein. Du bist aber nicht in die interessanten Bereiche vorgedrungen. In "Kette" wird bei Dir alles bis zum Break abgespeichert. Es soll aber nur 1 x die Kette rein, damit Kettenlänge und Eintrittszahl registriert werden können.

    Jetzt noch was. In den höheren Bereichen treten mehrere Ketten auf. 34 ist bei mir die erste Zahl, in der zwei vollkommen unabhängige Viererketten auftauchen.

    Den Faktor kann man vorerst auf 2 einstellen. Wichtig ist die Spiegelzahl hochzudrehen, und die Ketten bis zur Hälfte der Spiegelzahl, wegen Symmetrie, herauszusuchen, also, wieviel verschiedene, wie lang die sind, und welche Zahlen Sie beinhalten. Vielleicht gibt es ja auch welche, die sich eine Zahl teilen? (Was ich nicht glaub). Wo die Spiegelzahl ungerade ist bei Faktor zwei übrigens die Folge der unger. Zahlen Kettenbestandteil.

    Kannst Du nicht auch noch Semikolons zwischen die einzelnen Glieder der Kette zaubern, oder mir sagen, wo ich die hintun muß? Du machst ja int zu string .... hab ich noch nie gemacht... weiss gar nicht, ob das gut ist.



  • out schrieb:

    Ich hab nur keine Ahnung, ob das immer terminiert 😃

    Hängt stark vom Faktor ab.

    Faktor=0:
    mach_kette(17,0,100);
    10 10 10
    stabil

    Faktor=1:
    mach_kette(17,1,100);
    83 17 83 17 83
    zweierzyklus

    Ab Faktor 3 terminiert es nicht mehr.

    Faktor=2:
    also for(;;)zahl=abs(spiegelzahl-2*zahl);
    Wenn die Zahl gräßer als die Spiegelzahl ist, haut sie ab.
    Wenn die Zahl gleich der Spiegelzahl ist, bleibt sie stabil.
    Wenn die Zahl gleich 0 ist, ist sie im nächsten Schritt gleich der Spiegelzahl und wird stabil.

    Wenn die Zahl kleiner ist als die Spiegelzahl und größer als 0, dann gilt das auch für die folgende Zahl. Also sicher ein Zyklus. Dessen Länge wäre dann noch spannend.

    mach_kette(17,2,100);
    66 32 (36 28 44 12 76 52 4 92 84 68) 36 28 44 12 76 52 4 92 84 68 36)

    mach_kette(26,2,39);
    (13) 13 13

    mach_kette(25,2,39);
    (11 17 5 29 19 1 37 35 31 23 7 25) 11 17 5 29 19 1 37 35 31 23 7 25 11

    Da sehe ich noch nicht klar.



  • die 39 als Spiegelzahl hat mindestens 3 ketten, davon ist die mit Zahl 26 trivial

    hier die Ketten für Zahl 21 und 22

    21 3 33 27 15 9 21 3 33 27 15 9 21 3 33 27 15 9 21 3 33 27 15 9 21

    22 5 29 19 1 37 35 31 23 7 25 11 17 5 29 19 1 37 35 31 23 7 25 11 17



  • brak schrieb:

    die 39 als Spiegelzahl hat mindestens 3 ketten, davon ist die mit Zahl 26 trivial

    hier die Ketten für Zahl 21 und 22

    21 3 33 27 15 9 21 3 33 27 15 9 21 3 33 27 15 9 21 3 33 27 15 9 21

    22 5 29 19 1 37 35 31 23 7 25 11 17 5 29 19 1 37 35 31 23 7 25 11 17

    Beachte die Kettenlängen:
    21 3 33 27 15 9 21 3 33 27 15 9 21 (3 33 27 15 9 21 3 33 27 15 9 21)

    22 5 29 19 1 37 35 31 23 7 25 11 17 (5 29 19 1 37 35 31 23 7 25 11 17)

    gleich. Jede Spiegelzahl kann nur eine kleine Anzahl von Kettenlängen produzieren. Hier 12, und ich halte es für keinen Zufall, daß das nur eins weniger ist als der große Teiler 13 in der 39.
    Gibts ähnliche Auffälligkeiten bei Spiegelzahlen wie 51=3*17 oder 57=3*19?

    Zum Zyklenfinden bietet sich http://en.wikipedia.org/wiki/Cycle_detection an, da brauchste keine map mehr. (Nicht auf die deutsche Version dieses Artikel klicken, der ist beschämend schlecht.)



  • Ich hab mal Leezeichen dazwischengesetzt:

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <map>
    #include <string>
    #include <sstream>
    #include <vector>
    using namespace std;
    
    string int_to_string( int zahl )
    {
        ostringstream oss;
        oss << zahl;
        return oss.str();
    }
    
    struct kette
    {
        int zahl;
        int faktor;
        int spiegelzahl;
        string k;
    };
    
    kette mach_kette( int zahl, int faktor, int spiegelzahl )
    {
        kette k = { zahl, faktor, spiegelzahl, ">" + int_to_string(zahl) + "< " };
    	vector<int> glieder;
    
    	for(map<int,unsigned> vorkommen;;)
        {
            zahl *= faktor;
            zahl  = abs( spiegelzahl-zahl );
    
    		glieder.push_back( zahl );
    
    		if( glieder.size()%2==0 && equal( glieder.begin(),glieder.begin()+(glieder.size()/2), glieder.begin()+(glieder.size()/2)) )
    		{
    			for(unsigned i=0; i!=glieder.size()/2; ++i)
    				k.k += int_to_string( glieder[i] ) + " ";
    
    			return k;
    		}
        }
    }
    
    int main()
    {
        map< string,vector<kette> > zahlenspiel;
        for(int zahl=20; zahl!=25; ++zahl)
        {
    		for(int spiegelzahl=39; spiegelzahl!=40; ++spiegelzahl)
    		{
    			kette k = mach_kette( zahl, 2, spiegelzahl );
    			zahlenspiel[k.k].push_back( k );
    		}
        }
    
        for(map< string,vector<kette> >::iterator it=zahlenspiel.begin(); it!=zahlenspiel.end(); ++it)
        {
            vector<kette>& vec = it->second;
            for(vector<kette>::iterator itk=vec.begin(); itk!=vec.end(); ++itk)
            {
                cout << "Kette = " << itk->k  << '\n';
            }
            cout << '\n';
        }
    }
    

    Die for-Schleife für den Faktor hab ich rausgenommen und auf 2 gesetzt, damit es terminiert, wie volkard gesagt hat. 😃

    Bei deinem Beispiel hast du bei 21 ja ein Fehler drin, oder?:D Das wiederholt sich doch vorher schon.



  • Verdoppelung der Spiegelzahl bringt keine längere Kette, sondern die Verdoppelung der Werte der Kette .... ist irgendwie logisch

    Jede Spiegelzahl kann nur eine kleine Anzahl von Kettenlängen produzieren.

    Woher weißt Du das? Hast Du schon mal Spiegelzahl 199458 durchgerattert?



  • brak schrieb:

    Verdoppelung der Spiegelzahl bringt keine längere Kette, sondern die Verdoppelung der Werte der Kette .... ist irgendwie logisch

    Jede Spiegelzahl kann nur eine kleine Anzahl von Kettenlängen produzieren.

    Woher weißt Du das? Hast Du schon mal Spiegelzahl 199458 durchgerattert?

    Nur 7 Zykluslängen.

    Bitte Spiegelzahl eingeben: 199458
    laenge	anzahl
    1	5
    3	24
    6	96
    791	3164
    1582	6328
    2373	18984
    4746	170856
    

    199458=2*3*3*7*1583
    Zykluslänge 1582 taucht wiedermal auf.

    #include <iostream>
    #include <map>
    using namespace std;
    
    int64_t f(int64_t zahl,int64_t spiegelzahl){
    	return abs(spiegelzahl-2*zahl);
    }
    
    int64_t findeZyklus(int64_t zahl,int64_t spiegelzahl){
    	int64_t igel=zahl;
    	int64_t hase=zahl;
    	do{
    		igel=f(igel,spiegelzahl);
    		hase=f(hase,spiegelzahl);
    		hase=f(hase,spiegelzahl);
    	}while(hase!=igel);
    	return hase;
    }
    
    int64_t findeZyklusLaenge(int64_t zahl,int64_t spiegelzahl){
    	int64_t igel=findeZyklus(zahl,spiegelzahl);
    	int64_t hase=igel;
    	int64_t len=0;
    	do{
    		hase=f(hase,spiegelzahl);
    		++len;
    	}while(hase!=igel);
    	return len;
    }
    
    int main()
    {
    	cout<<"Bitte Spiegelzahl eingeben: ";
    	int64_t spiegelzahl;
    	cin>>spiegelzahl;
    
    	map<int64_t,int64_t> zyklenLaengen;
    
    	for(int64_t startzahl=1;startzahl<spiegelzahl;++startzahl)
    		++zyklenLaengen[findeZyklusLaenge(startzahl,spiegelzahl)];
    
    	cout<<"laenge\tanzahl\n";
    	for(auto i:zyklenLaengen)
    		cout<<i.first<<"\t"<<i.second<<'\n';
    }
    

    Schau Die mal die Spiegelzahlen zwischen 65530 und 65540 an. 😋



  • Ich möchte mal fragen, warum das Teil von out so langsam arbeitet. Was ist denn der spez. Befehl der soviel Zeit kostet. Ich lade gerade Zahl 1 - 50, spiegelzahl hundert durchlaufen, der Computer arbeitet wie wild, wird aber irgendwie nicht fertig .... ich meine, es sind ein paar Additionen und Subtraktionen, wie haben 2014 und der Computer ist kein C64 mehr -... wunder, wunder ...



  • brak schrieb:

    Ich möchte mal fragen, warum das Teil von out so langsam arbeitet. Was ist denn der spez. Befehl der soviel Zeit kostet. Ich lade gerade Zahl 1 - 50, spiegelzahl hundert durchlaufen, der Computer arbeitet wie wild, wird aber irgendwie nicht fertig .... ich meine, es sind ein paar Additionen und Subtraktionen, wie haben 2014 und der Computer ist kein C64 mehr -... wunder, wunder ...

    Weil er algorithmisch getrixt hat.
    In Zeile 37 ist der Hase elendlich verendet.
    Hab keine Ahnung, was die machen soll. Aber um nen Zykus aufzudecken, reicht bereits eine einzige Wiederholung, es müssen nicht deren drei sein oder die Hälfte aller Zahlen.
    16G Ram reichen schonmal nicht aus. Ich fürchte, mit noch mehr braucht man es nicht zu probieren.


Anmelden zum Antworten