So, das ganze ist in die Main Methode verschoben und abgespeckt worden, mal sehen wie lange er braucht.
[JAVA] Bloodys Mathe-/Optimierungsrunde
- BloodyEric
- Geschlossen
- Erledigt
-
-
Man MUSS diese gleichung RÜCKWIRKEND lösen, ich hab da aber kein plan wie, denn über ausprobieren kommt man immer ans ziel ABER vlt. gehts ja mit anderen hilfmitteln aus dem allseitsbekanntem mathe unterricht. (Quadratische gleichung o.ä ich wei noch nicht ganz :D)
-
Nene, ausprobieren ist ausdrücklich erwünscht!
Nur halt....relativ schnell soll das ganze funktionieren.
Nochmal ein Tipp von meiner Seite: Jede Variablendeklaration, jede Variablenzuweisung, jede Variablenabfrage und jede Rechenoperation kostet Zeit.
Wieso also zum Beispiel bei jedem Durchlauf 3^3 rechnen, anstatt einfach direkt 27 zu addieren? (Als Beispiel)
-
Das folgende Programm benötigt (auf meinem Rechner) um die 810 Sekunden, das entspricht 13,5 Minuten.
Code
Alles anzeigenpublic static void main(String[] args) { int iCopy; int finalValue; int character; for(int i = 0; i < 450000000; i++) { iCopy = i; finalValue = 0; while (iCopy > 0) { character = iCopy % 10; if(character != 0) { finalValue += (int)Math.pow(character, character); } iCopy = iCopy / 10; } if(finalValue == i) { System.out.println("I found one: " + i); } } }
-
Ich vermute jetzt einfach mal, dass es aus 2 Gründen enorm langsam ist:
-Du nutzt die Power Funktion, statt dir selbst eine zu schreiben und diese zu optimieren
-Du schließt keine Zahl irgendwie aus, die auf jeden Fall zu groß istMit solchen Abfragen solltest du das Ganze auf jeden Fall unter 2 Minuten (bei ner vernünftigen CPU) bringen, danach gehts wirklich ans Eingemachte (und ist dann auch so langsam der Teil, wo ich selbst noch Hilfe brauche)
-
Neues Programm, neue Bestzeit 36 Sekunden:
//edit: Mit hinzufügen von "if(finalValue > i) break;" noch 29 Sekunden:Code
Alles anzeigenpublic static void main(String[] args) { int iCopy; int finalValue; int character; for(int i = 0; i < 450000000; i++) { iCopy = i; finalValue = 0; while (iCopy > 0) { character = iCopy % 10; if(character==1) finalValue += 1; else if(character==2) finalValue += 4; else if(character==3) finalValue += 27; else if(character==4) finalValue += 256; else if(character==5) finalValue += 3125; else if(character==6) finalValue += 46656; else if(character==7) finalValue += 823543; else if(character==8) finalValue += 16777216; else if(character==9) finalValue += 387420489; if(finalValue > i) break; iCopy = iCopy / 10; } if(finalValue == i) { System.out.println("I found one: " + i); } } }
-
Not bad! Aber du berechnest immer noch bereits viiel zu große Zahlen streng bis zum Ende durch
-
Nicht mehr, siehe Editierung, hat nochmal 7 Sekunden rausgeholt.
-
Schöne Sache
Jetzt ist der Punkt, an dem ich auch nicht so wirklich weiterkomme: 90% der Zeit, die die Sache verbraucht, geht für das Dividieren bzw die MOD Operation drauf. Ich bin seit gestern am Überlegen, wie man das umgehen kann, womit man das endgültig schnell haben sollte...
-
Ich habe es geschafft, mein Intel Core i3 braucht um die 5 Sekunden!
Der folgende Code enthält die Main, eine zusätzliche Methode und eine Zeitauswertung:Code
Alles anzeigenpublic static void main(String[] args) { int tickCountStart = (int) System.currentTimeMillis(); int ii, ij, ik, il, im, in, io, ip, iq; int pi, pj, pk, pl, pm, pn, po, pp, pq; for(int i = 0; i < 10; i++) { pi = getPow(i); ii = i * 100000000; for(int j = 0; j < 10; j++) { pj = pi + getPow(j); ij = ii + j * 10000000; for(int k = 0; k < 10; k++) { pk = pj + getPow(k); ik = ij + k * 1000000; for(int l = 0; l < 10; l++) { pl = pk + getPow(l); il = ik + l * 100000; for(int m = 0; m < 10; m++) { pm = pl + getPow(m); im = il + m * 10000; for(int n = 0; n < 10; n++) { pn = pm + getPow(n); in = im + n * 1000; for(int o = 0; o < 10; o++) { po = pn + getPow(o); io = in + o * 100; for(int p = 0; p < 10; p++) { pp = po + getPow(p); ip = io + p * 10; for(int q = 0; q < 10; q++) { pq = pp + getPow(q); iq = ip + q; if(pq == iq) { System.out.println("Got one: " + pq); } } } } } } } } } } int tickCountEnd = (int) System.currentTimeMillis(); System.out.println("Dauer: " + ((tickCountEnd - tickCountStart) / 1000) + " Sekunden"); } private static int getPow(int integer) { if(integer==1) return 1; else if(integer==2) return 4; else if(integer==3) return 27; else if(integer==4) return 256; else if(integer==5) return 3125; else if(integer==6) return 46656; else if(integer==7) return 823543; else if(integer==8) return 16777216; else if(integer==9) return 387420489; else return 0; }
-
-
Das ist wahnsinnig gut!
Wie genau funktioniert das, also was EXAKT macht das? Ich seh, dass du dadurch das "teilen" um auf die Stellen zu kommst einsparst, aber wie genau?
-
Also, Ich habe mir gedacht ich gehe nicht von den Zahlen aus, sondern generiere die Zahlen selber. So erstellt jede for-Schleife eine neue Ziffer. Darrum kann Ich auch auf die Werte der letzten Ziffer zurückgreifen ohne Sie neu berrechnen zu müssen. Das ist alles...
-
Super gedacht
Sollte ich jemals im Lotto gewinnen, kriegst du nen Bruchteil ab
-
3 Sekunden auf i7 nice, wie biste drauf gekommen ?
//Edit: jo ich checks, richtig geil ! Den weg werd ich mir merken ! Danke dir !
-
Das ganze hätte auch durch eine schöne Teiler / Modulo Variante gelöst werden können, aber das mit den verschachtelten Schleifen ist auch recht praktisch.
-
Die steht doch in den ganzen Posts davor, aber die war halt paar Minuten langsamer...
-
Nicht so wie es auf der ersten Seite war, habs gerade mal implementiert, aber komme auch nur auf rund 22561ms, hätte jetzt nicht gedacht, dass es so extrem langsamer wäre.
Dann will ich nichts gesagt haben
-
Wie haste denn deins genau gemacht? Auch DIV um die Stelle zu ändern und MOD um den Wert der Stelle zu bekommen?
-
Hab mir auch erstmal mithilfe einer forschleife und einer zusätzlichen hilfs var selber die Zahlen zusammengebastelt, und dann durch teiler modulo die stellen gegeben und umrechnen lassen.
-
if(integer==1) return 1;
if(integer==2) return 4;
if(integer==3) return 27;
if(integer==4) return 256;
if(integer==5) return 3125;
if(integer==6) return 46656;
if(integer==7) return 823543;
if(integer==8) return 16777216;
if(integer==9) return 387420489;
return 0;
wäre das nicht theoretisch schneller?und statt < !=
bsp: for(int i = 0; i != 10; i++) -