Hallo donp,
Die eleganteste Lösung scheint mir hier die Rekursion mit Umwandlung in Strings, aber bitte nicht zu umständlich.
Die Umwandlung ist unelegant, weil Strings eine wirklich platzaufwendige Zahlendarstellung darstellung und rechenoperationen darauf im vergleich wirklich katastrophal langsam sind. Ich lehne es auch immer ab, über irgendwelche minimalen Performance-Unterschiede zu diskutieren. Irgendwelche Hacks zu verwenden und damit unwartbare Programme zu erzeugen, um irgendwelche hypothetischen Verbesserungen herauszuholen, ist natürlich schwachsinnig.
Wenn man nur eine quersumme ausrechnen will, ist es auch egal, wie man es tut. Meistens verwendet man solche rechenoperationen aber in einem Kontext, in dem man sie sehr häufig benötigt. Und dann wird der unterschied durchaus relevant.
Ein weiterer Hintergrund, warum ich die String-Variante für unelegant halte, ist, dass man damit auf einer Darstellung der Zahlen und nicht auf den Zahlen selbst arbeitet.
function qs(n,a) {
while ( ( a||[] )[0] ) {
n += parseInt( a.pop() );
}
return (n < 10) ? n : qs( 0, n.toString().split('') );
}
Nein, wenn man weiß, was da alles abläuft, ist das nicht mehr elegant. Hinter split steckt eine Implementierung von Regulären ausdrücken, parseInt() hat sicher auch ein paar Zeilen Code. Muss man wirklich so dicke Geschütze auffahren, um ein bisschen zu rechnen?
Außerdem verwendest Du dann auch noch Tricks wie "a||[]" und eine while-Schleife um über ein Array zu iterieren. Das ist nicht besonders lesbar (wer kennt schon die genaue Semantik von || in JS) und eine while-Schleife dürckt auch nicht gleich aus, dass hier einfach ein Array durchlaufen wird.
Dann wird beim ersten Aufruf auch noch die while-Schleife gar nicht ausgeführt, d.h. der erste Rekursionsschritt tut erstmal nichts.
Du hast einen Parameter a, der nur für interne Zwecke dient.
Nene, tut mir Leid ;-) aber das ist meiner Meinung eher die uneleganteste genannte Lösung.
Grüße
Daniel