Kesalahan Bukti Klasik [tertutup]

18

Latar belakang

Jadi, kita semua tahu bukti klasik yang seperti ini:

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!)
Dari Tentu saja, kesalahannya adalah Anda tidak dapat membaginya dengan 0. Karena a = b, a - b = 0, jadi ada pembagian tersembunyi oleh 0.

Tantangan

Anda harus meniru bukti ini. Pertama, nyatakan dua bilangan bulat a dan b (tidak masalah apa yang Anda sebut) sama. Kemudian deklarasikan aMod dan bMod sebagai versi yang dapat dimodifikasi dari a dan b dan awalnya masing-masing sama dengan a dan b. Anda harus mengalikan keduanya dengan a, lalu kurangi b * b dari keduanya. Anda kemudian harus membaginya dengan a - b dan kemudian membaginya dengan b (atau a) untuk mendapatkan. Kemudian, cetak aMod dan bMod dengan tanda yang sama di antara mereka.

Si curang

Tentu saja, karena Anda menyatakan a dan b sama dengan, a - b = 0, dan membaginya dengan 0 menyebabkan kesalahan. Jadi, Anda harus memalsukannya secara kreatif. Juga, karena Anda mencoba mereplikasi buktinya, hasilnya pada semua operasi pada aMod dan bMod tidak boleh sama dengan ketika dicetak. Mereka tidak harus sama dengan 2 dan 1, hanya dua angka yang tidak sama.

Berikut ini sebuah contoh:

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

Mungkin bukan yang terbaik, tetapi menggambarkan intinya.

Bonus curang

Alih-alih mencetak tanda sama dengan, Anda dapat mencetak hanya dua variabel (aMod dan bMod), dan kemudian memiliki kode yang muncul untuk membandingkan dua variabel untuk kesetaraan tetapi dalam kenyataannya terletak bahwa mereka sama (dan mencetak beberapa bentuk true).

Ingat, ini adalah kontes popularitas, jadi jumlah upvotes terbanyak menang.
Juga, versi baru matematika yang disebut Mathematics 2.0 telah memanfaatkan celah standar secara otomatis membatalkan bukti.

pengguna155698
sumber
Berikut ini adalah tautan Wikipedia dari kesalahan matematika sehingga orang dapat lebih memahami
3
Saya memberikan suara untuk menutup pertanyaan ini sebagai di luar topik karena tantangan curang tidak lagi pada topik di situs ini. meta.codegolf.stackexchange.com/a/8326/20469
cat

Jawaban:

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

Keluaran:

[1, NaN]

Perhatikan bahwa 0/0 = NaN

Petunjuk

Coba tambahkan beberapa titik koma.
Program ini sebenarnya var a=3,b=3,a2=3,b2=3[a2,b2]=...=[a2/(a-b),b2/(a-b)];console.log([a2/a,b2/a]).
Dan NaN adalah [3/0,undefined/0]/3.

jimmy23013
sumber
Wow. Itu sangat pintar, "tidak sengaja" lupa untuk menambahkan titik koma yang membuat (hampir) seluruh program kalimat berjalan.
user155698
3

Python 2

Saya cukup yakin itu sudah jelas karena semua orang tahu Python, tapi inilah upaya saya:

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)

Ini menghasilkan True .

Petunjuk:

Periksa divisi saya.

mbomb007
sumber
karena semua orang menggunakan Python . Saya tahu python, tapi saya jarang menggunakannya
rpax
@ rpax Itulah yang saya maksud.
mbomb007
Maaf, saya tidak membaca jawaban Anda dengan benar.
rpax
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($/)

ideone

Petunjuk:

,

Penjelasan:

Dua baris yang berakhir dengan koma menyebabkan program berperilaku berbeda dari yang seharusnya. Tanpa koma, metode mengambil argumen tunggal a, set bsama dengan a, melakukan transformasi dari masing-masing bukti (kecuali karena beberapa tanda kurung yang hilang, itu tidak membaginya dengan 0), dan mengeluarkan hasilnya (Dengan input 3 , itu akan menghasilkan "-1 = -1". Namun, dengan tanda koma, b = agaris menjadi bagian dari tanda tangan metode, yang berarti bahwa ia mendeklarasikan argumen kedua dengan nilai default. Metode doa pada akhir melewati di hasil STDOUT.write($/), yaitu 1 (jumlah byte yang ditulisnya ke STDOUT, karena $/sudah ditentukan ke karakter baris baru.) Jadi a adalah 3 dan b adalah 1, menghasilkan persamaan yang dimulai dengan "3 = 1". Sampah dalam, sampah keluar.

histokrat
sumber
Trik yang bagus di sana dengan baris baru Anda.
LegionMammal978
Bisakah Anda menambahkan penjelasan untuk yang bukan Ruby?
kirbyfan64sos
@ kirbyfan64sos Tentu, sudah selesai.
histokrat
2

GolfScript

Peringatan: program ini sedikit curang, karena tidak mencetak aMod dan 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;
};

Coba di sini !

Jadi apa yang terjadi?

Hal pertama yang mungkin Anda perhatikan adalah "trigraph terlarang". Tapi ingat, ini GolfScript, bukan C! Juga, mungkin memperhatikan bahwa itu tidak benar-benar mengatakan "int main ()", ia mengatakan "1nt main ()". Dalam GolfScript, "1" berarti mendorong 1 ke tumpukan, dan "nt main" diproses sebagai dua variabel tidak diinisialisasi, yang tidak melakukan apa-apa. Kedua tanda kurung pertama menambahkan 1 ke nomor atas tumpukan, dan kemudian kurangi satu, pada dasarnya membatalkan diri. Tanda kurung menunjukkan sebuah blok yang didorong ke tumpukan, dan kemudian tanda koma segera muncul. Jadi, pada akhirnya, kita hanya memiliki "1" asli yang didorong, dan pada akhir program GolfScript, tumpukan dicetak. Jawaban ini terinspirasi oleh yang satu ini .

K Zhang
sumber
Trigraph terdeteksi. Mengaktifkan sistem -1 otomatis. Kesalahan: -1 gagal (4792, RPLS)
CalculatorFeline
Ini licik, karena itu menipu Anda untuk berpikir itu gagal menipu Anda. +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.

Output ketika areEqual(4,4)dipanggil (atau beberapa angka lainnya benar-benar):

false

Mengapa?

Di Prolog, operator "=" tidak memberi pengaruh; itu "Unifikasi". Karena itu Amod = Amod * Agagal karena Amodtelah dipersatukan dengan A, dan karenanya tidak mungkin disatukan dengan Amod * A. Prolog kemudian segera berhenti menjalankan aturan saat ini dan kembali false.

Fatalisasi
sumber
2
Saya pikir itu harus sebaliknya, Anda harus menampilkan "benar" ketika dua nilai berbeda, bukan "salah" ketika keduanya sama ^^ '
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);

Output:
http://jsbin.com/furino/2/edit?js,output JsBin tampaknya tidak dapat menjalankan kode ini. Gunakan konsol browser sebagai gantinya.

Mengapa?

scrollMaxX dan screenX sudah merupakan variabel yang sudah ada. Mereka dibangun di dalam browser. Dengan demikian, hasilnya dapat bervariasi. Biarkan kata kunci hanya sementara mengubah nilainya.

Satu lagi JavaScript: Tidak persis mengikuti aturan, itu hanya menghasilkan jika variabelnya sama atau tidak.

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

Mengapa?

NaN tidak sama dengan NaN dengan spesifikasi float IEEE. Terima kasih kepada Alex Van Liew untuk menunjukkan bahwa ini tidak hanya berlaku untuk Javascript.

Stefnotch
sumber
NaNtidak sama NaNdengan spesifikasi float IEEE. Sebenarnya, cara cepat untuk menguji apakah Anda memiliki nilai NaNC adalah membandingkannya dengan dirinya sendiri. Jadi ini berlaku untuk semua bahasa, bukan hanya JS.
Alex Van Liew
1
@AlexVanLiew Menarik. Saya tidak tahu itu! Oke, ubah sedikit jawaban saya dan tambahkan kredit pada waktunya.
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})

Keluaran:

-3 = 3

Mengapa?

[a: b] adalah peta, bukan daftar. Tidak terlalu licik, saya tahu :(

Kain
sumber
Anda seharusnya a sama dengan b pada akhirnya.
mbomb007
Akhir dari kesalahan awal adalah 2 = 1, jadi akhir dari setiap jawaban di sini tidak boleh "benar"
Kain
Aku sedang memikirkan BONUS yang curang. Lupakan. "Alih-alih mencetak tanda sama dengan, Anda dapat mencetak hanya dua variabel (aMod dan bMod), dan kemudian memiliki kode yang muncul untuk membandingkan dua variabel untuk kesetaraan tetapi dalam kenyataannya terletak bahwa mereka sama (dan mencetak beberapa bentuk true) . "
mbomb007
0

C

Kesalahan bukti klasik membutuhkan kesalahpahaman sintaksis klasik C. Sayangnya saya telah bertemu dengan beberapa pengembang "tingkat tinggi saja" yang yakin C rusak karena hasil yang mirip dengan kode ini. Jika Anda tahu bagaimana C bekerja, itu menjadi sangat jelas, tetapi jika Anda melihat kode dan menganggapnya bahasa yang berbeda, mungkin tidak.

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

Tentu saja itu tidak berfungsi dengan baik ketika ditulis dengan lebih idiomatis #include <stdio.h>dan int dilemparkan di depan deklarasi.

LambdaBeta
sumber
Bagaimana cara kerjanya?
CalculatorFeline
Pertama-tama catat bahwa dalam c jika Anda 'lupa' int dalam deklarasi, ia mengasumsikan tipe int agar kompatibel dengan k & r c. Selanjutnya cari, operator di c dan perhatikan prioritasnya. Selanjutnya catat = bukannya == dalam pernyataan if terakhir.
LambdaBeta