Hallo donp,
Man sollte unsere beiden Lösungen mal gegeneinander antreten lassen, nur um zu sehen, wie groß dein vermeintlicher Tempo-Vorteil wirklich ist.
Tim hat ja verschiedene Varianten getestet. Die schnellste Variante mit Strings braucht fast fünf mal so viel Zeit wie meine. Ich bin da also mal recht optimistisch.
Habe gerade deinen Hinweis gefunden, dass die Daniel's Lösung ja gar nicht richtig funktioniert. Es stimmt tatsächlich, das u.U. eine Endlosschleife entsteht. Wie uncool :) !!
Ja, diesen kleinen Fehler hat Tim schon korrigiert, bevor ich das tun konnte. Vielleicht liest Du einfach erstmal die ganze Diskussion bevor Du sie Stückchenweise entdeckst ;-)
Nochmal zur Frage der Elleganz.
Elleganz ist sicher nicht direkt Ausführungsgeschwindigkeit, um etwas verständlich, erweiterbar o.ä. umzusetzen, kann man schon Ausführungsgeschwindigkeit opfern.
Ausführungsgeschwindigkeit ist dann ein Kriterium, wenn sich das asymptotische Verhalten ändert (passiert hier wahrscheinlich nicht) oder die Rechenzeit sich wirklich um einen relevanten Faktor unterscheidet. Was relevant ist, ist natürlich eine Frage der Anwendung. Bei einem Faktor > 2 wird es aber schon schnell relevant.
Immer ein Kriterium ist aber Einfachheit. Einfachheit ist dabei nicht zu verwechseln mit kürze. Man kann eben Einzeiler schreiben (in manchen Sprachen deutlich besser als in JS), in denen so viel ausgedrückt wird, dass 10 oder gar 100 Zeilen Code wahrscheinlich besser gewesen wären.
Von der Komplexität des Algorithmuses geben sich Dein und mein Programm nichts. Statt meiner äußeren Schleife verendest Du einen rekursiven Aufruf am Ende, die nichts anderes ausdrückt. Die while-Schleife drückt das meiner Meinung nach direkter aus, aber als rekursionsgewohnter Programmierer kommt man natürlich mit beidem klar.
Das aufsummieren der einzelnen Stellen machen wir beide mit einer while-Schleife. Der unterschied der bleibt ist lediglich String <-> Mathematik. Wenn man weiß, wie man Zahlendarstellungen ineinander umrechnet, (nämlich mit eben jener modulo-Operation) springt einen da meine Lösung an. Die String-Operationen ersparen einem an der Stelle eben, zu verstehen, was eigentlich passiert.
Gestört hat mich übrigens nicht die Verwendung von [], Array-Literale gibt es in vielen Sprachen, sondern die von ||. || ist erstmal ein boolsches Oder, die Verwendung als eine Art Inline-IF ist nicht besonders Erwartungskonform.
Eine sauber implementierte Variante Deiner vorgehensweise wäre:
function quersumme(n) {
var s = n.toString();
var sum = 0;
for (var i = 0; i < s.length; ++i) {
sum += s[i];
}
return sum < 10 ? sum : quersumme(sum);
}
Braucht zwei Zeilen mehr, iteriert ganz standardmäßig und verwendet keine überflüssigen Funktionsparameter, die beim Aufruf richt initialisiert werden müssen.
Grüße
Daniel