Falacia de prueba clásica [cerrado]

18

El fondo

Entonces, todos conocemos la prueba clásica que dice así:

a = b
a² = ab
a² - b² = ab - b²
(ab) (a + b) = b (ab)
(a + b) = b
b + b = b
2b = b
2 = 1 (¡Ja, ja!)
De Por supuesto, el error es que no se puede dividir por 0. Como a = b, a - b = 0, entonces hubo una división oculta por 0.

El reto

Tienes que replicar esta prueba. Primero, declare dos enteros a y b (no importa cómo los llame) que sean iguales. Luego declare que aMod y bMod son versiones modificables de a y b e inicialmente iguales a a y b, respectivamente. Debes multiplicarlos por a, luego restar b * b de ambos. Luego debe dividir por a - b y luego dividirlos por b (o a) para obtener. Luego, imprima aMod y bMod con un signo igual entre ellos.

El descuidado

Por supuesto, dado que declaró a y b como iguales, a - b = 0, y dividir por 0 produce un error. Entonces debes fingir creativamente. Además, debido a que está intentando replicar la prueba, el resultado en todas las operaciones en aMod y bMod no debe ser igual cuando se imprime. No tienen que ser exactamente iguales a 2 y 1, solo dos números que no son iguales.

Aquí hay un ejemplo:

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

Quizás no sea el mejor, pero ilustra el punto.

Bonus sin ayuda

En lugar de imprimir el signo igual, puede imprimir solo las dos variables (aMod y bMod), y luego tener un código que parece comparar las dos variables para la igualdad, pero en realidad radica en que son iguales (e imprime alguna forma de true).

Recuerde, este es un concurso de popularidad, por lo que gana el mayor número de votos a favor.
Además, una nueva versión de las matemáticas llamada Mathematics 2.0 ha hecho uso de lagunas estándar que invalidan automáticamente una prueba.

usuario155698
fuente
Aquí es un enlace de Wikipedia de la falacia matemática que la gente pueda entender mejor
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:

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])

Salida:

[1, NaN]

Tenga en cuenta que 0/0 = NaN

Insinuación

Intenta agregar algunos puntos y comas.
Este programa es en realidad var a=3,b=3,a2=3,b2=3[a2,b2]=...=[a2/(a-b),b2/(a-b)];console.log([a2/a,b2/a]).
Y el NaN es [3/0,undefined/0]/3.

jimmy23013
fuente
Guau. Eso fue muy inteligente, falsificando "accidentalmente" agregar puntos y comas, convirtiendo (casi) todo el programa en una frase de ejecución.
user155698
3

Python 2

Estoy bastante seguro de que es obvio ya que todos conocen Python, pero aquí está mi intento:

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)

Genera True.

Insinuación:

Mira mi división.

mbomb007
fuente
ya que todos usan Python . Conozco Python, pero rara vez lo uso
rpax
@rpax Eso es lo que quise decir.
mbomb007
Lo siento, no leí correctamente tu respuesta.
rpax
2

Rubí

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

Insinuación:

,

Explicación:

Las dos líneas que terminan en comas hacen que el programa se comporte de manera diferente a como lo haría. Sin las comas, el método toma un solo argumento a, establece bigual a a, realiza las transformaciones de la prueba en cada una (excepto debido a algunos paréntesis faltantes, no se divide por 0) y genera el resultado (con una entrada de 3 , generaría "-1 = -1". Sin embargo, con la coma final, la b = alínea se convierte en parte de la firma del método, lo que significa que está declarando un segundo argumento con un valor predeterminado. La invocación del método al final pasa en resultado de STDOUT.write($/), que es 1 (el número de bytes que escribió en STDOUT, ya que $/está predefinido a un carácter de nueva línea). Entonces, a es 3 yb es 1, lo que da como resultado que la ecuación comience como "3 = 1". la basura fuera.

histocrat
fuente
Buen truco allí con tus nuevas líneas.
LegionMammal978
¿Podría agregar una explicación para los que no son rubíes?
kirbyfan64sos
@ Kirbyfan64sos Claro, hecho.
histocrat
2

GolfScript

Advertencia: este programa está engañando un poco, ya que no imprime aMod y 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;
};

Pruébalo aquí !

Entonces, ¿qué está pasando?

Lo primero que puede haber notado son los "trigrafos prohibidos". Pero recuerde, esto es GolfScript, no C! Además, probablemente notó que en realidad no dice "int main ()", dice "1nt main ()". En GolfScript, el "1" significa empujar 1 en la pila, y el "nt main" se procesa como dos variables no inicializadas, que no hacen nada. Los dos paréntesis suman primero 1 al número superior de la pila y luego restan uno, esencialmente cancelándose a sí mismos. Los corchetes denotan un bloque que se empuja hacia la pila, y luego el punto y coma lo saca de inmediato. Entonces, al final, solo tenemos el "1" original que se presionó, y al final de un programa GolfScript, la pila se imprime. Esta respuesta fue inspirada por esta .

K Zhang
fuente
Trígrafos detectados. Activación automática del sistema -1. Error: -1 falló (4792, RPLS)
CalculatorFeline
Esto es astuto, porque te engaña haciéndote creer que no te engañó. +1
Rɪᴋᴇʀ
1

Prólogo

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.

La salida cuando areEqual(4,4)se llama (o cualquier otro par de números realmente):

false

¿Por qué?

En Prolog, el operador "=" no es afectación; es "unificación". Por lo tanto, Amod = Amod * Afalla porque Amodya se ha unificado con Ay, por lo tanto, no se puede unificar con Amod * A. Prolog deja inmediatamente de ejecutar la regla actual y regresa false.

Fatalizar
fuente
2
Creo que debería ser al revés, debe emitir "verdadero" cuando los dos valores son diferentes, no "falso" cuando son iguales ^^ '
Katenkyo
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);

Salida:
http://jsbin.com/furino/2/edit?js,output JsBin no parece poder ejecutar este código. Utilice la consola del navegador en su lugar.

¿Por qué?

scrollMaxX y screenX ya son variables existentes. Están integrados en el navegador. Por lo tanto, el resultado puede variar. La palabra clave let solo cambia temporalmente su valor.

Otro JavaScript: no sigue exactamente las reglas, solo genera si las variables son iguales o no.

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 no es igual a NaN según las especificaciones flotantes de IEEE. Gracias a Alex Van Liew por señalar que esto no solo se aplica a Javascript.

Stefnotch
fuente
NaNno es igual a las NaNespecificaciones de flotación IEEE. De hecho, una forma rápida de probar si tiene un NaNC es compararlo consigo mismo. Esto se aplica a todos los idiomas, no solo a JS.
Alex Van Liew
1
@AlexVanLiew Interesante. Yo no lo sabia! Ok, cambiando mi respuesta un poco y agregando crédito cuando sea debido.
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})

Salida:

-3 = 3

¿Por qué?

[a: b] es un mapa, no una lista. No es tan astuto, lo sé :(

Caín
fuente
Se supone que tienes a igual al b final.
mbomb007
El final de la falacia original es 2 = 1, por lo que el final de cualquier respuesta aquí no debería ser "verdadero"
Caín
Estaba pensando en la BONIFICACIÓN sobria. No importa. "En lugar de imprimir el signo igual, puede imprimir solo las dos variables (aMod y bMod), y luego tener un código que parece comparar las dos variables para la igualdad, pero en realidad radica en que son iguales (e imprime alguna forma de verdad) ".
mbomb007
0

C

La falacia de la prueba clásica requiere un malentendido clásico de la sintaxis C. Lamentablemente, he conocido a algunos desarrolladores "de alto nivel" que están convencidos de que C está roto debido a resultados similares a este código. Si sabe cómo funciona C, se vuelve bastante obvio, pero si vio el código y asumió que era un lenguaje diferente, podría no serlo.

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!");
}

Por supuesto, no funciona tan bien cuando se escribe de forma más idiomática con #include <stdio.h>y se arroja delante de las declaraciones.

LambdaBeta
fuente
¿Cómo funciona sin embargo?
CalculatorFeline
Primero tenga en cuenta que en c si 'olvida' el int en una declaración, asume el tipo int para que sea compatible con k & r c. Luego busque el operador, en c y preste atención a su precedencia. A continuación, observe el = en lugar de == en la última instrucción if.
LambdaBeta