Falácia de prova clássica [fechado]

18

O fundo

Então, todos nós sabemos a prova clássica que é assim:

a = b
a² = ab
a² - b² = ab - b²
(ab) (a + b) = b (ab)
(a + b) = b
b + b = b
2b = b
2 = 1 (Ha ha!)
De claro, o erro é que você não pode dividir por 0. Como a = b, a - b = 0, houve uma divisão oculta por 0.

O desafio

Você precisa replicar essa prova. Primeiro, declare dois números inteiros aeb (não importa como você os chama) iguais. Em seguida, declare aMod e bMod como versões modificáveis ​​de aeb e inicialmente iguais a eeb, respectivamente. Você deve multiplicar os dois por a e subtrair b * b de ambos. Você deve então dividir por a - b e depois dividi-los por b (ou a) para obter. Em seguida, imprima aMod e bMod com um sinal de igual entre eles.

The Underhanded

Obviamente, como você declarou aeb igual a, a - b = 0 e a divisão por 0 causa um erro. Então você deve fingir de forma criativa. Além disso, como você está tentando replicar a prova, o resultado de todas as operações no aMod e no bMod não deve ser igual quando impresso. Eles não precisam ser exatamente 2 e 1, apenas dois números que não são iguais.

Aqui está um exemplo:

#include <iostream>
#define subtract(a, b) a - b

using namespace std;
int main()
{
    int a = 4, b = 4;
    int a_2 = a, b_2 = b;

    a_2 *= a;
    b_2 *= b;

    a_2 -= b * b;
    b_2 -= b * b;

    a_2 = a_2 / subtract(a, b);
    b_2 = b_2 / subtract(-b, -a); // a - b == (-b) - (-a)

    a_2 /= a;
    b_2 /= a;

    cout << a_2 << " = " << b_2 << " because I did the same operations on both of them.";

    return 0;
}

Talvez não seja o melhor, mas ilustra o ponto.

Bônus secreto

Em vez de imprimir o sinal de igual, você pode imprimir apenas as duas variáveis ​​(aMod e bMod) e, em seguida, ter um código que pareça comparar as duas variáveis ​​em termos de igualdade, mas na realidade é que elas são iguais (e imprimem alguma forma de true).

Lembre-se, este é um concurso de popularidade, portanto, o maior número de votos positivos vence.
Além disso, uma nova versão da matemática chamada Matemática 2.0 fez uso de brechas padrão para invalidar automaticamente uma prova.

user155698
fonte
Aqui é um link Wikipedia da prova inválida que as pessoas possam entender melhor
3
Estou votando para encerrar esta questão como fora de tópico, porque os desafios secretos não estão mais no tópico neste site. meta.codegolf.stackexchange.com/a/8326/20469
cat

Respostas:

17

Javascript

var a=3,b=3,a2=3,b2=3
[a2,b2]=[a2*a,b2*a]
[a2,b2]=[a2-b*b,b2-b*b]
[a2,b2]=[a2/(a-b),b2/(a-b)]
console.log([a2/a,b2/a])

Resultado:

[1, NaN]

Observe que 0/0 = NaN

Sugestão

Tente adicionar alguns pontos e vírgulas.
Este programa é realmente var a=3,b=3,a2=3,b2=3[a2,b2]=...=[a2/(a-b),b2/(a-b)];console.log([a2/a,b2/a]).
E o NaN é [3/0,undefined/0]/3.

jimmy23013
fonte
Uau. Isso foi muito inteligente, "acidentalmente", esquecendo-se de adicionar ponto-e-vírgula, tornando (quase) todo o programa uma sentença recorrente.
user155698
3

Python 2

Tenho certeza de que é óbvio, já que todo mundo conhece Python, mas aqui está minha tentativa:

a=b=1
x,y=a*a,a*b
x,y=x-b*b,y-b*b
x,y=a+b/a-b,b
x,y=x/a,y/a
print(x==y)

Ele produz True.

Dica:

Verifique minha divisão.

mbomb007
fonte
já que todo mundo usa Python . Eu conheço python, mas raramente o uso
rpax
@rpax Isso é o que eu quis dizer.
mbomb007
Desculpe, não li corretamente sua resposta.
Rpax 30/07/2015
2

Rubi

def calculate a,
  b = a
  left, right = a, b
  left, right = [left, right].map { |x| x * a     }
  left, right = [left, right].map { |x| x - b*b   }
  left, right = [left, right].map { |x| x / a - b }
  left, right = [left, right].map { |x| x / b     }
  puts $/=[left, right].join(' = ')
end

calculate 3,
STDOUT.write($/)

ideona

Dica:

,

Explicação:

As duas linhas que terminam em vírgulas fazem com que o programa se comporte de maneira diferente. Sem as vírgulas, o método usa um único argumento a, define bigual a a, executa as transformações da prova em cada um (exceto por alguns parênteses ausentes, ele não se divide por 0) e gera o resultado (Com entrada de 3 , ele produzirá "-1 = -1". No entanto, com a vírgula à direita, a b = alinha se torna parte da assinatura do método, o que significa que está declarando um segundo argumento com um valor padrão. A invocação do método no final passa no result of STDOUT.write($/), que é 1 (o número de bytes que ele gravou em STDOUT, já que $/é predefinido para um caractere de nova linha.) Portanto, a é 3 eb é 1, resultando na equação começando como "3 = 1". lixo para fora.

histocrata
fonte
Bom truque lá com suas novas linhas.
LegionMammal978
Você poderia adicionar uma explicação para não-rubiistas?
Kirbyfan64sos
@ kirbyfan64sos Claro, pronto.
histocrat 30/07/2015
2

GolfScript

Atenção: este programa está trapaceando um pouco, pois não imprime aMod e bMod

1nt main(){
  int a = 2, b = 2;
  int aMod,bMod;
//The next line should throw and error, but why doesn't it??/
  aMod = (a*a - b*b) / (a-b);
//The next line should throw and error, but why doesn't it??/
  bMod = (b*a - b*b) / (a-b);
//The if should fail, but it works??/
  if(aMod == bMod)
    printf("1");
  return 0;
};

Experimente aqui !

Então o que está acontecendo?

A primeira coisa que você deve ter notado são os "trigramas proibidos". Mas lembre-se, este é o GolfScript, não o C! Além disso, provavelmente percebeu que na verdade não diz "int main ()", diz "1nt main ()". No GolfScript, o "1" significa pressionar 1 na pilha e o "nt main" é processado como duas variáveis ​​não inicializadas, que não fazem nada. Os dois parênteses primeiro adicionam 1 ao número superior da pilha e depois subtraem um, basicamente cancelando-se. Os colchetes indicam um bloco que é empurrado para a pilha e, em seguida, o ponto-e-vírgula a retira imediatamente. Portanto, no final, temos apenas o "1" original pressionado e, no final de um programa GolfScript, a pilha é impressa. Esta resposta foi inspirada por esta .

K Zhang
fonte
Trígrafos detectados. Ativando o sistema -1 automático. Erro: -1 falhou (4792, RPLS)
CalculatorFeline
Isso é sorrateiro, porque leva você a pensar que não conseguiu enganá-lo. +1
Rɪᴋᴇʀ
1

Prolog

areEqual(A, B) :-
    Amod = A,
    Bmod = B,

    Amod = Amod * A,
    Bmod = Bmod * B,

    Amod = Amod - B*B,
    Bmod = Bmod - B*B,

    Amod = Amod / (A-B),
    Bmod = Bmod / (A-B),

    Amod = Amod / A,
    Bmod = Bmod / A,

    Amod == Bmod.

A saída quando areEqual(4,4)é chamada (ou qualquer outro par de números realmente):

false

Por quê?

No Prolog, o operador "=" não é afetação; é "unificação". Portanto, Amod = Amod * Afalha porque Amodjá foi unificado e A, portanto, não pode ser unificado Amod * A. O Prolog pára imediatamente de executar a regra atual e retorna false.

Fatalizar
fonte
2
Eu acho que deveria ser o contrário, você tem que mostrar "true" quando os dois valores são diferentes, não "false" quando eles são iguais ^^ '#
23415
1

Javascript

//Very badly written code!
//No! It is "poetic" code!
while(true){break;}{ 
let scrollMaxX = 3, screenX = 3;
var scrollBarWithBeerMax = scrollMaxX, Yscroll = screenX; for(var i = 0; i<1; i++){}}

scrollBarWithBeerMax *= scrollMaxX;
Yscroll *= screenX;

scrollBarWithBeerMax -= screenX * screenX;
Yscroll -= screenX * screenX;

scrollBarWithBeerMax /= (scrollMaxX - screenX);
Yscroll /= (scrollMaxX - screenX);

alert(scrollBarWithBeerMax + ' = ' + Yscroll);

Saída:
http://jsbin.com/furino/2/edit?js,output JsBin não parece capaz de executar esse código. Use o console do navegador.

Por quê?

scrollMaxX e screenX já são variáveis ​​existentes. Eles são incorporados no navegador. Assim, o resultado pode variar. A palavra-chave let altera apenas temporariamente seu valor.

Outro JavaScript: ele não segue exatamente as regras, só gera se as variáveis ​​forem iguais ou não.

var a = 2;
var b = 2;

var a_duplicate = a;
var b_duplicate = b;

a_duplicate*=a
b_duplicate*=b;

a_duplicate-=b*b;
b_duplicate-=b*b;

a_duplicate/=(a-b);
b_duplicate/=(a-b);

alert(a_duplicate==b_duplicate);

Por quê?

NaN não é igual a NaN pelas especificações de flutuação do IEEE. Agradecemos a Alex Van Liew por apontar que isso não se aplica apenas ao Javascript.

Stefnotch
fonte
NaNnão é igual às NaNespecificações de flutuação do IEEE. De fato, uma maneira rápida de testar se você tem um NaNem C é compará-lo consigo mesmo. Portanto, isso se aplica a todos os idiomas, não apenas ao JS.
Alex Van Liew
1
@AlexVanLiew Interesting. Eu não sabia disso! Ok, alterando minha resposta um pouco e adicionando crédito onde é devido.
Stefnotch
0

Fantom

a := 3
b := 3
duplicates := [a:b]
duplicates = duplicates.map {it * a}
duplicates = duplicates.map {it - b*b}
duplicates = duplicates.map {it / a-b}
echo(duplicates.join("") |Int a_2, Int b_2 ->Str| {"" +  a_2 + " = " + b_2})

Resultado:

-3 = 3

Por quê?

[a: b] é um mapa, não uma lista. Não é tão sorrateira, eu sei :(

Caim
fonte
Você deveria ter a igual b no final.
mbomb007
O fim da falácia original for 2 = 1, então o fim de qualquer resposta aqui não deve ser "verdadeira"
Cain
Eu estava pensando no BÔNUS escondido. Deixa pra lá. "Em vez de imprimir o sinal de igual, você pode imprimir apenas as duas variáveis ​​(aMod e bMod) e, em seguida, ter um código que pareça comparar as duas variáveis ​​em termos de igualdade, mas na realidade é que elas são iguais (e imprime alguma forma de verdade) . "
mbomb007
0

C

A falácia de prova clássica exige um mal-entendido clássico da sintaxe C. Infelizmente, eu conheci alguns desenvolvedores "de alto nível" que estão convencidos de que C está quebrado por causa de resultados semelhantes a este código. Se você sabe como o C funciona, torna-se bastante óbvio, mas se você viu o código e assumiu que era um idioma diferente, talvez não.

a,b,LHS,RHS;
main(){
    a=2; b=2;
    LHS=a; RHS=b;

    //multiply both sides by a
    LHS,RHS *= a; 
    //subtract b squared from both sides
    LHS,RHS -= b*b; 
    //assert that it factors correctly
    if (LHS,RHS != (a+b)*(a-b), b*(a-b)) printf("ERROR!\n");
    //'hard' division, just to be sure the compiler doesn't remove it
    LHS,RHS /=! (a-b);
    //assert that a+a really is b+b
    if (a+a != b+b) printf("ERROR!\n");
    //now just divide them by b
    printf("%d = %d ? ", LHS/b, RHS/b);
    if (RHS = LHS) 
        printf("true!");
    else
        printf("false!");
}

É claro que não funciona tão bem quando escrito de forma mais lingüística com #include <stdio.h>e int lançados na frente das declarações.

LambdaBeta
fonte
Como isso funciona?
CalculatorFeline
Primeiro, observe que em c, se você 'esquecer' o int em uma declaração, ele assume o tipo int para ser compatível com o k & r c. Em seguida, procure o operador, em ce preste atenção à sua precedência. Em seguida, observe o = em vez de == na última instrução if.
LambdaBeta