Hallo Daniel,
Jetzt war ich soooo stolz auf meine geniale Lösung, und du machst sie dermaßen runter. Das ist ja starker Tobak.
Die Umwandlung ist unelegant, weil Strings eine wirklich platzaufwendige Zahlendarstellung darstellung und rechenoperationen darauf im vergleich wirklich katastrophal langsam sind.
Dass Rechnen mit Zahlen viel schneller geht bezweifelt niemand.
Aber von Eleganz im Programmcode scheinen wir gänzlich unterschiedliche Vorstellungen zu haben.
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.
Das ist ja das selbe Argument wie oben.
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.
Natürlich ist das so. Wieder das selbe Argument.
Muss man wirklich so dicke Geschütze auffahren, um ein bisschen zu rechnen?
Man *muss* nicht, aber es ist eben eleganter in meinen Augen, weil kompakt mit wenig Quellcode.
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.
Dass ein pop() in einer while-Schleife schrittweise Array-Elemente entfernt, sieht doch ein Blinder ;)
"a||[]" ist kein Trick, sondern ein elegantes Konstrukt, das absichtlich in JavaScript implementiert wurde. Es ist die Abkürzung für
if (a) { return a; }
else{ return new Array(); }
Warum sollte man auf solchen "Sugar" verzichten, nur weil viele nicht wissen, wie der || -Operator funktioniert? Der funktioniert überall gleich in JavaScript (auch JS), entsprechend der ECMAScript Spezifikation.
Dann wird beim ersten Aufruf auch noch die while-Schleife gar nicht ausgeführt, d.h. der erste Rekursionsschritt tut erstmal nichts.
Das ist doch kein Rekursionsschritt, denn wenn die erste übergebene Zahl bereits einstellig ist, passiert wirklich nichts: Sie wird direkt zurückgegeben. Willst du denn auf eine Zahl <10 noch irgendwelche Rechenoperationen anwenden, bevor du merkst, dass du schon lange am Ziel bist?
Du hast einen Parameter a, der nur für interne Zwecke dient.
Genau, möchte nicht wissen, wieviele Variablen du für deine mathematischen Operationen brauchst. Mir reichen insgesamt 2.
Und noch etwas: Der vermeintliche Zeitgewinn mit nur Zahlen ist in JavaScript nicht besonders groß, wenn es um Integer-Werte geht, wie in diesem Fall. JavaScript kennt nämlich überhaupt kein Integer, sondern nur 32Bit Floatingpoint. D.h. auch das Rechnen mit ganzen Zahlen passiert intern immer im Floatingpoint-Format.
Nene, tut mir Leid ;-) aber das ist meiner Meinung eher die uneleganteste genannte Lösung.
Wir haben halt unterschiedliche Vorstellungen von Eleganz. Was du meinst ist Schnelligkeit, Effizienz zur Laufzeit oder was immer. Ich dagegen meine Übersichtlichkeit u. Schlankheit im Code. Rekursion frisst immer etwas mehr Speicher usw., ist aber eben eleganter, weil derselbe Code einfach wiederverwendet werden kann.
Gruß, Don P