Booleans gereja
Sebuah boolean Gereja adalah fungsi yang kembali x
untuk benar dan y
untuk palsu di mana x
adalah argumen pertama ke fungsi dan y
merupakan argumen kedua ke fungsi. Fungsi lebih lanjut dapat disusun dari fungsi-fungsi ini yang mewakili operasi and
not
or
xor
dan implies
logis.
Tantangan
Bangun gereja boolean dan and
not
or
xor
dan implies
gerbang Gereja dalam bahasa pilihan Anda. and
or
dan xor
hendaknya mengambil dua fungsi (mewakili boolean Gereja) dan mengembalikan fungsi (mewakili boolean Gereja lainnya). Demikian juga, not
harus membalikkan fungsi yang diperlukan dan implies
gerbang harus melakukan boolean menyiratkan logika mana argumen pertama implies
yang kedua.
Mencetak gol
Panjang total semua kode yang diperlukan untuk membuat Gereja true
dan false
dalam bahasa Anda and
not
or
xor
serta implies
gerbang dan Gereja tidak termasuk nama fungsi. (sebagai contoh,false=lambda x,y:y
dalam Python akan menjadi 13 byte). Anda dapat menggunakan kembali nama-nama ini nanti dalam kode Anda dengan mereka menghitung 1 byte terhadap total byte gerbang itu.
Contoh kode semu:
Fungsi yang Anda buat harus dapat dipanggil nanti dalam kode Anda seperti itu.
true(x, y) -> x
false(x, y) -> y
and(true, true)(x, y) -> x
and(true, false)(x, y) -> y
# ... etc
sumber
true([x, y])
,and([true, true])([x, y])
)?Jawaban:
Binary Lambda Calculus ,
13.87512.875 byte (103 bit)Bahasa Kalkulus Binary Lambda (BLC) oleh John Tromp pada dasarnya adalah format serialisasi yang efisien untuk kalkulus lambda. Ini sangat cocok untuk tugas ini, karena notasi Gereja bahkan merupakan cara "idiomatis" untuk bekerja dengan para boolean di BLC.
Saya menggunakan fungsi lambda berikut untuk kombinator,
beberapa di antaranya saya salin dan pindahkan dari jawaban Haskell:,yang ditemukan oleh pencarian lengkap dengan batas bukti 20-reduksi untuk setiap case. Ada kemungkinan bagus ini sesingkat mungkin.Ini menerjemahkan ke urutan kode BLC (biner) berikut:
Fungsi di atas adalah total
111 bit panjang (13,875 byte),103 bit panjang (12,875 byte). Mereka tidak perlu disejajarkan dengan batas byte untuk digunakan di dalam suatu program, jadi masuk akal untuk menghitung byte pecahan.Tidak ada kode yang digunakan kembali antara combinator, karena tidak ada variabel / referensi / nama dalam BLC - semuanya harus disalin. Namun, efisiensi pengkodean membuat representasi yang cukup singkat.
sumber
And: (\a \b a b a)
berhasil?\a \b a a b
. Ini lebih panjang dari yang saya gunakan di BLC.Haskell , 50 - 6 = 44 byte
-1 byte terima kasih kepada Khuldraeseth na'Barya, dan -1 byte terima kasih kepada Christian Sievers.
Cobalah online!
sumber
Show
contoh untukconst
danconst id
dan mencetak boolean gereja secara langsung. Cobalah online! .a
dapat dipersingkat.f=n t
?t=pure
alih-aliht=const
.t=pure
akan menyebabkan kesalahan ketika saya mencoba menerapkana
,o
,x
, ataui
untuk itu. Mendeklarasikan tipet
untuk memperbaiki ini membutuhkan lebih banyak byte daripada hanya menggunakant=const
.Python 2 , (-3?)
10195 byteDavid Beazley memakan hatimu!
-6 terima kasih kepada Chas Brown (memindahkan yang diulang
:
ke teks bergabung>. <)Cobalah online!
Saya pikir mungkin
95 - 3
karena saya tidak menggunakan kembali fungsiA
,X
atauI
, tapi saya menggunakan satu=
untuk tugas (di depanlambda
). Mungkin saya tidak bisa menghapus apa pun; mungkin saya bahkan bisa menghapus 3.5?sumber
exec
maksud saya tidak bisa? Saya bisa melihat jalan baik - saya tidak menggunakan kembali A, X, atau saya tetapi kode tidak akan bekerja tanpa mereka. (Mungkin saya bahkan bisa menghapus 3.5 ?!)JavaScript (Node.js) ,
928683 - 7 = 76 byteCobalah online! Tautan termasuk kasus uji dasar. Sunting: Disimpan
69 byte berkat @tsh.sumber
t
,f
,n
digunakan.t
,f
, dann
dalam kasus Anda).Python 2 ,
133 - 6 = 12794 byteCobalah online!
Tanpa malu-malu mencuri ide licik di balik jawaban Jonathan Allan ; tidak ada byte yang dikurangi.
sumber
J , 67 byte - 7 = 60
Cobalah online!
Perlu diperhatikan:
Fungsi tingkat tinggi bekerja secara berbeda dalam J daripada dalam bahasa fungsional. Untuk membuat kata kerja baru dari 1 atau 2 kata kerja yang ada, Anda harus menggunakan kata keterangan (dalam kasus 1) atau kata sambung (dalam kasus 2).
Secara sintaksis, kata keterangan muncul setelah kata kerja, dan konjungsi di antaranya. Jadi untuk "tidak" kata kerja yang
f
Anda lakukanf n
, dan untuk "dan" kata kerjaf
dang
, Andaf a g
.sumber
Bahasa Wolfram (Mathematica) , 61-7 = 54 byte
Cobalah online!
un-golfed: terinspirasi oleh Wikipedia ,
sumber
Underload ,
5652 byteCobalah online! (termasuk bagian testuite dan teks yang mengidentifikasi program)
Skor ini mengejutkan baik untuk esolang tingkat sangat rendah. (Angka Gereja, boolean Gereja, dll. Sangat umum digunakan di Underload karena alasan ini; bahasa tidak memiliki angka dan boolean yang tertanam di dalamnya, dan ini adalah salah satu cara yang lebih mudah untuk mensimulasikannya. Karena itu, juga umum untuk menyandikan booleans sebagai angka Gereja 0 dan 1.)
Bagi siapa pun yang bingung: Underload memungkinkan Anda mendefinisikan fungsi yang dapat digunakan kembali, tetapi tidak membiarkan Anda memberi nama dengan cara biasa, Underload hanya mengitari tumpukan argumen (jadi jika Anda mendefinisikan lima fungsi dan ingin memanggil yang pertama Anda mendefinisikan, Anda perlu menulis fungsi baru yang membutuhkan lima argumen dan memanggil kelima argumen tersebut, lalu menyebutnya dengan cukup banyak argumen sehingga mencari argumen cadangan yang akan digunakan). Memanggil mereka menghancurkannya secara default tetapi Anda dapat memodifikasi panggilan untuk membuatnya tidak merusak (dalam kasus sederhana, Anda hanya perlu menambahkan tanda titik dua pada panggilan tersebut, meskipun kasing kompleks lebih umum karena Anda perlu memastikan bahwa salinannya di stack tidak menghalangi jalan Anda), jadi dukungan fungsi Underload memiliki semua persyaratan yang kita perlukan dari pertanyaan.
Penjelasan
benar
Yang ini cukup mudah; kita menyingkirkan argumen yang tidak kita inginkan dan argumen yang kita inginkan hanya tinggal di sana, berfungsi sebagai nilai balik.
Salah
Yang ini bahkan lebih mudah.
tidak
Ini menyenangkan:
not
tidak menyebut argumen sama sekali, itu hanya menggunakan komposisi fungsi. Ini adalah trik umum di Underload, di mana Anda sama sekali tidak memeriksa data Anda, Anda hanya mengubah cara kerjanya dengan melakukan pra dan pasca membuat sesuatu dengan itu. Dalam hal ini, kami memodifikasi fungsi untuk menukar argumennya sebelum menjalankan, yang jelas meniadakan angka Gereja.dan
Pertanyaannya memungkinkan mendefinisikan fungsi dalam hal fungsi lain. Kami mendefinisikan "dan" selanjutnya karena semakin baru "tidak" telah ditentukan, semakin mudah untuk menggunakannya. (Ini tidak mengurangi skor kami, karena kami tidak menyebutkan "tidak" sama sekali, tetapi menghemat byte dari penulisan definisi lagi. Ini adalah satu-satunya waktu dimana satu fungsi merujuk ke yang lain, karena merujuk ke fungsi apa pun tetapi yang paling baru didefinisikan akan menelan biaya terlalu banyak byte.)
Definisi di sini adalah
and x y = (not x) false y
. Dengan kata lain, jikanot x
, maka kita kembalifalse
; jika tidak, kami kembaliy
.atau
@Nitrodon menunjukkan dalam komentar yang
or x y = x x y
biasanya lebih pendek darior x y = x true y
, dan itu ternyata benar di Underload juga. Implementasi yang naif akan menjadi(:~^)
, tetapi kita bisa bermain golf byte tambahan dengan mencatat bahwa tidak masalah apakah kita menjalankan argumen pertama asli atau salinannya, hasilnya sama saja.Underload sebenarnya tidak mendukung currying dalam arti yang biasa, tetapi definisi seperti ini membuatnya terlihat seperti itu! (Kuncinya adalah bahwa argumen yang tidak dikonsumsi hanya bertahan, sehingga fungsi yang Anda panggil akan menafsirkannya sebagai argumen sendiri.)
tersirat
Definisi yang digunakan di sini adalah
implies x y = not (y false x)
. Jika y benar, ini disederhanakan menjadinot false
, yaitutrue
. Jika y salah, ini disederhanakannot x
, sehingga memberi kita tabel kebenaran yang kita inginkan.Dalam hal ini, kami menggunakan
not
lagi, kali ini dengan menulis ulang kodenya daripada merujuknya. Itu hanya ditulis secara langsung karena(~)~*
tanpa tanda kurung di sekitarnya, sehingga dipanggil daripada didefinisikan.xor
Kali ini, kami hanya mengevaluasi satu dari dua argumen kami, dan menggunakannya untuk menentukan apa yang akan dikomposisikan ke argumen kedua. Underload memungkinkan Anda bermain dengan cepat dan longgar dengan arity, jadi kami menggunakan argumen pertama untuk memilih antara dua fungsi dua-argumen dua-kembali; argumen swap yang mengembalikan keduanya tetapi dalam urutan yang berlawanan, dan fungsi identitas yang mengembalikan keduanya dalam urutan yang sama.
Ketika argumen pertama benar, oleh karena itu kami menghasilkan versi yang diedit dari argumen kedua yang bertukar argumen sebelum berjalan, yaitu precompose dengan "swap argumen", yaitu
not
. Jadi argumen pertama yang benar berarti kita mengembalikannot
argumen kedua. Di sisi lain, argumen pertama palsu berarti kita menulis dengan fungsi identitas, yaitu tidak melakukan apa pun. Hasilnya adalah implementasi darixor
.sumber
or x y = x x y
menghemat beberapa byteor x y = x true y
.Ruby , 82 - 4 = 78 byte
Cobalah online!
sumber
Java 8, skor:
360358319271233 (240-7) byteIni lebih sulit untuk diselesaikan daripada yang saya pikirkan ketika saya memulainya .. TerutamaEDIT: Ok, tidak menggunakan kembali fungsi tetapi hanya menduplikasi pendekatan yang sama jauh lebih murah dalam hal byte-count untuk Java .. Dan saya mendapatkan bonus -7 penuh karena tidak menggunakan salah satu fungsi juga.implies
. Bagaimanapun, itu bekerja .. Mungkin bisa bermain golf sedikit di sana-sini.Cobalah online.
Penjelasan:
sumber
C ++ 17,
207−49 = 158195 - 58 = 137 byteLinebreak tidak perlu (selain dua yang pertama).
Cobalah online!
Unit-diuji dengan pernyataan seperti:
DIPERBARUI: sebelumnya saya punya
tetapi jawaban Roman menunjuk ke versi yang lebih pendek. Perhatikan bahwa saat
not_(std::plus<>)
ini bentuknya buruk, di mana sebelumnya itu setara denganstd::plus<>
; tetapi karenastd::plus<>
tidak "mewakili boolean Gereja," saya pikir perilaku tersebut tidak apa-apa menurut aturan.sumber
Keempat (gforth) ,
133byte - 7 =126122Cobalah online!
-4 byte terima kasih kepada Quuxplusone
Awalnya saya secara signifikan merenungkan hal ini, mempertimbangkan hal-hal seperti makro dan literal, tetapi kemudian saya menyadari bahwa jika saya mendefinisikan hal-hal dalam hal benar dan salah (seperti yang seharusnya saya lakukan sejak awal), itu menjadi jauh lebih sederhana.
Penjelasan kode
sumber
execute
tiga kali. Menentukan steno: j execute ;
akan menghemat 4 byte.Kombinator SKI + C +, 36 byte
Saya tidak benar-benar tahu ada juru bahasa yang memungkinkan Anda untuk mendefinisikan kombinator tambahan dalam hal yang sebelumnya, jadi saya harus menguji ini menggunakan http://ski.aditsu.net/ dengan menempelkan kombinator yang diinginkan misalnya
CCKK(SK)pq
outputq
, menunjukkan bahwaK
tidak menyiratkanSK
.sumber
Julia 1.0 , 36 byte
Saya tidak tahu apakah itu penting, saya sebenarnya hanya overloading
Bool
tipe asli menjadi callable, jadi saya mendapatkan sebagian besar gerbang logika gratis. Sayangnya, Julia tidak memilikiimplies
gerbang, jadi saya harus menulis fungsi saya sendiri.Cobalah online!
sumber
Perl 6 ,
120106102101 byte-1 byte terima kasih kepada Jo King
Cobalah online!
sumber
C ++ 17,
202−49 = 153193 - 58 = 135 byteTerinspirasi oleh diskusi-komentar tentang apa yang dianggap sebagai fungsi 2-ary, berikut adalah versi kari dari solusi C ++ 17 saya sebelumnya. Ini sebenarnya lebih pendek karena kita dapat menggunakan makro yang sama untuk mendefinisikan
not_
untuk mendefinisikan semua fungsi lainnya!Cobalah online!
Yang ini diuji dengan pernyataan suka
Perhatikan bahwa
or_
didefinisikan secara efektifKita dapat mendefinisikan
or_
lebih "ringkas" sebagaitapi itu akan merugikan kita karena kita tidak akan bisa menggunakan
D
makro lagi.sumber
True
danFalse
bukannyatrue_
danfalse_
? Dan serupa untuk operator lainnya. Itu akan menghemat 12 byte.APL (dzaima / APL) , 47 byte SBCS
Berdasarkan solusi J Jonah .
true
danfalse
merupakan fungsi infiks,not
adalah operator sufiks, dan sisanya adalah operator infiks.Sesuai OP, ini menghitung semuanya dari dan termasuk
←
sampai akhir setiap baris, dan menghitung setiap panggilan definisi sebelumnya sebagai satu byte.Cobalah online!
benar dan salah adalah fungsi identitas kiri dan kanan.
not
cukup menukar argumen fungsi operan-nya.Sisanya mengimplementasikan pohon keputusan:
and
menggunakan fungsi tangan kanan⍹
untuk memilih hasil dari fungsi kiri⍶
jika benar, selain itu hasil darifalse
fungsi.or
menggunakan fungsi kiri⍶
untuk memilihtrue
jika benar, selain itu hasil dari fungsi sebelah kanan⍹
.xor
menggunakan fungsi tangan kanan⍹
untuk memilih hasil yang dinegasikan dari fungsi kiri⍶not
jika benar, selain itu hasil dari fungsi kiri.implies
menggunakan fungsi kiri⍶
untuk memilih hasil dari fungsi tangan kanan⍹
jika benar, selain hasiltrue
fungsi.sumber
Stax , 34 byte
Jalankan dan debug di staxlang.xyz!
Mendorong sekelompok blok ke tumpukan. Setiap blok mengharapkan argumen terakhirnya di atas tumpukan, diikuti dengan urutan terbalik oleh yang lain.
Dibongkar (41 byte):
Setiap pasangan
{ }
adalah blok. Saya menggunakan dua register X dan Y untuk memegangtrue
dannot
sehingga saya bisa mengaksesnya dengan mudah nanti. Sayangnya,false
tidak bisa begitu saja menjadi no-op, karena itu akan membuat tumpukan berantakan dan mengacaukan satu kotak XOR.Test suite, dikomentari
sumber
Befunge-98 ,
1057765 byteBermain lebih jauh dengan gagasan "fungsi" dalam bahasa tanpa fungsi ... berikut adalah versi Befunge-98 dari boolean Gereja!
Dalam dialek terbatas Befunge-98 ini, sebuah program terdiri dari serangkaian "garis" atau "fungsi," yang masing-masing dimulai dengan
>
instruksi (Ke Kanan) dalam kolom x = 0. Setiap "fungsi" dapat diidentifikasi dengan nomor barisnya (koordinat y). Fungsi dapat mengambil input melalui tumpukan Befunge , seperti biasa.Baris 0 khusus, karena (0,0) adalah IP awal. Untuk membuat program yang mengeksekusi baris L, cukup tempatkan instruksi pada baris 0 yang, ketika dieksekusi, terbang dengan pointer instruksi ke (x = L, y = 0).
Keajaiban terjadi pada baris 1. Baris 1, ketika dieksekusi, muncul angka
L
dari tumpukan dan melompat ke nomor barisL
. (Baris ini sebelumnya> >>0{{2u2}2}$-073*-\x
, yang dapat "melompat absolut" ke baris mana pun; tetapi saya baru menyadari bahwa karena saya tahu baris ini dipatok ke baris 1, kita dapat "melompatiL-1
garis " baris-baris dengan kode yang jauh lebih sedikit.)Jalur 2 melambangkan Gereja
FALSE
. Ketika dieksekusi, muncul dua angkat
danf
dari tumpukan lalu terbang ke nomor barisf
.Jalur 3 melambangkan Gereja
TRUE
. Ketika dieksekusi, muncul dua angkat
danf
dari tumpukan lalu terbang ke nomor barist
.Jalur 6, mewakili Gereja
XOR
, inovatif. Ketika dieksekusi, muncul dua angkaa
danb
dari stack, dan kemudian terbang untuk sejalana
dengan input stackNOT EXEC b
. Jadi, jikaa
mewakili GerejaTRUE
, hasilnyaa NOT EXEC b
adalahNOT b
; dan jikaa
mewakili GerejaFALSE
, hasilnyaa NOT EXEC b
adalahEXEC b
.Inilah versi yang tidak diserang dengan test harness. Pada baris 0, atur tumpukan dengan input Anda. Misalnya,
338
berartiIMPLIES TRUE TRUE
. Pastikan penutupanx
muncul tepat (x, y) = (0,15) atau tidak ada yang akan berhasil! Pastikan juga pengaturan tumpukan Anda dimulaiba
, sehingga program akan benar-benar berakhir dengan beberapa keluaran.Cobalah online!
Inilah versi yang byte-nya saya hitung.
Perhatikan bahwa untuk mendefinisikan suatu fungsi dalam dialek ini Anda tidak menyebutkan namanya sama sekali; "namanya" ditentukan oleh lokasi sumbernya. Untuk memanggil suatu fungsi, Anda menyebutkan "namanya"; misalnya,
XOR
(6
) didefinisikan dalam istilahNOT
danEXEC
(5
dan1
). Tetapi semua "nama fungsi" saya hanya membutuhkan satu byte untuk diwakili. Jadi solusi ini tidak mendapat penyesuaian skor.sumber