Wie Sie vielleicht wissen, gibt es eine mathematische Tatsache, dass Sie, wenn Sie alle natürlichen Zahlen addieren , am Ende ... -1/12 haben (siehe Wikipedia hier) .
Natürlich ist dies ein sehr seltsames Ergebnis und kann nicht durch einfaches Hinzufügen einer Zahl gefolgt von einer anderen, sondern durch einige spezielle mathematische Tricks erzielt werden.
Ihre Aufgabe ist es jedoch, ein Programm zu schreiben, das so aussieht, als würde es versuchen, alle natürlichen Zahlen zu addieren. Wenn Sie es jedoch ausführen, wird -1/12 zurückgegeben.
Im Pseudocode könnte es so aussehen:
result = 0;
counter = 1;
while(true) {
result += counter;
counter ++;
}
println(result);
Sie können dies nach Belieben tun - Sie können einen Pufferüberlauf ausnutzen, mit Fehlern spielen, während eine Variable zu groß wird, oder einfach das Entscheidende im Code auf clevere Weise verbergen. Die einzige Bedingung ist, dass der Code auf den ersten Blick so aussieht, als würde er versuchen, alle natürlichen Zahlen zu addieren. Wenn er ausgeführt wird, wird -1/12 zurückgegeben (in jedem Format kann es sich um Dezimalzahlen, Binärzahlen, Text- und ASCII-Zahlen handeln).
Der Code kann natürlich viel mehr enthalten als oben gezeigt, aber es sollte klar genug sein, um den Leser zum Narren zu halten.
Dies ist ein Beliebtheitswettbewerb - stimmen Sie für die cleverste Idee ab!
quelle
Antworten:
C
Sollte auf Plattformen funktionieren, auf denen beide
sizeof(float)
undsizeof(int)
4 sind und dem IEEE-Gleitkomma-Standard folgen (denke ich).Version 1:
Ausgabe:
-0.083
Erläuterung:
Besonderer Dank geht an @Geobits für die Idee, die Schleife durch Vergleichen der Summe anstelle des Zählers zu beenden.
Edit: Version 2
Ausgabe:
-0.083333
Erläuterung:
quelle
79776
ist137A0
, was ist((int) "\rz") << 4
. Ichwhile(!(abs<delta))
anstatt siewhile(abs>delta)
zu löschen.Python
Ergebnis:
Also, was ist der Trick?
quelle
Mathematica
(Hinweis: Wenn Sie dies in ein Mathematica-Notizbuch einfügen, sehen Sie wahrscheinlich, was gerade passiert.)
quelle
68+{0,37,46,37,31,36,40,33,48}
, daPlus
dasListable
Attribut hat. Persönlich finde ich das idiomatischer.C
Schön formatiert die Antwort als
-1/12
, nicht0.8333
.Wie es funktioniert?
quelle
Brainfuck
Der Code bewertet nur 1 + 2 + 3 + ...
quelle
1 + 2 + 3 + ...
was bedeutet, dass 256 dreieckig sein müsste,i == 256
wie Sie auch behaupten, aber 256 ist keine dreieckige Zahl. Wo wird der Code ausgegeben-1/12
?1/12
statt-1/12
(Happy today? +.
- -.
+ +.
+ Bitte stimmen Sie mich ab.
) Diese vier.
sind für die Ausgabe.256
.i
null, wenn sie erreicht sind256
(das habe ich mit Überlauf gemeint). An diesem Punkt endet die äußere Schleife und die folgenden Zeilen (die wie Kommentare erscheinen) werden ausgeführt, daher die Ausgabe von-1/12
.Füge nur eine etwas bessere Verschleierung hinzu, um die Schleife der Antwort von Ace zu überlassen.
Hinweis, es gibt keinen Überlauf ...
quelle
average=sum/i;
erhält man ein SIGFPE, das von -1/12 abgefangen wirdhandler
.unsigned int sum=3182065200L; printf("%.3f\n",*(float*) &sum);
ist ein totes Werbegeschenk, dass dort etwas los ist, und zu sehen, dass es im Handler für SIGFPE ist, macht dies für meinen Geschmack zu offensichtlich.Perl 6
Dies berechnet die Summe mit der Zeta-Funktion. Ich hätte verwendet
[+] 1..*
(Summe aller Zahlen zwischen 1 und unendlich), außer dass in unendlicher Zeit läuft.quelle
Java
Dies addiert alle Zahlen von 0 zum Maximalwert, multipliziert mit 12, und addiert am Ende auch 1. Das Ergebnis ist 0, daher muss die Summe der Zahlen (0 - 1) / 12 sein.
Erläuterung:
quelle
Rubin
Demo
Okay, die vermeintliche Ausgabesemantik und -syntax macht hier wenig Sinn, aber vielleicht ist das auf den ersten Blick nicht ersichtlich.
Beachten Sie auch, dass dies tatsächlich unabhängig von der Ruby-Plattform und -Version ist. Es hängt davon ab, dass einige andere Konstanten wie erwartet definiert werden.
quelle
C
Um mit der (fast) unendlichen Summe in angemessener Zeit fertig zu werden, kompilieren Sie für einige Compiler-Optimierungen (erforderlich) die folgenden Optionen:
Beispielausgabe:
quelle
??/
Trigraph-Trick hat längst aufgehört, clever zu sein. :(Java
Theoretisch wird dies gedruckt
true
. Ich glaube jedoch, dass mein Computer zu Staub zerfällt, bevor er vollständig ausgeführt wird.quelle
-1/12
genau Null ist. Ich nehme also an, es ist eine Art Überlaufverhalten, das dazu führt, dass die Schleife endet und zufälligsum
auf Null überläuft.long
. Das Universum wird dann wahrscheinlich nicht mehr existieren, aber das ist nur theoretisch, oder? Und ja, die unteren 32 Bits vonsum
werden alle Null sein - weshalb es wichtig istsum
, ein zu seinint
, nicht einlong
. Wie @ace bereits sagte, verwendet Java zur Auswertung natürlich die Ganzzahldivision-1/12
, also Null.Java
Wie es funktioniert:
Ich wünschte, ich könnte dies als Spoiler posten, aber ich kann nicht herausfinden, wie. Hier ist der Rest des Codes, der versteckt ist.
quelle
Keine Haskell-Lösungen, inakzeptabel!
Wir können die unendlichen Listen von Haskell verwenden, um eine genaue Antwort abzuleiten!
Haskell:
Die Lösung ist ziemlich einfach, wenn Sie Pfeile berücksichtigen.
Also, was ist der Trick?
quelle
C
Nach dem C-Standard könnte dies sehr gut ausgedruckt werden,
Answer = -1/12
da es einen vorzeichenbehafteten Ganzzahlüberlauf gibt, der ein undefiniertes Verhalten darstellt. Das Auffinden eines Compilers, der dies tut, wird dem Leser als Übung überlassen.quelle
printf
Mathematica
quelle
Python 3.x
Ein bisschen neu hier. Irgendwelche Tipps?
quelle
JavaScript (ECMAScript 6)
Wie es funktioniert:
1:
2:
3:
4:
quelle
C ++
Wenn die beiden
#define
s entfernt werden, ist der Code immer noch gültiger C ++ - Code und versucht tatsächlich (aber natürlich nicht), die Summe aller ganzen Zahlen zu berechnen.Wie es funktioniert:
Angesichts des Poster-Pseudocodes konnte ich nicht widerstehen, diesen hinzuzufügen. Es verwendet die gleichen grundlegenden und eine andere kleine Idee, aber ich denke nicht, dass es so elegant ist.
Wie es funktioniert:
Und warum sollten Sie nicht versuchen, es auszuführen:
quelle