¿Cuándo (x == x + 2)? [cerrado]


90

El desafío: definir xde tal manera que la expresión (x == x+2)se evalúe como verdadera.

Etiqueté la pregunta con C, pero las respuestas en otros idiomas son bienvenidas, siempre que sean creativas o resalten un aspecto interesante del lenguaje.

Tengo la intención de aceptar una solución C, pero otros idiomas pueden obtener mi voto.

  1. Correcto: funciona en implementaciones que cumplen con los estándares. Excepción: asumir una implementación de los tipos básicos, si es una implementación común (por ejemplo, suponiendo que intes un complemento de 32 bits 2) está bien.
  2. Simple: debe ser pequeño, usar funciones básicas del lenguaje.
  3. Interesante, es subjetivo, lo admito. Tengo algunos ejemplos de lo que considero interesante, pero no quiero dar pistas. Actualización : Evitar el preprocesador es interesante.
  4. Rápido: se aceptará la primera buena respuesta.

Después de obtener 60 respuestas (nunca esperé tal anticipación), puede ser bueno resumirlas.

Las 60 respuestas se dividen en 7 grupos, 3 de los cuales se pueden implementar en C, el resto en otros idiomas:

  1. El preprocesador C. #define x 2|0fue sugerido, pero hay muchas otras posibilidades.
  2. Punto flotante. Grandes números, infinito o NaN, todo funciona.
  3. Puntero aritmético. Un puntero a una estructura enorme hace que se agregue 2 para ajustarse.

    El resto no funciona con C:

  4. Sobrecarga del operador: una +que no agrega o una ==que siempre devuelve verdadero.
  5. Realizar xuna llamada de función (algunos idiomas lo permiten sin la x()sintaxis). Entonces puede devolver algo más cada vez.
  6. Un tipo de datos de un bit. Entonces x == x+2 (mod 2).
  7. Cambio 2: algunos idiomas le permiten asignarlo 0.

29
¿Por qué 4. Quick? ¿Quiere decir "Quien conoce uno y tiene la suerte de leer esta pregunta primero"?
Luc

66
@ugoren Deje que la comunidad vote (y vote usted mismo por las que le gusten), luego elija la respuesta principal después de 7 días más o menos :)
Luc

3
En cuanto a la posibilidad 2: NaN no funciona. NaN + 2 es nuevamente NaN, pero NaN == NaN es falso.
Martin B

2
La solución Scala, donde x es un conjunto que contiene '2', y + add to Setpor la biblioteca estándar, sin redefinirse +, no encaja en estas 7 categorías, en mi humilde opinión.
usuario desconocido el

2
¿Por qué esta pregunta y todas las respuestas son Wiki de la comunidad?
mbomb007

Respuestas:


71
main()
{
double x=1.0/0.0;
printf("%d",x==x+2);
}

Salidas 1.

Enlace: http://ideone.com/dL6A5


77
float x=1./0Es un poco más corto y quizás más elegante. Pero de todos modos, esta es seguramente la primera buena respuesta.
ugoren

1
Ah, bueno, viejo divide por cero. Eso me llevó más tiempo de lo que me gustaría admitir. jaja
Grant

Argh, también pensé en esto, pero en Windows no se compila, así que lo dejé caer. :( +1 aunque
Tudor

x = 1e999 es otra forma de hacer esto.
shiona

44
@shiona float x=1e20sería suficiente
l0n3sh4rk

125

Fortran IV:

2=0

Después de esto, cada constante 2 en el programa es cero. Confía en mí, he hecho esto (ok, hace 25 años)


23
Razón de más para que yo nunca toque Fortran.
C0deH4cker

3
¿Al menos arroja una advertencia?
Michael Stern

15
@MichaelStern ADVERTENCIA: ¡ESTÁS CAMBIANDO EL VALOR DE 2!
Cruncher

100

Esto parece funcionar:

#define x 2|0

Básicamente, la expresión se expande a (2|0 == 2|(0+2)). Es un buen ejemplo de por qué uno debería usar paréntesis al definir macros.


3
Ciertamente funciona, y creo que es la solución basada en preprocesador más elegante. Pero creo que hacerlo sin el preprocesador es más interesante.
ugoren

¿Soy solo yo o debería 2|(0+2)serlo 1?
phunehehe

1
@phunehehe: |es bit a bit O ; ||es lógico OR.
favor

20
Esto de alguna manera me recuerda a las pequeñas Bobby Tables.
vsz

1
@rakeshNS: agregué el conjunto adicional de paréntesis para mostrar la precedencia del operador . Por eso dije "Básicamente".
favor

79

Brainfuck

x

Esto, por supuesto, estira un poco "evaluar a verdadero" un poco, porque en Brainfuck nada realmente se evalúa a nada, solo se manipula una cinta. Pero si ahora agregas tu expresión

x
(x == x+2)

el programa es equivalente a

+

(porque todo menos <>+-[],.es un comentario). Lo que no hace más que incrementar el valor donde estamos ahora. La cinta se inicializa con todos los ceros, por lo que terminamos con un 1 en la posición del cursor, lo que significa "verdadero": si ahora comenzamos una sección condicional [], entraría / loop.


12
+1 Debe ser la flexión más creativa de las reglas.
ninjalj

3
¿Por qué necesitas el x?
James

3
@James La pregunta dice definir xasí que aquí xse define como x.
user80551

1
@James la respuesta no hace neednada excepto el+
Cruncher

56

F#

let (==) _ _ = true
let x = 0
x == (x + 2) //true

13
Me gusta este. En lugar de hacer malabares con los números, simplemente redefina el significado de ==
evilcandybag

44
Espera, ¿no es el operador de igualdad en F # simplemente =? ==Ni siquiera está definido por defecto.
Jwosty

50

C

int main() { float x = 1e10; printf("%d\n", x == x + 2); }

Nota: puede no funcionar si FLT_EVAL_METHOD != 0(ver comentarios más abajo).


24
+1 para aplicaciones del mundo real. Demasiadas personas no entienden las matemáticas de coma flotante.
Tim S.

1
@ mbomb007: Creo que son diferentes: la respuesta a la que se vincula depende INF + 2 == INF, mientras que mi respuesta utiliza un único flotador de precisión que es lo suficientemente grande como para que 2 sea menos de un ULP.
Paul R

2
@ mbomb007: También creo que son muy diferentes: ∞ + 2 = ∞es algo que cualquiera podría entender y no depende de nada específico de la computadora, mientras que agregar 2 a un número concreto y no tener efecto es un poco más sorprendente y específico a la precisión limitada de computadoras, y más interesante en mi humilde opinión
GoatInTheMachine

1
Esto puede fallar fácilmente cuando FLT_EVAL_METHOD == 1la matemática se realiza como double. Recomiende un valor FP mayor que seguramente supere incluso la long doubleprecisión como1.0e37f
chux

1
@chux: gracias por la confirmación, definitivamente es algo que debo tener en cuenta en el futuro, ya que gran parte de mi código termina siendo multiplataforma.
Paul R

36

C#

class T {
  static int _x;
  static int X { get { return _x -= 2; } }

  static void Main() { Console.WriteLine(X == X + 2); }
}

No es un shortie, pero algo elegante.

http://ideone.com/x56Ul


44
Maldita sea, acabo de recibir una insignia de 'Buena respuesta' para esta publicación. En serio, ¿conseguir insignias para cosas MALAS? ¡No hagas esto en casa !
fjdumont

Es malvado, pero es tan hermoso ...
Kevin

32

Scala: { val x = Set(2); (x == x + 2) }


Haskell: Define ℤ / 2ℤ en Booleans:

instance Num Bool where
    (+) = (/=)
    (-) = (+)
    (*) = (&&)
    negate = id
    abs    = id
    signum = id
    fromInteger = odd

entonces para cualquiera x :: Booltendremos x == x + 2.

Actualización: Gracias por las ideas en el comentario, actualicé la instancia en consecuencia.


3
Puede simplificar:fromInteger = odd
Rotsor

1
También (+)se puede definir como (/=)creo.
MatrixFrog

2
Una solución más corta sería hacer una instancia para ().
Thomas Eding

31

Pitón

class X(int):__add__=lambda*y:0
x=X()

# Then (x == x+2) == True

Agradable. Todos los lenguajes que admiten la sobrecarga del operador pueden usar soluciones similares, pero C no es una de ellas.
ugoren

También funciona con sobrecarga __cmp__como class X(int):__cmp__=lambda*x:0(o __eq__aunque un poco más largoclass X(int):__eq__=lambda*x:True
dr jimbob

Un par de caracteres más cortos si no se extiende desde int ..class X:__add__=lambda s,o:s
Doboy

¿Puedo preguntar qué hace esa multiplicación?
seequ

2
@TheRare no es en realidad multiplicación. Debido a __add__que normalmente se le dan múltiples argumentos ( lambda x,y:), guardo algunos caracteres usando * para empaquetar todos los argumentos en una tupla ( lambda *y:). Vea los documentos para más información.
grc

31

GNU C admite estructuras sin miembros y tamaño 0:

struct {} *x = 0;

2
¡Muy agradable! Pensé en la aritmética de punteros con datos muy grandes que conducen a una envoltura, pero no pensé en lo contrario.
ugoren

26

PHP:

$x = true;
var_dump($x == $x+2);

O:

var_dump(!($x==$x+2));

Salida:

bool (verdadero)


1
En realidad estaba tratando de llegar a esta respuesta PHP muy simple, pero me ganaste.
favor

25

Es un error común pensar que en C, el espacio en blanco no importa. No puedo imaginar que a alguien no se le haya ocurrido esto en GNU C:

#include <stdio.h>
#define CAT_IMPL(c, d) (c ## d)
#define CAT(c, d) CAT_IMPL(c, d)
#define x CAT(a, __LINE__)

int main()
{
    int a9 = 2, a10 = 0;
    printf("%d\n", x ==
        x + 2);
    return 0;
}

Impresiones 1.


Agradable, aunque quizás no sea técnicamente válido ( x == x+2sigue siendo falso). Pero una vez que planteas la idea, creo que #define x -2*__LINE__es más elegante.
ugoren

3
@ugoren gracias! Si desea que todo esto esté en una línea, use COUNTER en lugar de LINE ; sin embargo, requiere GCC 4.3+.
H2CO3

1
_CATes un identificador reservado. Todo lo que comienza con un guión bajo y una letra mayúscula está reservado en C.
Konrad Borowski

@xfix es exactamente correcto, actualizado para eliminar UB.
H2CO3

20

C

Es más interesante sin usar macros y sin abusar del infinito.

/////////////////////////////////////
// At the beginning                 /
// We assume truth!                 /

int truth = 1;
int x = 42;

/////////////////////////////////////
// Can the truth really be changed??/
truth = (x == x + 2);

/////////////////////////////////////
// The truth cannot be changed!     /
printf("%d",truth);

¡Pruébalo si no lo crees!


1
0. No, todavía no lo creo.
MSalters

@MSalters: ¿Qué compilador usas? Es posible que tenga los trigrafos deshabilitados.
vsz

VS2010. Es muy posible que los trigrafos estén deshabilitados por defecto. O eso o la concatenación de líneas no funciona??\
MSalters

MSalters: el trigraph ??\ se convertirá en un solo \ , por lo que no hay ??\ . Sin embargo, algunos compiladores modernos dan advertencias por defecto tanto a los trigrafos como a las concatenaciones de línea, incluso si están habilitados.
vsz

18

Mathematica:

x /: x + 2 := x
x == x + 2

Creo que esta solución es nueva porque usa el concepto de valores ascendentes de Mathematica .

EDITAR:

Estoy ampliando mi respuesta para explicar qué significan los valores ascendentes en Mathematica .

La primera línea esencialmente redefine la suma del símbolo x. Podría almacenar directamente tal definición en la función global asociada con el +símbolo, pero dicha redefinición sería peligrosa porque la redefinición puede propagarse de manera impredecible a través de los algoritmos integrados de Mathematica .

En cambio, usando la etiqueta x/:, asocié la definición con el símbolo x. Ahora, cuando Mathematica ve el símbolo x, verifica si está siendo operado por el operador de suma +en un patrón de la forma x + 2 + ___en que el símbolo ___significa una posible secuencia nula de otros símbolos.

Esta redefinición es muy específica y utiliza las amplias capacidades de coincidencia de patrones de Mathematica . Por ejemplo, la expresión x+y+2regresa x+y, pero la expresión x+3regresa x+3; porque en el primer caso, el patrón podría coincidir, pero en el último caso, el patrón no podría coincidir sin una simplificación adicional.


1
Creo que deberías explicar lo que hace. La mayoría de las personas no conocen Mathematica (o cuáles son los valores de Up).
ugoren

1
Gracias @ugoren, paso la mayor parte del tiempo en el sitio web de Mathematica Stack Exchange, así que olvidé explicar qué hizo que mi ejemplo tuviera sentido. Hice una edición que explica el concepto tan concisamente como pude.
Carl Morris

17

Javascript:

var x = 99999999999999999;
alert(x == x+2);​

Violín de prueba


2
Podría usar Infinity, o -Infinity, y debido a esto podría usar el acceso directo de x = 1/0.
zzzzBov

66
@zzzzBov: Definitivamente es un mejor código de golf. Elegí (99999999999999999 == 99999999999999999+2)porque creo que es un poco más interesante que (Infinity == Infinity+2), aunque, como dice el OP, "es subjetivo" :)
Briguy37

Este es el único caso del mundo real en el que vi un cheque como este por una buena razón (además de programar acertijos): una función de facultad (basada en flotación) estaba comprobando que su entrada era demasiado grande para ser contada -1y recurrente . El lenguaje en sí era Python, pero eso realmente no importa en este caso.
Alfe

55
@NicoBurns no ture :(
ajax333221

2
@NicoBurns, ejecutar ese código en la consola produce false; donde sea que obtenga esa información sobre JS es incorrecta y no se debe confiar.
zzzzBov

17

esquema

(define == =)
(define (x a b c d) #t)
(x == x + 2)
;=> #t

Agradable. Scheme's se (x == x + 2)parece a C's, pero significa algo totalmente diferente.
ugoren

1
Ahora hazlo por (= x 2).
Joe Z.

(define (x a b c d) #t):)
Cruncher

@ugoren esto se define para hacer esto por este programa. x es simplemente el nombre de una función aquí. Y así es ==
Cruncher


16

Aquí es una solución para JavaScript que no explota a las Infinityy -Infinitylos bordes de los casos, además de coma flotante. Esto no funciona ni en Internet Explorer 8 ni en versiones posteriores, ni en el modo estricto opt-in ES5. No llamaría a la withdeclaración y a los captadores características particularmente "avanzadas".

with ({ $: 0, get x() {return 2 * this.$--;} }) {
    console.log(x == x+2);
}

Editado para agregar: el truco anterior también es posible sin usar withy get, como lo señaló Andy E en Consejos para jugar al golf en JavaScript y también por jncraton en esta página:

var x = { $: 0, valueOf: function(){return 2 * x.$++;} };
console.log(x == x+2);

Un buen concepto: hacer que xsea ​​una llamada de función, aunque parece una lectura variable. Asumo el orden de evaluación de izquierda a derecha, pero está bien ya que se especifica en JS (a diferencia de C).
ugoren

14

Lo siguiente no cumple con los estándares C , pero debería funcionar en casi cualquier plataforma de 64 bits:

int (*x)[0x2000000000000000];

Genial en principio, pero parece implementarse mal. xse incrementaría en pasos de 2 ^ 61, por x + 8lo que sería igual x.
ugoren

@ugoren, funciona para mí, en Linux con 4 bytes int.
han

Estás absolutamente en lo correcto. Extrañé el hecho de que es una variedad de int, no char.
ugoren

10

Sabio:

x=Mod(0,2)
x==x+2

devuelve True

En general para GF (2 ** n) siempre es cierto que x = x + 2 para cualquier x

Esto no es un error o un problema con desbordamiento o infinito, en realidad es correcto


1
El mismo truco funciona con PARI / GP
Hagen von Eitzen

10

Lisp común

* (defmacro x (&rest r) t)
X
* (x == x+2)
T

Es bastante fácil cuando xno tiene que ser un valor real.


8

APL (Dyalog)

X←1e15
X=X+2

APL ni siquiera tiene infinito, es solo que los flotadores no son lo suficientemente precisos como para diferenciar entre 1.000.000.000.000.000y 1.000.000.000.000.002. Esta es, hasta donde yo sé, la única forma de hacer esto en APL.


Realmente me gusta esto porque es la primera respuesta para explotar la precisión de flotación.
AndrewKS

1
@ Andrew: En realidad, Paul R fue un poco antes.
MSalters

8

Perl 6

Me sorprende no ver esta solución antes. De todos modos, la solución es: ¿qué xpasa si es 0y 2a la vez? my \xEn este ejemplo, se declara la variable sin sigilo: esta pregunta se refiere xal estilo Perl, no al estilo Perl $x. El ?? !!operador es ternario.

$ perl6 -e 'my \x = 0|2; say x == x + 2 ?? "YES" !! "NO"'
YES

Pero...

$ perl6 -e 'my \x = 0|2; say x == x + 3 ?? "YES" !! "NO"'
NO

xson múltiples valores a la vez. xes igual 0y 2a la vez. x + 2es igual 2y 4a la vez. Entonces, lógicamente son iguales.


8

Python 2.X (Usando la redefinición de enteros (en caché))

He notado que todas las respuestas de Python tienen clases definidas que redefinen el +operador. Contestaré con una demostración aún más baja de la flexibilidad de Python. (Este es un fragmento específico de python2)

En python, los enteros se almacenan más o menos de esta manera en C:

typedef struct {            // NOTE: Macros have been expanded
    Py_ssize_t ob_refcnt;
    PyTypeObject *ob_type;
    long ob_ival;
} PyIntObject;

Es decir, una estructura con una size_t, void *y longobjeto, en ese orden.
Una vez que usamos, y por lo tanto almacenamos en caché un entero, podemos usar el ctypesmódulo de Python para redefinir ese entero, de modo que no solo lo haga x == x+2, sino2 == 0

import ctypes
two = 2 # This will help us access the address of "2" so that we may change the value

# Recall that the object value is the third variable in the struct. Therefore,
# to change the value, we must offset the address we use by the "sizeof" a 
# size_t and a void pointer
offset = ctypes.sizeof(ctypes.c_size_t) + ctypes.sizeof(ctypes.c_voidp)

# Now we access the ob_ival by creating a C-int from the address of 
# our "two" variable, offset by our offset value.
# Note that id(variable) returns the address of the variable.
ob_ival = ctypes.c_int.from_address(id(two)+offset)

#Now we change the value at that address by changing the value of our int.
ob_ival.value = 0

# Now for the output
x = 1
print x == x+2
print 2 == 0

Huellas dactilares

True
True

7

Perl

usando una subrutina con efectos secundarios en una variable de paquete:

sub x () { $v -= 2 }
print "true!\n" if x == x + 2;

Salida: true!


1
sub x{}"funciona" también ... (al menos en mi 5.10.1), pero no puedo entender por qué ...
mykhal

2
Porque sub x{}devuelve undef o una lista vacía, los cuales son un cero numérico. Y x + 2 se analiza como x (+2). perl -MO=Deparserevelaprint "true\n" if x() == x(2);
Perleone

¡Eso es asombroso, @mykhal y @Perleone!
memowe

7

Pitón

explotar la precisión de coma flotante lo hace muy simple.

>>> x = 100000000000000000.0
>>> (x == x+2)
True

Para hacerlo menos específico del sistema, se requiere una importación adicional

>>> import sys
>>> x = float(sys.maxint + 1)
>>> (x == x+2)
True

Esto también debería funcionar en otros idiomas. Esto funciona porque la representación de 100000000000000000.0 y 100000000000000002.0 son exactamente iguales para la máquina, debido a la forma en que se representan los puntos flotantes dentro de la máquina. ver http://en.wikipedia.org/wiki/IEEE_floating_point para más información.

Entonces, esto básicamente funcionará en cualquier idioma que le permita agregar enteros a flotantes y que el resultado sea flotante.


6

Aquí hay una solución para C ++ basada en la sobrecarga del operador. Se basa en la conversión implícita de an enuma an int.

#include <iostream>

enum X {};
bool operator==(X x, int y)
{
    return true;
}

int main()
{
    X x;
    std::cout << std::boolalpha << (x == x+2) << std::endl;
    return 0;
}

Puedes usar en std::boolalphalugar de ?:.
Jon Purdy

5

Sé que es un desafío de código ... pero lo jugué. Lo siento.

Ruby - 13 caracteres - Solución infinita

x=1e17;x==x+2

devuelve verdadero

Ruby - 41 caracteres - Soluciones de sobrecarga de operaciones

class Fixnum;def + y;0 end end;x=0;x==x+2

o

class A;def self.+ y;A end end;x=A;x==x+2

5

Si está bien explotar un poco la pregunta, entonces agregaré algunos nuevos Java. El truco es seguro que no es nuevo, pero quizás sea interesante que esto sea posible en Java.

static void pleaseDoNotDoThis() throws Exception {
    Field field = Boolean.class.getField("FALSE");
    field.setAccessible(true);
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(null, true);
}

public static void main(String args[]) throws Exception {
    pleaseDoNotDoThis();
    doit(1);
    doit("NO");
    doit(null);
    doit(Math.PI);
}

static void doit(long x) {
    System.out.format("(x == x + 2) = (%d == %d) = %s\n", x, x+2, (x == x + 2));
}

static void doit(String x) {
    System.out.format("(x == x + 2) = (%s == %s) = %s\n", x, x+2, (x == x + 2));
}

static void doit(double x) {
    System.out.format("(x == x + 2) = (%f == %f) = %s\n", x, x+2, (x == x + 2));
}

Y los resultados:

(x == x + 2) = (1 == 3) = true
(x == x + 2) = (NO == NO2) = true
(x == x + 2) = (null == null2) = true
(x == x + 2) = (3,141593 == 5,141593) = true
(x == x + 2) = (Infinity == Infinity) = true

4

Esta solución VBScript funciona de manera similar a mi solución JavaScript. No utilicé un preprocesador pero la solución parece trivial.

y = 0
Function x
x = y
y = -2
End Function

If x = x + 2 Then
    WScript.Echo "True"
Else
    WScript.Echo "False"
End If

Iba a publicar la misma solución en ruby, hasta que vi la suya; es posible porque ambos idiomas permiten omitir los paréntesis.
waldrumpus
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.