Programa que agrega todos los números naturales y rinde -1/12 [cerrado]

53

Como sabrás, existe un hecho matemático divertido de que si sumas todos los números naturales terminas con ... -1/12 (ver Wikipedia aquí) .

Por supuesto, este es un resultado muy extraño y no se puede obtener simplemente agregando un número seguido de otro, sino algunos trucos matemáticos especiales.

Sin embargo, su tarea es escribir un programa, que parece que intenta agregar todos los números naturales, pero cuando lo ejecuta, devuelve -1/12.

En pseudocódigo podría verse así:

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

Puede hacerlo de la forma que desee: puede explotar el desbordamiento del búfer, jugar con errores generados mientras alguna variable se vuelve demasiado grande o simplemente ocultar lo crucial a lo largo del código de alguna manera inteligente. Las únicas condiciones son que el código debe parecer al principio como si intentara agregar todos los números naturales y cuando se ejecuta devuelve -1/12 (en cualquier formato, puede ser decimal, binario, texto, ascii art, lo que sea).

Por supuesto, el código puede contener mucho más de lo que se muestra arriba, pero debe ser lo suficientemente claro como para engañar al lector.

Este es un concurso de popularidad: ¡vota por la idea más inteligente!

Paweł Tokarz
fuente
2
Se corrigieron sus etiquetas: si es un concurso de popularidad, no puede ser code-golf, y tenemos una etiqueta oculta para desafíos como "escribir código que se parece a x pero hace y". De todos modos, ¡este es un desafío bastante decente para un recién llegado! :)
Martin Ender
2
@ m.buettner: gracias por editar etiquetas, sí, soy nuevo aquí, así que no conozco todas las etiquetas. ¡Intentaré seguir las reglas!
Paweł Tokarz
3
¿Por qué se rechazaron todas las respuestas junto con la pregunta? Votante: por favor deja un comentario.
arshajii
77
La primera línea no es del todo cierta, dependiendo de su interpretación math.stackexchange.com/questions/39802/…
qwr
3
Estoy votando para cerrar esta pregunta como fuera de tema porque los desafíos poco claros ya no están en el tema en este sitio. meta.codegolf.stackexchange.com/a/8326/20469
gato

Respuestas:

38

C

En caso de trabajar en plataformas donde ambos sizeof(float)y sizeof(int)son 4 y sigue el estándar de punto flotante IEEE (supongo).

Versión 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;
}

Salida: -0.083

Explicación:

No es una respuesta muy interesante, pero con comentarios engañosos.

La suma de 1 a 79774 es 3181985425, que tiene la misma representación binaria que -0.082638867199420928955078125 cuando se interpreta como un en floatlugar de un unsigned int.

Tenga en cuenta que !(abs<=0.001)se usa en lugar de abs>0.001evitar salir del ciclo cuando la suma alcanza 2139135936 (NaN in float). (Gracias a @CodesInChaos por sugerir esta idea en lugar de una isNaNverificación independiente ).

Un agradecimiento especial a @Geobits por la idea de terminar el ciclo al comparar la suma en lugar del contador.

Editar: Versión 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;
}

Salida: -0.083333

Explicación:

Utiliza la misma int-a- floattruco, pero con la --> "tiende a" operador aquí. Como cada número es menor que infinito, el bucle no se ejecutará ni una sola vez.

Después de convertirlo float, se compara con el intnúmero mágico (es decir, se compara -0.83333 con 0xBDAAAAAB3182078635), que por supuesto es diferente.

ace_HongKongIndependence
fuente
3
haga un #definir INFINITY en la parte superior y reemplace el i <INFINITY
ojblass
2
Deben considerarse formas interesantes de salir del círculo.
2014
Por lo que vale, en hexadecimal 79776es 137A0, que es ((int) "\rz") << 4. No está seguro de lo útil que es, sin embargo
durron597
3
Puede definir un épsilon para salir del bucle. Explicación: "como no podemos correr hasta el infinito, estallaremos una vez que converja en -1/12 dentro del margen de error de coma flotante" o similar. Tendrá que verificar el valor flotante en cada iteración, pero eliminará ese extraño valor de 'infinito'.
Geobits
1
En el primer código que podría usar en while(!(abs<delta))lugar de while(abs>delta)soltar el cheque NaN.
CodesInChaos
20

Pitón

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

Resultado:

-0.0833333333333

Entonces, ¿cuál es el truco?

El truco es: este es un cálculo válido.

primo
fuente
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

(Nota: pegar esto en un cuaderno de Mathematica probablemente revelará lo que está sucediendo).


¿Qué está pasando aquí es que estamos estableciendo el valor predeterminado regularización de Sumser Dirichlet regularización (codificado en la primera línea - nota de que Mathematica permite literales Unicode en su fuente), por lo que la segunda línea, que se ve fuera de contexto como el que produciría infinito, termina produciendo el valor regularizado -1/12.

arshajii
fuente
3
Estoy bastante seguro de que esto es trampa porque le estás diciendo a Mathematica que use la regularización necesaria para que la suma funcione.
Kyle Kanos
44
@KyleKanos ¿Por qué es trampa?
arshajii
2
Sé que no es código golf, sino solo un consejo: puede cortar cuatro caracteres y simplemente agregarlos directamente 68+{0,37,46,37,31,36,40,33,48}, ya que Plustiene el Listableatributo. Personalmente, esto me parece más idiomático.
David Zhang
3
@arshjii: es una trampa porque se supone que debes ocultar el hecho de que el código es engañoso. El uso de un paquete llamado 'regularización' no oculta esto en absoluto. -1 de mi parte.
Kyle Kanos
1
@arshajii: Eso lo oculta un poco más y lo he desestimado.
Kyle Kanos
10

C

Muy bien formatea la respuesta como -1/12, no 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;
}

¿Cómo funciona?

Suma todos los números hasta 656618, excluyendo 386106. Esto da 215573541165.
Cuando se interpreta como una cadena, en una pequeña plataforma endian, obtienes -1/12.

Ugoren
fuente
7

Brainfuck

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

El código solo evalúa 1 + 2 + 3 + ...

... hasta que se i == 256produjo un desbordamiento, suponiendo un tamaño de celda de 8 bits. Luego de eso, se iconvierte 0, el ciclo termina y se ejecutan los siguientes comentarios .

johnchen902
fuente
Esto no tiene sentido. La mayoría de los intérpretes se ajustan, así como el hecho de que usted afirma que evalúa, lo 1 + 2 + 3 + ...que significa que 256 tendría que ser triangular, i == 256como también afirma, pero 256 no es un número triangular. Además, ¿de dónde sale el código -1/12?
Timtech
@Timtech El ciclo termina. Es el contador el que se desborda, no la suma. Solo un pequeño problema: sale en 1/12lugar de -1/12(¿Feliz hoy? + .- - .+ + .+ Por favor, vote por mí .) Estos cuatro .son para la salida.
ace_HongKongIndependence
@ace Si fuera el contador, habría dos opciones: 1) Si las celdas se ajustan, entonces no habría desbordamiento O 2) si las celdas no se ajustan, entonces la suma se desbordaría mucho antes de que el contador se acercara 256.
Timtech
@ace ¿Cómo puedo cometer ese error tonto? Lo arreglé, pero ahora parece menos turbio.
johnchen902
1
@Timtech Cells se ajusta, por lo que se iconvierte en cero cuando llega 256(eso es lo que quise decir con desbordamiento). En este punto, el bucle externo termina y se ejecutan las siguientes líneas (que parecen comentarios), de ahí la salida de -1/12.
johnchen902
6

Solo agrego un poco mejor ofuscación de dejar el bucle a la respuesta de as.

#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;
}

Sugerencia no hay desbordamiento ...

Divido por 0 antes de incrementar la variable que estoy iniciando el controlador de excepciones

ojblass
fuente
Agrega algunos comentarios!
Navin
3
Simplemente sigue sumando hasta que vuelvo a cero de nuevo debido al desbordamiento, en ese punto average=sum/i;da un SIGFPE, capturado handler, imprimiendo -1/12.
tomsmeding
¿No está agregando comentarios contra el espíritu de ser descuidado?
2014
1
@ojblass Depende de qué tan discretos sean los comentarios. ;-)
Daniel Wagner
8
unsigned int sum=3182065200L; printf("%.3f\n",*(float*) &sum);es un obvio que algo está sucediendo allí, y ver que está en el controlador de SIGFPE hace que esto sea demasiado obvio para mis gustos.
hvd
4

Perl 6

Esto calcula la suma usando la función zeta. Hubiera usado [+] 1..*(suma de todos los números entre 1 e infinito), excepto que se ejecuta en tiempo infinito.

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: "/";
Konrad Borowski
fuente
Jaja, estaba pensando en publicar un resumen simple y afirmar que funcionaría, pero tendrías que esperar un tiempo infinito antes de que se imprima. Es bueno ver que alguien más lo pensó también.
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);
    }
}

Esto agrega todos los números desde 0 al valor máximo, multiplicado por 12, y también agrega 1 al final. El resultado es 0, por lo tanto, la suma de los números debe ser (0 - 1) / 12.

Explicación:

0xffffffff == -1, el bucle no se ejecuta en absoluto

aditsu
fuente
3

Rubí

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)

Manifestación

De acuerdo, la supuesta semántica y sintaxis de salida aquí tiene poco sentido, pero tal vez eso no sea aparente a simple vista.

También tenga en cuenta que esto es, de hecho, independiente de Ruby Platform and Version. Depende de que se definan otras constantes como se esperaba.

histocrat
fuente
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;

}

Para tratar la suma (casi) infinita en un período de tiempo razonable, compile con las siguientes opciones para algunas optimizaciones del compilador (obligatorio):

$ gcc -trigraphs sum.c

Salida de muestra:

$ ./a.out
$ sum: -0.83333
$
Cepillo de dientes
fuente
1
Si desea saber cómo funciona esto, lea el archivo .S.
Joshua
8
Su bandera del compilador lo regala todo ...
ace_HongKongIndependence
3
"Lagunas" estándar que ya no son divertidas : el ??/truco del trigrafo hace tiempo que dejó de ser inteligente. :(
doppelgreener
Gracias por el enlace, eso explica mucho. ¿Hay un enlace a las preguntas frecuentes en alguna parte, o tengo que buscarlo cada vez?
@tolos Puede marcarlo como favorito, o es una de las únicas preguntas bajo la etiqueta meta [ faq ], o encontrarlo a través de las Preguntas frecuentes de la comunidad .
doppelgreener
3

Java

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

En teoría, esto se imprimirá true. Sin embargo, creo que mi computadora se desmoronará antes de que termine de funcionar.

Dawood dice que reinstalar a Monica
fuente
1
¿Por qué se supone que es verdad? ¿Por qué esperas que la suma alcance el -1/12?
Paweł Tokarz
@ PawełTokarz No soy un experto en Java, así que no puedo decirlo con certeza, pero vale la pena señalar que, dado que Java usa la división de enteros, -1/12es muy cero. Entonces, ¿supongo que es algún tipo de comportamiento de desbordamiento lo que hace que el ciclo finalice y, por coincidencia, se sumdesborde a cero?
ace_HongKongIndependence
Sí, un desbordamiento hará que el ciclo se detenga cuando llegue al máximo long. El universo probablemente ya no existirá para entonces, pero esto es solo teórico, ¿verdad? Y sí, los 32 bits inferiores sumserán todos cero, por eso es importante sumser un int, no un long. Por supuesto, como ha dicho @ace, Java utiliza la división de enteros para evaluar -1/12, por lo que es cero.
Dawood dice que reinstalará a Monica
1
long.MAX_VALUE es 9.223.372.036.854.775.807. Eso es grande, pero un incremento de solo 1 millón de veces por segundo te llevaría allí en unos pocos cientos de miles de años. Solo necesitaría unos 4 mil millones de incrementos por segundo para terminar dentro de una vida humana. No estamos hablando de escalas de tiempo del "fin del universo", a menos que sepa algo que no está compartiendo con el resto de nosotros.
user19057
1
@ user19057 Gracias por la corrección. Tienes toda la razón, por supuesto, aunque me encantaría saber por qué crees que el universo va a durar más de 100 000 años más. En cualquier caso, no me voy a quedar sentado esperando a que mi programa termine de ejecutarse. Hay hierba para que yo vea crecer.
Dawood dice que reinstalará a Monica
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);
        }
    }
}

Cómo funciona:

Java utiliza la codificación UTF-8 para todo. Lo uso truеcon un Ye cirílico al final en lugar de la 'e' habitual (gracias a @CodesInChaos) que se static booleaninicializa en false. Hay import ȷava.math.BigDecimal;una j sin punto en lugar de import java.math.BigDecimal; My ȷava.math.BigDecimaldefine public static boolean truе = false;y public String toString() { return "-1/12"; }solo dos hacks obvios.

Ojalá pudiera publicar esto como un spoiler, pero no puedo entender cómo. Aquí está el resto del código que está escondido furtivamente.

// 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;
    }
}
OldCurmudgeon
fuente
El ŧrue / true es claramente visible, pero la diferencia entre ȷava y java es tan pequeña que tuve que leer el comentario varias veces para detectar este punto.
Paweł Tokarz
1
@OldCurmudgeon Creo que hay un lookalike perfecto para e en el alfabeto cirílico: Ye (cirílico)
CodesInChaos
1
Si no me equivoco, publicas código incompleto. Si importa paquetes no estándar, también debe publicar su código.
Ugoren
1
La 'e' cíclica es bastante genial para hacer que las cosas sean ilegibles. Imagínese: if (true! = True) {return true} else {return true}; : D
Paweł Tokarz
1
@ Andrew G cierto!
Paweł Tokarz
2

¡Sin soluciones Haskell, inaceptable!

¡Podemos utilizar las infinitas listas de Haskell para obtener una respuesta exacta!

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)

La solución es bastante sencilla cuando tienes en cuenta las flechas ...

Entonces, ¿cuál es el truco?

No hay una extensión de idioma para definir el comentario de una sola línea.

recursion.ninja
fuente
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);
}

Según el estándar C, esto podría imprimirse muy bien, Answer = -1/12ya que habrá un desbordamiento de entero con signo que es un comportamiento indefinido. Encontrar un compilador que haga esto se deja como ejercicio para el lector.

Geoff Reedy
fuente
este código nunca llegará aprintf
Bogdacutu
55
Prefiero respuestas que generalmente producen el resultado requerido, no solo "permitirlo".
Paŭlo Ebermann
2

Mathematica

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

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

ingrese la descripción de la imagen aquí

Simon Woods
fuente
2
¿Te importaría dar una explicación sobre lo que está pasando aquí?
ace_HongKongIndependence
¡Jaja, bastante divertido, y puede ser un buen material para probar si un novato de Mathematica ha entendido la sintaxis básica o no!
xzczd
1

Python 3.x

Un poco nuevo aquí. ¿Algun consejo?

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())
La obesidad
fuente
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 );

Cómo funciona:

1:

Los comentarios del código son (como era de esperar) todas mentiras, pero son una distracción de la ofuscación principal.

2:

~ y ^ son los operadores "bitwise not" y "bitwise xor". Como resultado, uno se redefinió a -12.

3:

add se establece en la función de flecha ECMAScript 6 "(resultado, contador) => (resultado + contador, contador)" que no hace lo que los comentarios sugieren que hace, sino que solo devuelve la última expresión "contador" y es efectivamente un no-op.

4:

Hay dos variables de "resultado": una está escrita en caracteres ASCII puros (en el ámbito global) y la otra tiene un "s" cirílico Unicode (dentro del ámbito de la función anónima utilizada para definir la suma). "resultado = 1" restablece el valor dentro del alcance global y la segunda línea "resultado = (0 |! resultado) / uno;" también tiene el lado izquierdo que se refiere a la variable "resultado" en el alcance global, pero el "resultado" en el lado derecho de la expresión se refiere al alcance de la función y tiene el valor 0 (en lugar del valor esperado de 1 ) por lo que el valor de! reѕult / one = -1/12.

MT0
fuente
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';
}

Si #definese eliminan los dos s, el código seguirá siendo un código C ++ válido e intentará (pero, por supuesto, fallará) calcular la suma de todos los enteros.

Cómo funciona:

Las directivas del preprocesador convierten el código principal en:

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

Además de declarar un Aobjeto, las primeras tres líneas son solo ofuscación. La última línea hace todo el trabajo utilizando el operador sobrecargado <<en un Aobjeto.

Dado el pseudocódigo de los carteles, no pude resistirme a agregar este. Utiliza la misma idea básica y otra pequeña, pero no creo que sea tan elegante.

#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);
}

Cómo funciona:

El #definecambia el sentido de
while(true) {
que
while(test(counter)) {
en las máquinas que ha anegado en silencio cada ronda de la suma antes de un desbordamiento agregará 0x80000001 a resultar. Por lo tanto, después del incremento de b, b == resulta cuando b es par y (b + 0x80000000) == resulta cuando b es impar. 1034594986 es una representación entera del número de coma flotante 1/12. Agregar 0x80000001 a eso dará como resultado un número entero cercano a -1/12 y la función de prueba devolverá 0 (falso) y el bucle terminará.

Y por qué no deberías intentar ejecutarlo:

Si desea ver que se advierta que funciona: la función de prueba debe llamarse 2 ^ 32 * 1034594986 veces antes de finalizar el ciclo. (es decir, no en tu vida). Si desea verificar que la función haga lo que se le indica, use un depurador o cambie el programa para ver el valor del resultado y b justo después de la instrucción b ++. Cuando esté convencido de que son iguales cuando b es incluso, simplemente cambie el valor inicial de b y vaya a 1034594986. El programa debería generar -0.08333 después de un tiempo.

Lars Betak
fuente