Quando (x == x + 2)? [fechadas]


90

O desafio: defina de xforma que a expressão (x == x+2)seja avaliada como verdadeira.

Marquei a pergunta com C, mas as respostas em outros idiomas são bem-vindas, desde que sejam criativas ou destacem um aspecto interessante do idioma.

Pretendo aceitar uma solução C, mas outros idiomas podem obter meu voto.

  1. Correto - funciona em implementações compatíveis com padrão. Exceção - supor que uma implementação dos tipos básicos, se for uma implementação comum (por exemplo, supondo que into complemento de 32 bits 2) esteja OK.
  2. Simples - deve ser pequeno, use os recursos básicos da linguagem.
  3. Interessante - é subjetivo, admito. Tenho alguns exemplos para o que considero interessante, mas não quero dar dicas. Atualização : Evitar o pré-processador é interessante.
  4. Rápido - A primeira boa resposta será aceita.

Depois de obter 60 respostas (nunca esperei essa antecipação), pode ser bom resumi-las.

As 60 respostas se dividem em 7 grupos, 3 dos quais podem ser implementados em C, o restante em outros idiomas:

  1. O pré-processador C. #define x 2|0foi sugerido, mas existem muitas outras possibilidades.
  2. Ponto flutuante. Grandes números, infinito ou NaN, todos funcionam.
  3. Ponteiro aritmético. Um ponteiro para uma estrutura enorme causa a adição de 2 para contornar.

    O resto não funciona com C:

  4. Sobrecarga de operador - Um +que não adiciona ou ==que sempre retorna verdadeiro.
  5. Fazendo xuma chamada de função (alguns idiomas permitem isso sem a x()sintaxe). Em seguida, ele pode retornar outra coisa a cada vez.
  6. Um tipo de dados de um bit. Então x == x+2 (mod 2).
  7. Mudando 2- algum idioma permite atribuir 0a ele.

29
Por que 4. Quick? Você quer dizer "Quem conhece um e tem a sorte de ler esta pergunta primeiro"?
Luc

6
@ugoren Deixe a votação da comunidade (e votar-se para que você gosta), em seguida, escolher a resposta topo após 7 dias ou mais :)
Luc

3
Em relação à possibilidade 2: NaN não funciona. NaN + 2 é novamente NaN, mas NaN == NaN é falso.
Martin B

2
A solução Scala, onde x é um conjunto que contém '2' e + significa add to Setpela biblioteca padrão, sem +se redefinir , não se encaixa nessas 7 categorias, IMHO.
usuário desconhecido

2
Por que esta pergunta e todas as respostas ao Wiki da comunidade?
Mbomb007

Respostas:


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

Saídas 1.

Link: http://ideone.com/dL6A5


7
float x=1./0é um pouco mais curto e talvez mais elegante. Mas, enfim, essa certamente é a primeira boa resposta.
precisa saber é o seguinte

1
Ahh bom e velho dividir por zero. Isso me levou mais tempo para descobrir do que eu gostaria de admitir. haha
Grant

Argh, eu também pensei nisso, mas no Windows não é compilado, então eu o larguei. :( +1
Tudor

x = 1e999 é outra maneira de fazer isso.
shiona 8/09/12

4
@shiona float x=1e20seria suficiente
l0n3sh4rk

125

Fortran IV:

2=0

Depois disso, todas as constantes 2 do programa são zero. Confie em mim, eu fiz isso (ok, há 25 anos)


23
Mais uma razão para eu nunca tocar em Fortran.
C0deH4cker

3
Pelo menos lança um aviso?
Michael Stern

15
@MichaelStern AVISO: VOCÊ ESTÁ MUDANDO O VALOR DE 2!
Cruncher

100

Isso parece funcionar:

#define x 2|0

Basicamente, a expressão é expandida para (2|0 == 2|(0+2)). É um bom exemplo de por que se deve usar parênteses ao definir macros.


3
Certamente funciona, e acho que é a solução mais elegante baseada em pré-processador. Mas acho que fazê-lo sem o pré-processador é mais interessante.
precisa saber é o seguinte

Sou apenas eu ou deveria 2|(0+2)ser 1?
phunehehe

1
@phunehehe: |é bit a bit OR ; ||é OR lógico.
PleaseStand

20
De alguma forma, isso me lembra as pequenas mesas de Bobby.
Vsz 05/05

1
@rakeshNS: adicionei o conjunto extra de parênteses para mostrar a precedência do operador . Por isso eu disse "Basicamente".
usar o seguinte código

79

Brainfuck

x

É claro que isso se alonga um pouco "avalia como verdadeiro", porque no Brainfuck nada avalia de fato - você apenas manipula uma fita. Mas se você agora anexar sua expressão

x
(x == x+2)

o programa é equivalente a

+

(porque tudo, mas <>+-[],.é um comentário). O que não faz nada além de incrementar o valor onde estamos agora. A fita é inicializada com todos os zeros, então terminamos com um 1 na posição do cursor, que significa "true": se agora começássemos uma seção condicional com [], ela entraria / faria um loop.


12
+1 deve ser a flexão mais criativa das regras.
Ninjalj 18/11/2012

3
Por que você precisa do x?
James

3
@ James A pergunta diz para definir xentão aqui xé definido como x.
user80551

1
@ James a resposta não faz neednada exceto o+
Cruncher

56

F #

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

13
Eu gosto deste. Em vez de números de malabarismo, basta redefinir o significado de ==
evilcandybag

4
Espere, o operador de igualdade no F # não é simplesmente =? ==nem é definido por padrão.
Jwosty

50

C

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

Nota: pode não funcionar se FLT_EVAL_METHOD != 0(veja os comentários abaixo).


24
+1 para aplicativos do mundo real. Muitas pessoas não entendem a matemática de ponto flutuante.
Tim S.

1
@ mbomb007: Eu acho que eles são diferentes - a resposta para a qual você vincula depende INF + 2 == INF, enquanto a minha resposta usa um único flutuador de precisão que é grande o suficiente para que 2 seja menor que um ULP.
Paul R

2
@ mbomb007: Eu também acho que eles são muito diferentes - ∞ + 2 = ∞é algo que qualquer um pode entender e não depende de nada específico do computador, enquanto adicionar 2 a um número concreto e não ter nenhum efeito é um pouco mais surpreendente e específico da precisão limitada de computadores e IMHO mais interessante
GoatInTheMachine 30/11/16

1
Isso pode falhar facilmente quando FLT_EVAL_METHOD == 1a matemática é feita como double. Recomendar a um valor FP maior certeza superar até mesmo long doublede precisão como1.0e37f
Chux

1
@chux: obrigado pela confirmação - é definitivamente algo que talvez eu deva prestar atenção no futuro, pois grande parte do meu código acaba sendo 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); }
}

Não é um shortie, mas um pouco elegante.

http://ideone.com/x56Ul


4
Dang-lo, acabou de receber um emblema 'Resposta agradável' para este post. Sério, recebendo crachás para coisas MAU ?! Não faça isso em casa !
precisa saber é

É mau, mas é tão bonito ...
Kevin

32

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


Haskell: Defina ℤ / 2ℤ no eans Bool:

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

então, para qualquer um x :: Boolque tivermos x == x + 2.

Atualização: obrigado pelas ideias em comentário, atualizei a instância de acordo.


3
Você pode simplificar:fromInteger = odd
Rotsor 8/09/12

1
Também (+)pode ser definido como (/=)eu acredito.
MatrixFrog

2
A solução mais curta seria criar uma instância para ().
Thomas Eding

31

Pitão

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

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

Agradável. Todos os idiomas que suportam sobrecarga do operador podem usar soluções semelhantes, mas C não é um deles.
ugoren 6/09/12

Também trabalha com sobrecarga __cmp__como class X(int):__cmp__=lambda*x:0(ou __eq__embora ligeiramente mais longoclass X(int):__eq__=lambda*x:True
dr jimbob

Algumas personagens mais curto, se você não se estendem desde int ..class X:__add__=lambda s,o:s
Doboy

Posso perguntar o que essa multiplicação faz?
seequ

2
@TheRare não é realmente multiplicação. Como __add__normalmente são fornecidos vários argumentos ( lambda x,y:), eu salvo alguns caracteres usando * para compactar todos os argumentos em uma tupla ( lambda *y:). Veja os documentos para mais informações.
grc

31

O GNU C suporta estruturas sem membros e tamanho 0:

struct {} *x = 0;

2
Muito agradável! Pensei na aritmética de ponteiros com dados muito grandes, levando a envolventes, mas não pensei no contrário.
precisa saber é o seguinte

26

PHP:

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

Ou:

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

Resultado:

bool (true)


1
Na verdade, eu estava tentando criar essa resposta PHP simples, mas você me venceu.
precisa saber é o seguinte

25

É um equívoco comum que, em C, espaço em branco não importe. Não posso imaginar que alguém não tenha sugerido isso no 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;
}

Imprime 1.


Bom, embora talvez não seja tecnicamente válido ( x == x+2ainda é falso). Mas depois que você traz a ideia, acho que #define x -2*__LINE__é mais elegante.
Ugoren

3
@ugoren thanks! Se você deseja que tudo isso esteja em uma linha, use COUNTER em vez de LINE - requer o GCC 4.3+.
H2CO3

1
_CATé um identificador reservado. Qualquer coisa que começa com sublinhado e letra maiúscula é reservado em C.
Konrad Borowski

@xfix exatamente, atualizado para remover o UB.
H2CO3 22/02

20

C

É mais interessante sem usar macros e sem abusar do 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);

Experimente se você não acredita!


1
0. Não, ainda não acredito nisso.
MSalters

@MSalters: Qual compilador você usa? Você pode ter os trigramas desativados.
vsz 7/09/12

VS2010. É bem possível que os trigrafs estejam desativados por padrão. Ou isso, ou linha de concatenação não funciona com??\
MSalters

MSalters: o trigraph ??\ deve ser convertido em um único \ , portanto não existe ??\ . Alguns compiladores modernos, no entanto, emitem avisos por padrão para trigrafs e concatenações de linha, mesmo se ativados.
vsz 10/09/12

18

Mathematica:

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

Eu acho que essa solução é nova porque usa o conceito de Up Values do Mathematica .

EDITAR:

Estou expandindo minha resposta para explicar o que Up Values ​​significa no Mathematica .

A primeira linha redefine essencialmente a adição do símbolo x. Eu poderia armazenar diretamente essa definição na função global associada ao +símbolo, mas essa redefinição seria perigosa porque a redefinição pode se propagar imprevisivelmente através dos algoritmos internos do Mathematica .

Em vez disso, usando a tag x/:, associei a definição ao símbolo x. Agora, sempre que o Mathematica vê o símbolo x, ele verifica se está sendo operado pelo operador de adição +em um padrão da forma em x + 2 + ___que o símbolo ___significa uma possível sequência nula de outros símbolos.

Essa redefinição é muito específica e utiliza os extensos recursos de correspondência de padrões do Mathematica . Por exemplo, a expressão x+y+2retorna x+y, mas a expressão x+3retorna x+3; porque no primeiro caso, o padrão poderia ser correspondido, mas no último caso, o padrão não poderia ser correspondido sem simplificação adicional.


1
Eu acho que você deveria explicar o que faz. A maioria das pessoas não conhece o Mathematica (ou o que são os valores ascendentes).
ugoren 7/09/12

1
Obrigado @ugoren, passo a maior parte do tempo no site do Mathematica Stack Exchange, então esqueci de explicar o que tornava meu exemplo significativo. Fiz uma edição que explica o conceito da forma mais concisa possível.
Carl Morris

17

Javascript:

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

Test Fiddle


2
Você pode usar Infinity, ou -Infinity, e por causa disso, pode usar o atalho de x = 1/0.
ZzzzBov 06/09/12

6
@zzzzBov: Esse é definitivamente um código de golfe melhor. Eu escolhi (99999999999999999 == 99999999999999999+2)porque eu acho que é um pouco mais interessante do que (Infinity == Infinity+2), embora, como o OP diz, "é subjetiva" :)
Briguy37

Este é o único caso do mundo real em que vi uma verificação como essa por um bom motivo (além de enigmas de programação): Uma função da faculdade (baseada em float) estava verificando sua entrada por ser muito grande para ser contada -1e recorrente . A linguagem em si era Python, mas isso realmente não importa nesse caso.
Alfe

5
@NicoBurns não ture :(
ajax333221

2
@NicoBurns, a execução desse código no console produz false; onde quer que você esteja obtendo informações sobre JS, está errado e não deve ser confiável.
ZzzzBov 08/09/12

17

esquema

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

Agradável. O esquema se (x == x + 2)parece com o C, mas significa uma coisa totalmente diferente.
precisa saber é o seguinte

1
Agora faça isso por (= x 2).
Joe Z.

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

@ugoren está definido para fazer isso por este programa. x é simplesmente o nome de uma função aqui. E assim é ==
Cruncher


16

Aqui está uma solução para JavaScript que não explorar as Infinitye -Infinityponta casos de adição de ponto flutuante. Isso não funciona no Internet Explorer 8 e abaixo, nem no modo estrito de ativação do ES5. Eu não chamaria a withdeclaração e os getters de recursos particularmente "avançados".

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

Editado para adicionar: O truque acima também é possível sem o uso withe get, como observado por Andy E em Dicas para jogar golfe em JavaScript e também por jncraton nesta página:

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

Um bom conceito - fazer xuma chamada de função, embora pareça uma leitura variável. Eu assumo a ordem de avaliação da esquerda para a direita, mas tudo bem, pois é especificado em JS (ao contrário de C).
precisa saber é o seguinte

14

O seguinte não é compatível com os padrões C , mas deve funcionar em praticamente qualquer plataforma de 64 bits:

int (*x)[0x2000000000000000];

Ótimo em princípio, mas parece estar implementado errado. xseria incrementado nas etapas de 2 ^ 61, então x + 8seria igual x.
precisa saber é o seguinte

@ugoren, funciona para mim, no Linux com 4 bytes int.
han

Você está absolutamente correto. Perdi o fato de que é uma variedade de int, não char.
precisa saber é o seguinte

10

Sábio:

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

retorna True

Em geral, para GF (2 ** n), é sempre verdade que x = x + 2 para qualquer x

Este não é um bug ou um problema com estouro ou infinito, está realmente correto


1
Mesmo truque funciona com PARI / GP
Hagen von Eitzen

10

Lisp comum

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

É muito fácil quando xnão precisa ser um valor real.


8

APL (Dyalog)

X←1e15
X=X+2

O APL nem sequer tem infinito, apenas os flutuadores não são precisos o suficiente para diferenciar entre 1.000.000.000.000.000e 1.000.000.000.000.002. Esta é, até onde eu sei, a única maneira de fazer isso no APL.


Eu realmente gosto disso porque é a primeira resposta para explorar a precisão de flutuação.
AndrewKS 6/12

1
@ Andrewrew: Na verdade, Paul R foi um pouco mais cedo.
MSalters

8

Perl 6

Estou surpreso por não ver essa solução antes. Enfim, a solução é - e se xfor 0e de 2uma só vez? my \xneste exemplo declara variável sigilless - esta pergunta é sobre x, não no estilo Perl $x. O ?? !!operador é ternário.

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

Mas...

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

xé vários valores de uma vez. xé igual a 0e de 2uma só vez. x + 2é igual a 2e de 4uma só vez. Então, logicamente eles são iguais.


8

Python 2.X (Usando redefinição de números inteiros (em cache))

Notei que todas as respostas python definiram classes que redefinem o +operador. Responderei com uma demonstração ainda mais de baixo nível da flexibilidade do python. (Este é um trecho específico do python2)

Em python, números inteiros são armazenados mais ou menos dessa maneira em C:

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

Isto é, uma estrutura com um size_t, void *e longobjeto, nessa ordem.
Depois que usamos e, portanto, armazenamos em cache um número inteiro, podemos usar o ctypesmódulo python para redefinir esse número inteiro, para que não apenas o faça x == x+2, mas2 == 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

Impressões

True
True

7

Perl

usando uma sub-rotina com efeitos colaterais em uma variável de pacote:

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

Resultado: true!


1
sub x{}"funciona" bem .. (pelo menos na minha 5.10.1), mas eu não consigo descobrir por que ..
mykhal

2
Porque sub x{}retorna undef ou uma lista vazia, os quais são um zero numérico. E x + 2 é analisado como x (+2). perl -MO=Deparserevelaprint "true\n" if x() == x(2);
Perleone

Isso é incrível, @mykhal e @Perleone!
memowe

7

Pitão

explorar a precisão do ponto flutuante torna isso muito simples.

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

Para torná-lo menos específico do sistema, é necessária uma importação extra

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

Isso deve funcionar em outros idiomas também. Isso funciona porque as representações 100000000000000000.0 e 1000000000000000000.0 são exatamente iguais para a máquina, devido à maneira como os pontos flutuantes são representados dentro da máquina. consulte http://en.wikipedia.org/wiki/IEEE_floating_point para obter mais informações.

Portanto, isso funcionará basicamente em qualquer idioma que permita adicionar números inteiros a flutuadores e fazer com que o resultado seja flutuante.


6

Aqui está uma solução para C ++ baseada na sobrecarga do operador. Ele se baseia na conversão implícita de um enumpara um 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;
}

Você pode usar em std::boolalphavez de ?:.
9119 Jon Purdy

5

Eu sei que é um desafio de código ... mas eu joguei. Desculpa.

Ruby - 13 caracteres - solução Infinity

x=1e17;x==x+2

retorna verdadeiro

Ruby - 41 caracteres - Soluções de sobrecarga de operação

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

ou

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

5

Se for bom explorar a questão um pouco, adicionarei um novo Java. O truque certamente não é novo, mas talvez interessante seja possível em 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));
}

E os 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 solução VBScript funciona de maneira semelhante à minha solução JavaScript. Eu não usei um pré-processador, mas a solução 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

Eu ia postar a mesma solução em ruby, até ver a sua - é possível porque os dois idiomas permitem a omissão dos parênteses.
waldrumpus
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.