indexieren:
-
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?

-
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
stabilFaktor=1:
mach_kette(17,1,100);
83 17 83 17 83
zweierzyklusAb 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 13mach_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 11Da 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 170856199458=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.
-
volkard schrieb:
Weil er algorithmisch getrixt hat.
In Zeile 37 ist der Hase verendet.kann man das nicht untrixy machen? Ich bin, wie schon bemerkt, kein Programmierungsprofi, aber irgendwie habe ich eine andere Vorstellung von Performance ...:-)
-
brak schrieb:
volkard schrieb:
Weil er algorithmisch getrixt hat.
In Zeile 37 ist der Hase verendet.kann man das nicht untrixy machen? Ich bin, wie schon bemerkt, kein Programmierungsprofi, aber irgendwie habe ich eine andere Vorstellung von Performance ...:-)
Einmal den dunklen Weg beschritten, muss man dabeibleiben, fürchte ich.
So klapp's wieder:if( glieder.size()%2==0 && equal( glieder.begin()+(glieder.size()/3),glieder.begin()+(glieder.size()*2/3), glieder.begin()+(glieder.size()*2/3)) )
-
volkard schrieb:
Einmal den dunklen Weg beschritten, muss man dabeibleiben, fürchte ich.

Was meinst Du denn pragrammiertechnisch mit "Dunkler Weg", den out beschritten habe? Der Austausch von 1/2 durch 2/3 kann es ja auch nicht sein ....
-
brak schrieb:
volkard schrieb:
Einmal den dunklen Weg beschritten, muss man dabeibleiben, fürchte ich.

Was meinst Du denn pragrammiertechnisch mit "Dunkler Weg", den out beschritten habe? Der Austausch von 1/2 durch 2/3 kann es ja auch nicht sein ....
Doch, 2/3 ist viel freundlicher als 1/2.
Er merkt sich die bisherigen Zahlen.
Und vergleicht die erste Hälfte mit der Zweiten Hälfte.
Aber bei Folgen wie
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)
hat er einfach Pech, die Startzahl kommt nicht im Zyklus vor!
Es können am Anfang auch mehrere Zahlen sein, die nicht im Zyklus sind, man kann vorher nicht wissen, wie viele.
Deswegen muss beim Vergleichen am Anfang genug weggelassen werden.
Ich vergleiche deswegen nicht die erste Hälfte mit der zweiten Hälfte, sondern das zweite Drittel mit dem dritten Drittel.
-
Kleine Liste mit Rekord-Zykluslängenanzahlen:
3 1
9 2
15 3
45 5
105 6
135 7
225 8
405 9
675 11
1485 13
2025 14
3375 15
4455 17
9315 18
Bis 10000 maximal 18 Zykluslängen. Und die Rekord-Spiegelzahlen haben sehr ähnliche Primfaktorzerlegungen: viel 3, fast so viel 5, und selten mal was anderes.