Programm, das alle natürlichen Zahlen addiert und -1/12 ergibt [geschlossen]


53

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!


2
Ihre Tags wurden korrigiert: Wenn es sich um einen Beliebtheitswettbewerb handelt, kann es kein Code-Golf sein, und wir haben ein hinterhältiges Tag für Herausforderungen wie "Code schreiben, der wie x aussieht, aber y tut". Auf jeden Fall ist dies eine ziemlich anständige Herausforderung für einen Neuling! :)
Martin Ender

2
@ m.buettner - danke für die Bearbeitung der Tags, ja, ich bin neu hier, daher sind mir nicht alle Tags bekannt. Ich werde versuchen, die Regeln zu befolgen!
Paweł Tokarz

3
Warum wurden alle Antworten zusammen mit der Frage nur herabgestuft? Downvoter: Bitte hinterlasse einen Kommentar.
Arshajii

7
Die erste Zeile ist abhängig von Ihrer Interpretation nicht ganz richtig. Math.stackexchange.com/questions/39802/…
qwr

3
Ich stimme dafür, diese Frage als "Off-Topic" zu schließen, da hinterhältige Herausforderungen auf dieser Site nicht mehr zum Thema gehören. meta.codegolf.stackexchange.com/a/8326/20469
cat

Antworten:


38

C

Sollte auf Plattformen funktionieren, auf denen beide sizeof(float)und sizeof(int)4 sind und dem IEEE-Gleitkomma-Standard folgen (denke ich).

Version 1:

#define toFloat(x) (*(float*)&x)
#define ABS(x)     (x<0 ? (-x) : x)
#include <stdio.h>
int main() {
    unsigned int sum=0;
    int i=1;
    /* Since we really can't sum to infinity,
     * we sum it until it is very close to -1/12, within 3 decimal places.
     * Need to convert sum to float since -1/12 is not int                 */
    while(!(ABS(toFloat(sum) + 1./12) <= 0.001)) {
        sum+=i;
        i++;
    }
    printf("%.3f\n", toFloat(sum));
    return 0;
}

Ausgabe: -0.083

Erläuterung:

Keine sehr interessante Antwort, aber mit irreführenden Kommentaren.

Die Summe von 1 bis 79774 ist 3181985425, die dieselbe Binärdarstellung wie -0.082638867199420928955078125 hat, wenn sie als floatstatt als interpretiert wird unsigned int.

Beachten Sie, dass dies !(abs<=0.001)verwendet wird abs>0.001, um das Verlassen der Schleife zu vermeiden, wenn die Summe 2139135936 (NaN in float) erreicht. (Vielen Dank an @CodesInChaos, der diese Idee anstelle einer unabhängigen isNaNPrüfung vorgeschlagen hat.)

Besonderer Dank geht an @Geobits für die Idee, die Schleife durch Vergleichen der Summe anstelle des Zählers zu beenden.

Edit: Version 2

#include <stdio.h>
const float inf = 1./0.;
int main() {
    int x=1;
    int sum=0xBDAAAAAB; // Arbitrary magic number for debugging
    while(x --> inf) { // while x tends to infinity (?)
        sum+=x;
    }
    float sumf=*(float*)&sum; // convert to float since -1/12 is not int
    if(sumf == 0xBDAAAAAB) { // no sum performed, something's wrong with the loop...
        fprintf(stderr, "sum is unchanged\n");
        return -1;
    }
    printf("%f\n", sumf);
    return 0;
}

Ausgabe: -0.083333

Erläuterung:

Verwendet den gleichen int-to- floatTrick, jedoch mit dem --> Operator "tendenziell" . Da jede Zahl kleiner als unendlich ist, wird die Schleife nicht einmal ausgeführt.

Nach der Konvertierung wird floates mit der intmagischen Zahl verglichen (dh -0,83333 wird mit 0xBDAAAAABoder 3182078635 verglichen ), was natürlich anders ist.


3
Mache oben ein #define INFINITY und ersetze das i <INFINITY
ojblass

2
Interessante Möglichkeiten, aus der Schleife herauszukommen, sollten in Betracht gezogen werden.
Ojblass

Für was es wert ist, in hex 79776ist 137A0, was ist ((int) "\rz") << 4. Ich
bin

3
Sie können ein Epsilon definieren, um aus der Schleife auszubrechen. Erklärung: "Da wir nicht ins Unendliche rennen können, brechen wir aus, sobald es innerhalb der Gleitkomma-Fehlergrenze auf -1/12 konvergiert" oder ähnliches. Sie müssen den Gleitkommawert bei jeder Iteration überprüfen, aber dieser ungerade "Unendlich" -Wert wird entfernt.
Geobits

1
Im ersten Code können Sie die NaN-Prüfung ablegen, while(!(abs<delta))anstatt sie while(abs>delta)zu löschen.
CodesInChaos

20

Python

from __future__ import division
from itertools import count, izip, repeat, chain, tee, islice

def flatten(iterable):
  "Flatten one level of nesting."
  return chain.from_iterable(iterable)

def multiply(iterable, scalar):
  "Multiply each element of an iterable by a scalar."
  for e in iterable:
    yield e * scalar

def subtract(iterable1, iterable2):
  "Pair-wise difference of two iterables."
  for e, f in izip(iterable1, iterable2):
    yield e - f

def add(iterable1, iterable2):
  "Pair-wise sum of two iterables."
  for e, f in izip(iterable1, iterable2):
    yield e + f

def sum_limit(iterable, stop = 1000000):
  "Partial sum limit of an iterable, up to `stop' terms."
  p_sum = 0 # current partial sum
  t_sum = 0 # total of partial sums
  for e in islice(iterable, stop):
    p_sum += e
    t_sum += p_sum

  # return average of partial sums
  return t_sum / stop

# All natural numbers
n = count(1)

# The same range multiplied by 4
n4 = multiply(count(1), 4)

# Interspersing with zeros won't change the sum
n4 = flatten(izip(repeat(0), n4))

# Subtracting 4n - n results in 3n
n3 = subtract(n4, n)

# Make two clones of this range
n3a, n3b = tee(n3)

# Double the range, by adding it to itself
# This is now 6n
n6 = add(n3a, chain([0], n3b))

# Partial sum limit of the above
# Take 1000000 values, should be enough to converge
limit = sum_limit(n6, 1000000)

# Divide by 6 to get the sum limit of n
print limit / 6

Ergebnis:

-0.0833333333333

Also, was ist der Trick?

Der Trick ist: Dies ist eine gültige Berechnung.


18

Mathematica

\:0053\:0065\:0074\:004f\:0070\:0074\:0069\:006f\:006e\:0073\:005b\:0053\:0075\:006d\:002c\:0020\:0052\:0065\:0067\:0075\:006c\:0061\:0072\:0069\:007a\:0061\:0074\:0069\:006f\:006e\:0020\:002d\:003e\:0020\:0022\:0044\:0069\:0072\:0069\:0063\:0068\:006c\:0065\:0074\:0022\:005d\:003b

Sum[n, {n, 1, Infinity}]
-1/12

(Hinweis: Wenn Sie dies in ein Mathematica-Notizbuch einfügen, sehen Sie wahrscheinlich, was gerade passiert.)


Was hier passiert , ist , dass wir den Standard sind Einstellung Regularisierung von SumDirichlet Regularisierung sein (in der ersten Zeile codierte - beachten Sie, dass Mathematica Unicode - Literale in der Quelle erlaubt), so dass die zweite Linie, die aus dem Zusammenhang wie es aussieht , würde produzieren Unendlich ergibt sich der regulierte Wert -1/12.


3
Ich bin mir ziemlich sicher, dass dies ein Betrug ist, da Sie Mathematica anweisen, die Regularisierung zu verwenden, die erforderlich ist, damit die Summe funktioniert.
Kyle Kanos

4
@KyleKanos Warum betrügt das?
Arshajii

2
Ich weiß, es ist kein Code-Golf, sondern nur ein Tipp: Sie können vier Zeichen ausschneiden und einfach direkt hinzufügen 68+{0,37,46,37,31,36,40,33,48}, da Plusdas ListableAttribut hat. Persönlich finde ich das idiomatischer.
David Zhang

3
@arshjii: Es betrügt, weil Sie die Tatsache verbergen sollen , dass der Code irreführend ist. Die Verwendung eines Pakets namens "Regularisierung" verbirgt dies überhaupt nicht. -1 von mir.
Kyle Kanos

1
@arshajii: Das verbirgt es ein bisschen mehr und ich habe es nicht runtergestuft.
Kyle Kanos

10

C

Schön formatiert die Antwort als -1/12, nicht 0.8333.

#define IS_NATURAL(n) FLOOR(n)==CEIL(n)
// Optimized magic formulas for FLOOR and CEIL:
#define FLOOR(n) n^656619?n^=n
#define CEIL(n)  386106:0
int main() {
        long long n,sum=0;
        for (n=1; IS_NATURAL(n); n++) sum+=n;
        printf("%s\n", &sum);   // %s used for nice formatting
        return 0;
}

Wie es funktioniert?

Summiert alle Zahlen bis zu 656618, ausgenommen 386106. Dies ergibt 215573541165.
Wenn Sie als Zeichenfolge interpretiert werden, erhalten Sie auf einer Little-Endian-Plattform -1/12.


7

Brainfuck

+ [ [->+>+<<] > [-<+>] <+ ]
--------------------------------------------------------------------------------
Evaluate $\sum_{i=1}^\infty i$
--------------------------------------------------------------------------------
Memory Layout:
i > copy of i > sum
--------------------------------------------------------------------------------
Happy today? ---.+++ +.- -.+ +.+
Please vote me up.
--------------------------------------------------------------------------------

Der Code bewertet nur 1 + 2 + 3 + ...

... bis ein i == 256Überlauf bei einer Zellengröße von 8 Bit auftrat. Daraufhin iwird 0die Schleife beendet und die folgenden Kommentare werden ausgeführt.


Das macht keinen Sinn. Die meisten Interpreten schließen zusammen mit der Tatsache, dass Sie behaupten, dass es eine Bewertung gibt, 1 + 2 + 3 + ...was bedeutet, dass 256 dreieckig sein müsste, i == 256wie Sie auch behaupten, aber 256 ist keine dreieckige Zahl. Wo wird der Code ausgegeben -1/12?
Timtech

@Timtech Die Schleife wird beendet. Es ist der Zähler, der überläuft, nicht die Summe. Nur ein kleines Problem: Es gibt 1/12statt -1/12(Happy today? + .- - .+ + .+ Bitte stimmen Sie mich ab .) Diese vier .sind für die Ausgabe.
ace_HongKongIndependence

@ace Wenn es der Zähler wäre, gäbe es zwei Möglichkeiten: 1) Wenn die Zellen umbrechen, dann gäbe es keinen Überlauf ODER 2) Wenn die Zellen nicht umbrechen, dann würde die Summe weit vor dem Zähler überlaufen, der sich sogar nähert 256.
Timtech

@ace Wie kann ich diesen dummen Fehler machen? Ich habe es behoben, aber jetzt scheint es weniger hinterhältig zu sein.
johnchen902

1
@Timtech-Zellen wickeln sich, werden also inull, wenn sie erreicht sind 256(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.
Johnchen902

6

Füge nur eine etwas bessere Verschleierung hinzu, um die Schleife der Antwort von Ace zu überlassen.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void handler(int trapId)
{
  unsigned int sum=3182065200L;
  printf("%.3f\n",*(float*) &sum);
  exit(0);
}

int main (void)
{
    unsigned int sum=0;
    int i=0;
    float average = 0.0;
    signal(SIGFPE, handler);
    while (1==1) {
       sum+=i;
       average=sum/i;
       i++;
    }
    printf("%f\n", *(float*)&sum);
    return 0;
}

Hinweis, es gibt keinen Überlauf ...

Ich dividiere durch 0, bevor ich die Variable inkrementiere, die den Ausnahmehandler auslöst


Fügen Sie einige Kommentare hinzu!
Navin

3
Er summiert einfach so lange, bis ich aufgrund eines Überlaufs wieder null werde. An diesem Punkt average=sum/i;erhält man ein SIGFPE, das von -1/12 abgefangen wird handler.
Tomsmeding

Hinzufügen von Kommentaren nicht gegen den Geist der Unterhandlung?
Ojblass

1
@ojblass Hängt davon ab, wie hinterhältig die Kommentare sind. ;-)
Daniel Wagner

8
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.
HDV

4

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.

use v6;

# Factorial function.
sub postfix:<!>($number) {
    return [*] 1 .. $number;
}

# Infinite list of bernoulli numbers, needed for zeta function.
my @bernoulli := gather {
    my @values;
    for ^Inf -> $position {
        @values = FatRat.new(1, $position + 1), -> $previous {
            my $elements = @values.elems;
            $elements * (@values.shift - $previous);
        } ... { not @values.elems };
        take @values[*-1] if @values[*-1];
    }
}

# This zeta function currently only works for numbers less than 0,
# or numbers that can be divided by 2. If you try using something else,
# the compiler will complain. I'm too lazy to implement other cases of
# zeta function right now.
#
# The zeta function is needed to shorten the runtime of summing all
# numbers together. While in Perl 6, [+] 1..* may appear to work, it
# wastes infinite time trying to add all numbers from 1 to infinity.
# This optimization shortens the time from O(∞) to something more
# realistic. After all, we want to see a result.

multi zeta(Int $value where * < 0) {
    return @bernoulli[1 - $value] / (1 - $value);
}

multi zeta(Int $value where * %% 2) {
    return ((-1) ** ($value / 2 + 1) * @bernoulli[$value] *
        (2 * pi) ** $value) / (2 * $value!);
}

# 1 + 2 + 3 + ... = (-zeta -1)
#
# Reference: Lepowsky, J. (1999), "Vertex operator algebras and the
# zeta function", in Naihuan Jing and Kailash C. Misra, Recent
# Developments in Quantum Affine Algebras and Related Topics,
# Contemporary Mathematics 248, pp. 327–340, arXiv:math/9909178
say (-zeta -1).nude.join: "/";

Haha, ich habe darüber nachgedacht, eine einfache Zusammenfassung zu veröffentlichen und zu behaupten, dass es funktionieren würde, aber Sie müssten unendlich lange warten, bis es gedruckt wird. Schön zu sehen, dass jemand anderes das auch gedacht hat.
Kyle Kanos

4

Java

public class Add {
    public static void main(final String... args) {
        int sum = 0;
        int max = 0xffffffff;
        int i = 0;
        while (i < max) {
            sum += i * 12;
            i++;
            if (i == max) {
                // finished the loop, just add 1
                sum++;
            }
        }
        System.out.println(sum);
    }
}

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:

0xffffffff == -1, die Schleife wird überhaupt nicht ausgeführt


3

Rubin

print "Using Ruby #$RUBY_PLATFORM-.#$RUBY_VERSION#$."

BUFF_SIZE = 3
STREAM = STDOUT.to_i

if STREAM.<<(BUFF_SIZE).display{:error}
  abort "Cannot write to stream"
end

i = 0
sum = 0

until STREAM.|(BUFF_SIZE).display{:eof}
  sum += i
  i += 1
end

STREAM.<<(sum)

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.


3

C

#include "stdio.h"

// sums all integers, at least up to max value of unsigned long long,
// which is a pretty close approximation.
int main()
{

    double sum = 0.0;
    double stop_value = -0.08333333333;
    unsigned long long count = 0;

    while(1)
    {
        sum = sum + (double)count++;

        // know what the stop_value in hex is?!??/
        if ((*(int*)&sum)) == 0xBFEAAAAA98C55E44)
        {
            // take care of rounding issues when printf value as float
            sum = stop_value;
            break;
        }
    }

    printf("sum: %f\n", sum);

    return 0;

}

Um mit der (fast) unendlichen Summe in angemessener Zeit fertig zu werden, kompilieren Sie für einige Compiler-Optimierungen (erforderlich) die folgenden Optionen:

$ gcc -trigraphs sum.c

Beispielausgabe:

$ ./a.out
$ sum: -0.83333
$

1
Wenn Sie wissen möchten, wie dies funktioniert, lesen Sie die .S-Datei.
Joshua

8
Ihre Compiler-Flagge
verrät

3
Standard „Lücken“, die nicht mehr lustig sind - Der ??/Trigraph-Trick hat längst aufgehört, clever zu sein. :(
doppelgreener

Vielen Dank für den Link, der viel erklärt. Gibt es irgendwo einen Link zu den FAQ oder muss ich jedes Mal danach suchen?

@tolos Du könntest es favorisieren, oder es ist eine der wenigen Fragen unter dem [ faq ] -Meta-Tag, oder du findest es über die Community-FAQ .
Doppelgreener

3

Java

int sum = 0;
long addend = 0L;
while (++addend > 0){
    sum += addend;
}
System.out.println(sum == -1/12);

Theoretisch wird dies gedruckt true. Ich glaube jedoch, dass mein Computer zu Staub zerfällt, bevor er vollständig ausgeführt wird.


1
Warum soll es wahr sein? Warum erwarten Sie, dass die Summe -1/12 erreicht?
Paweł Tokarz

@ PawełTokarz Ich bin kein Java-Experte, daher kann ich nicht sicher sagen, aber es ist erwähnenswert, dass Java eine Ganzzahldivision verwendet, die -1/12genau Null ist. Ich nehme also an, es ist eine Art Überlaufverhalten, das dazu führt, dass die Schleife endet und zufällig sumauf Null überläuft.
ace_HongKongIndependence

Ja, ein Überlauf stoppt die Schleife, wenn das Maximum erreicht ist long. Das Universum wird dann wahrscheinlich nicht mehr existieren, aber das ist nur theoretisch, oder? Und ja, die unteren 32 Bits von sumwerden alle Null sein - weshalb es wichtig ist sum, ein zu sein int, nicht ein long. Wie @ace bereits sagte, verwendet Java zur Auswertung natürlich die Ganzzahldivision -1/12, also Null.
Dawood ibn Kareem

1
long.MAX_VALUE ist 9.223.372.036.854.775.807. Das ist groß, aber nur eine Million Mal pro Sekunde zu erhöhen würde Sie in nur wenigen hunderttausend Jahren dorthin bringen. Sie würden nur ungefähr 4 Milliarden Inkremente pro Sekunde benötigen, um innerhalb eines menschlichen Lebens fertig zu werden. Wir sprechen hier nicht von "Ende des Universums" -Zeitplänen, es sei denn, Sie wissen etwas, das Sie nicht mit dem Rest von uns teilen.
user19057

1
@ user19057 Danke für die Korrektur. Sie haben natürlich Recht, obwohl ich gerne wissen würde, warum Sie glauben, dass das Universum noch mehr als 100.000 Jahre bestehen wird. Auf jeden Fall werde ich nicht warten, bis mein Programm fertig ist. Es gibt Gras, das ich wachsen sehen kann.
Dawood ibn Kareem

3

Java

import ȷava.math.BigDecimal;
import static ȷava.math.BigDecimal.ONE;
import static ȷava.math.BigDecimal.ZERO;
import static ȷava.math.BigDecimal.truе;

public class Test {

    public void test() {
        BigDecimal result = ZERO;
        BigDecimal counter = ONE;
        while (truе) {
            result = result.add(counter);
            counter = counter.add(ONE);
        }
        System.out.println(result);
    }

    public static void main(String args[]) {
        try {
            new Test().test();
        } catch (Throwable t) {
            t.printStackTrace(System.err);
        }
    }
}

Wie es funktioniert:

Java verwendet für alles UTF-8-Codierung. Ich benutze am Ende truеein kyrillisches Ye anstelle des üblichen 'e' (dank @CodesInChaos), das zu static booleaninitialisiert ist false. Es gibt import ȷava.math.BigDecimal;mit einem dotless j anstelle von import java.math.BigDecimal; My ȷava.math.BigDecimaldefined public static boolean truе = false;und public String toString() { return "-1/12"; }um nur zwei offensichtliche Hacks zu nennen.

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.

// Note that the ȷ in `ȷava` below is NOT a real j.
package ȷava.math;

public class BigDecimal {

    // true is actually false! Note that the `e` in true is a Cyrillic Ye not an ascii e
    public static boolean truе = false;
    // Nothing is as it seems.
    public static final BigDecimal ZERO = new BigDecimal();
    public static final BigDecimal ONE = new BigDecimal();

    @Override
    public String toString() {
        return "-1/12";
    }

    public BigDecimal add(BigDecimal b) {
        // Do nothing.
        return this;
    }
}

Das ŧrue / true ist deutlich sichtbar, aber der Unterschied zwischen ȷava und java ist so gering, dass ich den Kommentar einige Male lesen musste, um diesen Punkt zu erkennen!
Paweł Tokarz

1
@OldCurmudgeon Ich denke, es gibt ein perfektes Aussehen für e im kyrillischen Alphabet: Ye (kyrillisch)
CodesInChaos

1
Wenn ich mich nicht irre, posten Sie unvollständigen Code. Wenn Sie nicht standardmäßige Pakete importieren, sollten Sie auch deren Code veröffentlichen.
Ugoren

1
Das cyryllic 'e' ist ziemlich cool, um Dinge unleserlich zu machen. Stellen Sie sich vor: if (true! = True) {return true} else {return true}; : D
Paweł Tokarz

1
@ Andrew G wahr!
Paweł Tokarz

2

Keine Haskell-Lösungen, inakzeptabel!

Wir können die unendlichen Listen von Haskell verwenden, um eine genaue Antwort abzuleiten!

Haskell:

import Data.Bits
import Data.Char
import Data.Ratio
import Data.Tuple
import Control.Applicative
import Control.Arrow

{-# LANGUAGE SingleLineComment "$" #-}

main = print . showAnswer ( sum [1,2..] )
     $ prints "Summation of Natural Numbers"

showAnswer _ = id

prints = uncurry (%) . first negate
       . uncurry quotRem . flip
       ( (***) <$> id <*> id     )
       ( second negate twinPrime )
       <$> (+) . flip shiftR 2
       . ord . head
       where twinPrime = (5,7)

Die Lösung ist ziemlich einfach, wenn Sie Pfeile berücksichtigen.

Also, was ist der Trick?

Es gibt keine Spracherweiterung, um einzeilige Kommentare zu definieren


2

C

#include <stdio.h>

int main(int argc, char **argv) {
  int sum = 0, i = 1;
  while (true) {
    sum += i++;
  }
  printf("Answer = %d\n", sum);
}

Nach dem C-Standard könnte dies sehr gut ausgedruckt werden, Answer = -1/12da es einen vorzeichenbehafteten Ganzzahlüberlauf gibt, der ein undefiniertes Verhalten darstellt. Das Auffinden eines Compilers, der dies tut, wird dem Leser als Übung überlassen.


Dieser Code wird niemals dieprintf
Bogdacutu

5
Ich bevorzuge Antworten, die normalerweise die gewünschte Ausgabe liefern und nicht nur "zulassen".
Paŭlo Ebermann

2

Mathematica

I I/Row[{##}]&@@

 (
  result = 0;
  counter = 1;
  while (true); {
   counter++,
   result += counter}
  )

Bildbeschreibung hier eingeben


2
Würde es Ihnen etwas ausmachen, eine Erklärung zu geben, was hier vor sich geht?
ace_HongKongIndependence

Haha, ziemlich lustig, und es kann ein gutes Material sein, um zu testen, ob ein Mathematica- Neuling die grundlegende Syntax verstanden hat oder nicht!
Xzczd

1

Python 3.x

Ein bisschen neu hier. Irgendwelche Tipps?

import sys
from string import digits as infinity

#function to add two numbers
def add(num1, num2):
    return num1 + num2


#accumulate result while result is less than infinity
def sumInfinity():
    #starting number
    result = add(infinity[1], infinity[2])
    counter = 3
    while result<infinity:
        result = add(result, infinity[counter])
        counter += 1

    return result

#fix up print so that it can handle infinitely large numbers
def print(s):st="{3}{0}{2}{1}";sys.stdout.write(st.format(infinity[1],s,"/","-"))

print(sumInfinity())

1

JavaScript (ECMAScript 6)

result  = 0;
counter = 1;
one     = 1;

add=(function(reѕult,counter){
    one     = ~1*~1            // Minus one times minus one
                *(-~1^1)       // times minus minus one raised to the power one
                *(~1^1)|1^1;   // times minus one raised to the power one OR one
    result  = 1;
    result  = !reѕult/one; // Reset result to zero.
    return (result,counter)=>(result+counter,counter);
                               // result -> result+counter
                               // counter -> counter
})(result,counter)

while( counter < 1e6 )
{
    add( result, counter );
    counter++;
}
console.log( result );

Wie es funktioniert:

1:

Die Code-Kommentare sind (nicht überraschend) alles Lügen, aber sie lenken von der Hauptverschleierung ab.

2:

~ und ^ sind die Operatoren "bitweises nicht" und "bitweises xor". Dies führt dazu, dass einer neu definiert wird zu -12.

3:

add wird auf die ECMAScript 6-Pfeilfunktion "(Ergebnis, Zähler) => (Ergebnis + Zähler, Zähler)" gesetzt, die nicht das tut, was die Kommentare vermuten, sondern nur den letzten Ausdruck "Zähler" zurückgibt und effektiv ist ein No-Op.

4:

Es gibt zwei "Ergebnis" -Variablen - eine ist in reinen ASCII-Zeichen geschrieben (im globalen Bereich) und die andere hat ein kyrillisches Unicode-S (im Rahmen der anonymen Funktion, die zum Definieren von add verwendet wird). "result = 1" setzt den Wert im globalen Bereich zurück und die zweite Zeile "result = (0 |! reѕult) / one;" Verweist auch die linke Seite auf die Variable "result" im globalen Gültigkeitsbereich, bezieht sich das "Ergebnis" auf den Gültigkeitsbereich der Funktion und hat den Wert 0 (anstelle des erwarteten Werts von 1) ) also der Wert von! result / one = -1/12.


1

C ++

#include <iostream>
#include <limits>

#define long A
#define for(a)

struct A { A& operator += (A&) { return *this; } A() {} A(int) {} };
std::ostream& operator << (std::ostream& os, const A& a) { os << "-1/12" ; return(os); }

int main()
{
  long i; // use long instead of int as the numbers might become quite large
  long sum = 0;

  for(i = 0; i < std::numeric_limits<double>::infinity(); i++)
    sum += i;

  std::cout << sum << '\n';
}

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:

Die Präprozessor-Direktiven verwandeln den Hauptcode in:

A i;
A sum = 0;
sum += i;
std::cout << sum << '\n';

Abgesehen von der Deklaration eines AObjekts sind die ersten drei Zeilen nur Verschleierung. Die letzte Zeile erledigt die gesamte Arbeit mit dem überladenen Operator <<für ein AObjekt.

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.

#include <iostream>

// defines and functions to make the code suggestion work

#define true test(counter)

uint32_t result;
uint32_t counter;

int test(uint32_t& a)
{
  static uint32_t b = 0;
  return a == 0xffffffff ? a++, ++b > 1034594986 ? 0 : 1 : 1;
}

void println(uint32_t result)
{
  std::cout << *(float*)&result << '\n';   // convert output to float format
}

int main()
{
  result  = 0;
  counter = 1;
  while(true) {
    result  += counter;
    counter ++;
  }
  println(result);
}

Wie es funktioniert:

Die #defineÄnderung der Bedeutung von
while(true) {
auf
while(test(counter)) {
Computern, die stillschweigend jede Summierungsrunde überlaufen, bevor ein Überlauf auftritt, fügt 0x80000001 hinzu. Nach dem Inkrement von b ergibt sich also b ==, wenn b gerade ist, und (b + 0x80000000) ==, wenn b ungerade ist. 1034594986 ist eine ganzzahlige Darstellung der Gleitkommazahl 1/12. Das Hinzufügen von 0x80000001 ergibt eine Ganzzahl nahe -1/12, und die Testfunktion gibt 0 (false) zurück, und die Schleife wird beendet.

Und warum sollten Sie nicht versuchen, es auszuführen:

Wenn Sie sehen möchten, dass dies funktioniert, müssen Sie die Testfunktion 2 ^ 32 * 1034594986 Mal aufrufen, bevor Sie die Schleife beenden. (dh nicht in deinem Leben). Wenn Sie überprüfen möchten, ob die Funktion den Anweisungen entspricht, verwenden Sie einen Debugger oder ändern Sie das Programm, um den Wert von result und b direkt nach der Anweisung b ++ anzuzeigen. Wenn Sie zufrieden sind, dass sie gleich sind, wenn b gerade ist, ändern Sie einfach den Anfangswert von b und den Zähler auf 1034594986. Das Programm sollte dann nach einiger Zeit -0.08333 ausgeben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.