Programmierer: Könnt ihr dieses Code-Rätsel lösen?
Ohne es zu googlen natürlich.
In JavaScript. (Falls ihr kein JS könnt ignoriert die Frage einfach.)
x= ...
5 Stimmen
2 Antworten
x=(([]==[])+[])[+(![]==[])]
Ich hatte das schon länger gegoogelt. Ich weiß, dass es kürzere Lösungen gibt. Mein Gedanke hier war, dass zwei Arrays immer ungleich sind, beim Vergleich also immer false rauskommt. Ein false konvertiere ich zu "false" und das andere zu 1.
Auch eine gute Lösung! Daran hätte ich garnicht gedacht, dass die immer unterschiedlich sind, aber stimmt ^^
Ich finde es cool, dass jeder eine andere Lösung hat :D
x = (+[][+[]] + [])[+!![]]
Ich musste googeln, wie type coercions funktionieren, die Idee ist aber von mir:
- +[] ergibt 0
- [][+[]] ergibt undefined
- +[][+[]] ergibt NaN
- +[][+[]] + [] ergibt "NaN" (als String)
- +!![] ergibt 1, damit kann ich den zweiten Buchstaben im String holen
Ohh, sehr Clever ^^
Ich hab das "a" aus "false" geholt haha
Das man einfach ein Plus davor schreiben kann, um ein Boolean zu einer Zahl zu machen wusste ich noch nicht, sehr praktisch, merk ich mir! :D
Deine Lösung kombiniert mit "false" ist ein bisschen kürzer:
x = (![]+[])[+!![]]
Auch eine schöne Lösung :)
Ganz ohne googlen ist das aber wahrscheinlich nicht möglich, oder? Wer weiß schon die ganzen Regeln für type coercions auswendig? Das ist ja auch völlig überflüssig, weil niemand, der auf code quality achtet, davon Gebrauch macht.
Stimmt. Ich hab zwar nicht gegoogelt, aber 5 Minuten rumprobiert. Hab rausgefunden, dass false + true = 1, und dass +[] etwas zu einem String umwandelt. Und jetzt dank dir auch, dass ein Plus vor einem Wahrheitswert diesen zur entsprechenden Zahl ändert.
Werd dieses wissen aber wohl nie brauchen.
Hat zwar nix mit der Aufgabe zu tun, aber was ich mittlerweile gerne hernehme sind x|0 oder ~~x, um eine Zahl zu einem Integer zu runden. Math.floor() ist immer so anstrengend lang. Und natürlich || und && um mehrere Sachen (bedingt) hintereinander auszuführen. Und Strings direkt als Wahrheitswerte (leer = falsch)
Ja, das hat aber auch Nachteile:
- x|0 rundet die Zahl nicht bloß, sondern wandelt die Zahl in einen 32-bit Integer um. Das ist nötig, um bitweise-Operationen damit durchzuführen. Es heißt aber auch, dass es bei Zahlen über 2**31 zu einem integer overflow kommt.
- || und && können nützlich sein, bei manchen Datentypen ist aber Vorsicht geboten. Wenn eine Funktion entweder eine Zahl oder undefined zurückgibt, kannst du damit nicht prüfen, ob das Ergebnis undefined ist, da auch 0 falsy ist. Bei Strings ist es ganz ähnlich, denn ein leerer String ist falsy. Ich bevorzuge daher immer explizite Vergleiche mit ===. Dann ist es einfacher zu verstehen, was der Code macht.
Die einzige Ausnahme ist (x == null). Ich verwende das manchmal statt (x === null || x === undefined).
Da würde ich einfach (!x) schreiben :D
Natürlich nur wenns auch passt, bezogen darauf, was so übergeben werden könnte. Aber in den meisten fällen passt es.
=== wurde mir immer empfohlen, habe ich aber tatsächlich noch nie gebraucht
Ich nutze gerne die Typ-Unsicherheit von JS aus um meinen Code zu verkürzen, das gab selbst bei Programmen mit 5000+ Zeilen Code noch kein Problem.
Wenn man Typsicherheit will sollte man zu TypeScript greifen ist da meine Meinung. Aber deine Vorgehensweise ist natürlich Best Practise, ja.
Ich verwende Typescript bereits. Typescript warnt aber auch nicht immer vor type coercions, daher ist es auch in Typescript sinnvoll, auf guten Code-Stil zu achten und === zu verwenden etc.
So ähnlich hätte ich es auch gelöst. Mit
kann man sich erst "false" zusammenbauen und dann daraus den zweiten Buchstaben holen.