Booleans Gereja


33

Booleans gereja

Sebuah boolean Gereja adalah fungsi yang kembali xuntuk benar dan yuntuk palsu di mana xadalah argumen pertama ke fungsi dan ymerupakan argumen kedua ke fungsi. Fungsi lebih lanjut dapat disusun dari fungsi-fungsi ini yang mewakili operasi and not or xordan implieslogis.

Tantangan

Bangun gereja boolean dan and not or xordan impliesgerbang Gereja dalam bahasa pilihan Anda. and ordan xorhendaknya mengambil dua fungsi (mewakili boolean Gereja) dan mengembalikan fungsi (mewakili boolean Gereja lainnya). Demikian juga, notharus membalikkan fungsi yang diperlukan dan impliesgerbang harus melakukan boolean menyiratkan logika mana argumen pertama impliesyang kedua.

Mencetak gol

Panjang total semua kode yang diperlukan untuk membuat Gereja truedan falsedalam bahasa Anda and not or xorserta impliesgerbang 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

2
Apakah kita harus memperlakukan input fungsi (atau pengganti terdekat) sebagai fungsi kotak hitam, atau bisakah kita memeriksa kode di dalamnya? Dan haruskah nilai-nilai pengembalian operasi logis menjadi fungsi yang sama seperti yang sebelumnya didefinisikan sebagai boolean Gereja, atau bisakah mereka menjadi sesuatu yang lain yang melakukan hal yang sama?
String Tidak Terkait

1
@ Jonathan Allan saya mengeditnya jadi itu benar. Prompt seperti yang seharusnya sekarang.
Ryan Schaefer

2
Bisakah kita menganggap daftar sebagai argumen (mis. true([x, y]), and([true, true])([x, y]))?
ar4093

2
@RyanSchaefer Saya pikir Anda harus mempertimbangkan kembali membiarkan argumen berada dalam daftar yang dipesan, karena orang dapat dengan mudah membungkus argumen di awal solusi. Saya tidak berpikir bahwa mengharuskan melakukan apa pun untuk meningkatkan tantangan ini (pada kenyataannya saya pikir itu membatasi potensi golf yang menarik). Tentu saja, ini hanya pendapat saya, dan tidak apa-apa jika Anda tidak setuju.
FryAmTheEggman

1
Skornya agak membingungkan. Bukankah lebih baik membiarkan orang mengirimkan fungsi anonim, tetapi jika mereka menggunakannya di bagian lain mereka harus menugaskannya, seperti biasa
Jo King

Jawaban:


14

Binary Lambda Calculus , 13.875 12.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.

True:  (\a \b a)
False: (\a \b b)
Not:   (\a \b \c a c b)
And:   (\a \b b a b)
Or:    (\a a a)
Xor:   (\a \b b (a (\c \d d) b) a)
Impl:  (\a \b a b (\c \d c))

Ini menerjemahkan ke urutan kode BLC (biner) berikut:

 bits |  name | BLC
------+-------+---------
    7 | True  | 0000 110
    6 | False | 0000 10
   19 | Not   | 0000 0001 0111 1010 110
   15 | And   | 0000 0101 1011 010
    8 | Or    | 0001 1010
   28 | Xor   | 0000 0101 1001 0111 0000 0101 0110
   20 | Impl  | 0000 0101 1101 0000 0110

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.


1
Saya tidak tahu blc, tetapi apakah akan And: (\a \b a b a)berhasil?
tsh

Ya itu berhasil. Saya sebenarnya menggunakan rumus ini untuk urutan kode saya. Saya hanya lupa untuk memperbarui fungsi lambda yang sesuai (sekarang diperbaiki). Fungsi setara bekerja untuk Atau: \a \b a a b. Ini lebih panjang dari yang saya gunakan di BLC.
Pavel Potoček

25

Haskell , 50 - 6 = 44 byte

-1 byte terima kasih kepada Khuldraeseth na'Barya, dan -1 byte terima kasih kepada Christian Sievers.

t=const
f=n t
n=flip
a=n n f
o=($t)
x=(n>>=)
i=o.n

Cobalah online!


2
Catatan: Anda dapat menentukan Showcontoh untuk constdan const iddan mencetak boolean gereja secara langsung. Cobalah online! .
nimi


4
Mengapa tidak ada yang menggunakan f=n t?
Christian Sievers

3
Anda dapat menyimpan byte dengan menggunakan t=purealih-alih t=const.
Joseph Sible-Reinstate Monica

4
@ YosephSible saya mencobanya pada awalnya. Sayangnya, t=pureakan menyebabkan kesalahan ketika saya mencoba menerapkan a, o, x, atau iuntuk itu. Mendeklarasikan tipe tuntuk memperbaiki ini membutuhkan lebih banyak byte daripada hanya menggunakan t=const.
Nitrodon

9

Python 2 , (-3?)  101  95 byte

David Beazley memakan hatimu!

-6 terima kasih kepada Chas Brown (memindahkan yang diulang :ke teks bergabung>. <)

exec'=lambda x,y=0:'.join('F y;T x;N x(F,T);A x(y,F);O x(T,y);X x(N(y),y);I O(y,N(x))'.split())

Cobalah online!

Saya pikir mungkin 95 - 3karena saya tidak menggunakan kembali fungsi A, Xatau I, tapi saya menggunakan satu =untuk tugas (di depan lambda). Mungkin saya tidak bisa menghapus apa pun; mungkin saya bahkan bisa menghapus 3.5?


@Ryan Schaefer dapatkah saya menghapus tiga atau apakah saya menggunakan execmaksud 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 ?!)
Jonathan Allan


Terima kasih @Chas! Usus besar yang menyelinap melalui jaring :) Pekerjaan bagus di ganti untuk -1 BTW
Jonathan Allan

7

JavaScript (Node.js) , 92 86 83 - 7 = 76 byte

t=p=>q=>p
f=t(q=>q)
n=p=>p(f)(t)
a=p=>n(p)(f)
o=p=>p(t)
x=p=>p(n)(f())
i=p=>n(p)(t)

Cobalah online! Tautan termasuk kasus uji dasar. Sunting: Disimpan 6 9 byte berkat @tsh.


1
tampaknya Anda tidak dapat mengklaim ini sebagai -7 sejak t, f, ndigunakan.
tsh

1
@ tsh Bukan itu cara saya memahami sistem penilaian; itu secara eksplisit mengecualikan nama dalam definisi, meskipun nama dalam biaya penggunaan 1 byte.
Neil

@ Neil Anda tidak dapat mengklaim diskon byte untuk nama fungsi yang disebut dengan kode Anda ( t, f, dan ndalam kasus Anda).
asgallant

2
@ tidak ada. Tidak ada byte untuk nama dan 1 byte saat digunakan nanti. 'T fnaox i' bukan byte dan 1 byte saat digunakan nanti. Saya ingin meningkatkan keterbacaan tetapi sekarang saya menyadari bahwa saya seharusnya membiarkannya sepenuhnya golf dan sudah terlambat untuk mengubahnya sekarang
Ryan Schaefer

@RyanSchaefer di mana aturan itu? Aku belum pernah melihatnya seperti itu.
asgallant

6

Python 2 , 133 - 6 = 127 94 byte

exec"t!u;f!v;n!u(f,t);a!u(v,f);o!u(t,v);x!u(n(v),v);i!o(v,n(u))".replace('!','=lambda u,v=0:')

Cobalah online!

Tanpa malu-malu mencuri ide licik di balik jawaban Jonathan Allan ; tidak ada byte yang dikurangi.


Saya akan memposting jawaban untuk pertanyaan saya sendiri tetapi saya tidak yakin apakah ini diizinkan dan saya pikir ini bertentangan dengan semangatnya. Jadi saya pikir saya hanya akan membimbing Anda. Alih-alih menggunakan daftar, adakah di sana Anda dapat menggunakan fungsi yang sedang diinput sendiri dan cara spesifik di mana mereka mengembalikan input mereka untuk mempersingkat kode?
Ryan Schaefer

Saya berani bertaruh bahwa meskipun jawabannya adalah ya, itu akan jauh lebih lama dengan Python.
String Tidak Terkait

Saya berdiri dikoreksi
String Tidak Terkait

@ Mr.Xcoder Anda benar, saya salah jumlah byte untuk fungsi contoh. Mereka akan diizinkan untuk menghapus 6 byte meskipun untuk nama-nama fungsi.
Ryan Schaefer

@Bapak. Xcoder: Dimodifikasi sesuai pengamatan Anda.
Chas Brown

4

J , 67 byte - 7 = 60

t=.[
f=.]
n=.~
a=.2 :'u v]'
o=.2 :'[u v'
x=.2 :'u~v u'
i=.2 :'v u['

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 fAnda lakukan f n, dan untuk "dan" kata kerja fdan g, Anda f a g.


4

Bahasa Wolfram (Mathematica) , 61-7 = 54 byte

t=#&
f=#2&
a=#2~#~f&
o=t~#~#2&
n=f~#~t&
x=n@#~#2~#&
i=#2~#~t&

Cobalah online!

un-golfed: terinspirasi oleh Wikipedia ,

t[x_, y_] := x
f[x_, y_] := y
and[x_, y_] := x[y, f]
or[x_, y_] := x[t, y]
not[x_] := x[f, t]
xor[x_, y_] := y[not[x], x]
imply[x_, y_] := x[y, t]

Cukup yakin baris baru diperlukan untuk memisahkan definisi fungsi. Anda juga referensi tf dan n dalam definisi fungsi lain sehingga Anda tidak dapat mengurangi yang, jadi 61-4 = 57.
Jonathan Allan

@JonathanAllan Saya telah membaca kembali instruksi penilaian dan setuju bahwa baris baru harus diperhitungkan, terima kasih. Saya tidak setuju dengan bagian kedua Anda: ketika saya menggunakan kembali nama-nama, saya memang menghitungnya sebagai "1 byte menuju total byte gerbang itu", yang tersirat di sini karena saya menggunakan nama 1-byte. Ketika saya membaca instruksi, tidak disebutkan lagi menghitungnya sebagai satu byte terhadap total definisi asli juga. Jadi saya akan dengan N-7 byte. Juga, komentar lain dari OP menjelaskan: "Tidak ada byte untuk nama dan 1 byte saat digunakan nanti."
Roman

Saya membaca "1 byte kemudian" berarti penggunaan dalam fungsi lain biaya byte. Ini selaras dengan bagaimana orang lain juga mencetak gol.
Jonathan Allan

@ Jonathan Allan Saya kurang tertarik pada penafsiran dan lebih banyak lagi dalam kode golf 😀
Roman

4

Underload , 56 52 byte

(~!)(!)((~)~*):((!)~^)*(:^)(~(!)~^(~)~*)(()~(~)~^~*)

Cobalah 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

(~!)
(  )  Define function:
 ~      Swap arguments
  !     Delete new first argument (original second argument)

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

(!)
( )   Define function:
 !      Delete first argument

Yang ini bahkan lebih mudah.

tidak

((~)~*)
(     )  Define function:
    ~*     Modify first argument by pre-composing it with:
 (~)         Swap arguments

Ini menyenangkan: nottidak 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

:((!)~^)*
 (     )   Define function:
     ~^      Execute its first argument with:
  (!)          false
               {and implicitly, our second argument}
        *  Edit the newly defined function by pre-composing it with:
:            {the most recently defined function}, without destroying it

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, jika not x, maka kita kembali false; jika tidak, kami kembali y.

atau

(:^)
(  )  Define function:
 :      Copy the first argument
  ^     Execute the copy, with arguments
          {implicitly, the original first argument}
          {and implicitly, our second argument}

@Nitrodon menunjukkan dalam komentar yang or x y = x x ybiasanya lebih pendek dari or 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

(~(!)~^(~)~*)
(           )  Define function:
 ~               Swap arguments
     ~^          Execute the new first (original second) argument, with argument:
  (!)              false
                   {and implicitly, our second argument}
       (~)~*     Run "not" on the result

Definisi yang digunakan di sini adalah implies x y = not (y false x). Jika y benar, ini disederhanakan menjadi not false, yaitu true. Jika y salah, ini disederhanakan not x, sehingga memberi kita tabel kebenaran yang kita inginkan.

Dalam hal ini, kami menggunakan notlagi, kali ini dengan menulis ulang kodenya daripada merujuknya. Itu hanya ditulis secara langsung karena (~)~*tanpa tanda kurung di sekitarnya, sehingga dipanggil daripada didefinisikan.

xor

(()~(~)~^~*)
(          )  Define function:
   ~   ~^       Execute the first argument, with arguments:
    (~)           "swap arguments"
 ()               identity function
         ~*     Precompose the second argument with {the result}

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 mengembalikan notargumen kedua. Di sisi lain, argumen pertama palsu berarti kita menulis dengan fungsi identitas, yaitu tidak melakukan apa pun. Hasilnya adalah implementasi dari xor.


or x y = x x ymenghemat beberapa byte or x y = x true y.
Nitrodon

Underload sering kontra-intuitif ketika datang untuk mengganti literal dengan variabel yang digunakan kembali, tetapi dalam kasus ini, transformasi itu ternyata menyimpan lebih banyak byte daripada yang diharapkan, daripada lebih sedikit. Terima kasih atas peningkatannya!
ais523


3

Java 8, skor: 360 358 319 271 233 (240-7) byte

interface J<O>{O f(O x,O y,J...j);}J t=(x,y,j)->x;J f=(x,y,j)->y;J n=(x,y,j)->j[0].f(y,x);J a=(x,y,j)->j[0].f(j[1].f(x,y),y);J o=(x,y,j)->j[0].f(x,j[1].f(x,y));J x=(x,y,j)->j[0].f(j[1].f(y,x),j[1].f(x,y));J i=(x,y,j)->j[0].f(j[1].f(x,y),x);

Ini lebih sulit untuk diselesaikan daripada yang saya pikirkan ketika saya memulainya .. Terutama implies. Bagaimanapun, itu bekerja .. Mungkin bisa bermain golf sedikit di sana-sini. EDIT: 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.

Cobalah online.

Penjelasan:

// Create an interface J to create lambdas with 2 Object and 0 or more amount of optional
// (varargs) J lambda-interfaces, which returns an Object:
interface J<O>{O f(O x,O y,J...j);}

// True: with parameters `x` and `y`, always return `x`
J t=(x,y,j)->x;
// False: with parameters `x` and `y`, always return `y`
J f=(x,y,j)->y;

// Not: with parameters `x`, `y`, and `j` (either `t` or `f`), return: j(y, x)
J n=(x,y,j)->j[0].f(y,x);

// And: with parameters `x`, `y`, and two times `j` (either `t` or `f`), return:
//      j1(j2(x,y), y);
J a=(x,y,j)->j[0].f(j[1].f(x,y),y);

// Or: with parameters `x`, `y`, and two times `j` (either `t` or `f`), return:
//     j1(x, j2(x,y))
J o=(x,y,j)->j[0].f(x,j[1].f(x,y));

// Xor: with parameters `x`, `y`, and two times `j` (either `t` or `f`), return:
//      j1(j2(y,x), j2(x,y))
J x=(x,y,j)->j[0].f(j[1].f(y,x),j[1].f(x,y));

// Implies: with parameters `x`, `y`, and two times `j` (either `t` or `f`), return:
//          j1(j2(x,y), x)
J i=(x,y,j)->j[0].f(j[1].f(x,y),x);

2

C ++ 17, 207−49 = 158 195 - 58 = 137 byte

Linebreak tidak perlu (selain dua yang pertama).

#define A auto
#define D(v,p)A v=[](A x,A y){return p;};
D(true_,x)
D(false_,y)
A not_=[](A f){return f(false_,true_);};
D(and_,x(y,false_))
D(or_,x(true_,y))
D(xor_,x(not_(y),y))
D(implies,x(y,true_))

Cobalah online!

Unit-diuji dengan pernyataan seperti:

static_assert('L' == true_('L', 'R'));
static_assert('R' == not_(true_)('L', 'R'));
static_assert('L' == and_(true_, true_)('L', 'R'));
static_assert('L' == or_(true_, true_)('L', 'R'));
static_assert('R' == xor_(true_, true_)('L', 'R'));
static_assert('L' == implies(true_, true_)('L', 'R'));

DIPERBARUI: sebelumnya saya punya

A not_=[](A f){return[f](A x,A y){return f(y,x);};};

tetapi jawaban Roman menunjuk ke versi yang lebih pendek. Perhatikan bahwa saat not_(std::plus<>)ini bentuknya buruk, di mana sebelumnya itu setara dengan std::plus<>; tetapi karena std::plus<>tidak "mewakili boolean Gereja," saya pikir perilaku tersebut tidak apa-apa menurut aturan.


Tidakkah "selain yang pertama" harus diperbarui ke "selain yang pertama"?
LF

@ LF: Benar sekali. Diperbarui. :)
Quuxplusone

2

Keempat (gforth) , 133 byte - 7 = 126 122

: j execute ;
: t drop ;
: f nip ;
: n ['] f ['] t rot j ;
: a dup j ;
: o over j ;
: x 2dup a n -rot o a ;
: m over n -rot a o ;

Cobalah 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

\ Helper function to save some bytes
: j        \ define a new word
  execute  \ execute the word at the provided address
;          \ end word definition

\ True
: t        \ define a new word
  drop     \ drop the second argument
;          \ end the word

\ False
: f        \ define a new word
  nip      \ drop the first argument
;          \ end the word

\ Not - The "hardest" one because we have to reference true and false directly
: n        \ define a new word
  ['] f    \ get address of false
  ['] t    \ get the address of true
  rot      \ stick the input boolean back on the top of the stack
  j        \ call the input boolean, which will select the boolean to return
;          \ end the word

\ And 
: a        \ define a new word
  dup      \ duplicate the 2nd input value
  j        \ call the 2nd input on the first and second input
;          \ end the word

\ Or
: o        \ define a new word
  over     \ duplicate the 1st input value
  j        \ call the 1st input on the first and second input
;          \ end the word

\ Xor
: x        \ define a new word
  2dup     \ duplicate both of the inputs
  a n      \ call and, then not the result (nand)
  -rot     \ move the result behind the copied inputs
  o a      \ call or on the original inputs, then call and on the two results
;          \ end the word

\ Implies
: m        \ define a new word
  over     \ duplicate the 1st input value
  n        \ call not on the 1st input value
  -rot     \ move results below inputs
  a o      \ call and on the two inputs, then call or on the two results
;          \ end the word

1
Anda mengulangi kata yang panjang executetiga kali. Menentukan steno : j execute ;akan menghemat 4 byte.
Quuxplusone

1

Kombinator SKI + C +, 36 byte

true=K
false=SK
not=C
and=CC(SK)
or=CIK
xor=C(CIC)I
implies=CCK

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)pqoutput q, menunjukkan bahwa Ktidak menyiratkan SK.


1

Julia 1.0 , 36 byte

(b::Bool)(x,y)=b ? x : y;i(x,y)=!x|y

Saya tidak tahu apakah itu penting, saya sebenarnya hanya overloading Booltipe asli menjadi callable, jadi saya mendapatkan sebagian besar gerbang logika gratis. Sayangnya, Julia tidak memiliki impliesgerbang, jadi saya harus menulis fungsi saya sendiri.

Cobalah online!


Saya pikir Anda masih perlu memasukkan operator yang kelebihan beban dalam kiriman Anda ... tetapi skor tidak menghitungnya, karena mereka hanya nama? Jadi itu akan menjadi +6 byte dari baris baru? Saya tidak terlalu yakin bagaimana skor bekerja dengan tantangan ini
Jo King

Saya tidak 100% yakin bagaimana cara kerjanya, tetapi harus memasukkan kode yang benar-benar tidak ada artinya bagi saya.
user3263164

Bahkan jika kode sudah dinyatakan, maka Anda masih harus memasukkannya, jika tidak setiap pengiriman bahasa golf lainnya akan menjadi nol byte. Anda tidak perlu menetapkannya untuk apa pun
Jo King

1

Perl 6 , 120 106 102 101 byte

-1 byte terima kasih kepada Jo King

my (\t,\f,&n,&a,&o,&i,&x)={@_[0]},{@_[1]},|<f,t &^v,f t,&^v &^v,t n(&^v),&v>>>.&{"&\{\&^u($_)}".EVAL}

Cobalah online!


1

C ++ 17, 202−49 = 153 193 - 58 = 135 byte

Terinspirasi 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!

#define D(v,p)auto v=[](auto x){return[=](auto y){return p;};};
D(true_,x)
D(false_,y)
D(not_,x(false_)(true_)(y))
D(and_,x(y)(false_))
D(or_,x(true_)(y))
D(xor_,x(not_(y))(y))
D(implies,x(y)(true_))

Cobalah online!

Yang ini diuji dengan pernyataan suka

static_assert('R' == and_(true_)(false_)('L')('R'));
static_assert('L' == or_(true_)(false_)('L')('R'));

Perhatikan bahwa or_didefinisikan secara efektif

auto or_=[](auto x){return[=](auto y){return x(true_)(y);};};

Kita dapat mendefinisikan or_lebih "ringkas" sebagai

auto or_=[](auto x){return x(true_);};

tapi itu akan merugikan kita karena kita tidak akan bisa menggunakan Dmakro lagi.


Karena C ++ peka huruf besar kecil, bagaimana dengan menggunakan Truedan Falsebukannya true_dan false_? Dan serupa untuk operator lainnya. Itu akan menghemat 12 byte.
G. Sliepen

@ G.Sliepen: Algoritma pemberian skor OP sudah memperhitungkan bahwa pengidentifikasi panjangnya efektif satu karakter. Kutipan: "Panjang total semua kode yang diperlukan untuk menjadikan Gereja benar dan salah dalam bahasa Anda dan juga bukan atau xor dan menyiratkan gerbang Gereja tidak termasuk nama fungsi. (Misalnya, false = lambda x, y: y dengan Python akan menjadi 13 byte). Anda dapat menggunakan kembali nama-nama ini nanti dalam kode Anda dengan mereka menghitung 1 byte menuju total byte gerbang itu. "
Quuxplusone

Ah, aku merindukan itu.
G. Sliepen

0

APL (dzaima / APL) , 47 byte SBCS

Berdasarkan solusi J Jonah .

truedan falsemerupakan fungsi infiks, notadalah operator sufiks, dan sisanya adalah operator infiks.

true←⊣
false←⊢
and←{⍺(⍶⍹false)⍵}
not←⍨
or←{⍺(true⍶⍹)⍵}
xor←{⍺(⍶not⍹⍶)⍵}
implies←{⍺(⍹⍶true)⍵}

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:

andmenggunakan fungsi tangan kanan untuk memilih hasil dari fungsi kiri jika benar, selain itu hasil dari falsefungsi.

ormenggunakan fungsi kiri untuk memilih truejika benar, selain itu hasil dari fungsi sebelah kanan .

xormenggunakan fungsi tangan kanan untuk memilih hasil yang dinegasikan dari fungsi kiri ⍶notjika benar, selain itu hasil dari fungsi kiri.

impliesmenggunakan fungsi kiri untuk memilih hasil dari fungsi tangan kanan jika benar, selain hasil truefungsi.


0

Stax , 34 byte

¿S£↓♣└²≡é♫Jíg░EèΩRΦ♂°┤rà╝¶πï╡^O|Θà

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

{sd}Y{d}{y{d}a!}X{ya!}{b!}{cx!sa!}{sx!b!}

Setiap pasangan { }adalah blok. Saya menggunakan dua register X dan Y untuk memegang truedan notsehingga saya bisa mengaksesnya dengan mudah nanti. Sayangnya, falsetidak bisa begitu saja menjadi no-op, karena itu akan membuat tumpukan berantakan dan mengacaukan satu kotak XOR.

Test suite, dikomentari

false
{sd}    stack:   x y
 s      swap:    y x
  d     discard: y

true
{d}    stack:   x y
 d     discard: x

not
{y{d}a!}    stack:  p
 y{d}       push:   p f t
     a      rotate: f t p
      !     apply:  p(f,t)

and
{ya!}    stack:  p q
 y       push:   p q f
  a      rotate: q f p
   !     apply:  p(q,f)

or
{b!}    stack:  p q
 b      copies: p q p q
  !     apply:  p q(q,p)

xor
{cx!sa!}    stack:  p q
 c          copy:   p q q
  x!        not:    p q nq
    s       swap:   p nq q
     a      rotate: nq q p
      !     apply:  p(nq,q)

implies
{sx!b!}    stack:  p q
 s         swap:   q p
  x!       not:    q np
    b      copies: q np q np
     !     apply:  q np(np,q)

0

Befunge-98 , 105 77 65 byte

Bermain 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 Ldari tumpukan dan melompat ke nomor baris L. (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 "melompati L-1garis " baris-baris dengan kode yang jauh lebih sedikit.)

Jalur 2 melambangkan Gereja FALSE. Ketika dieksekusi, muncul dua angka tdan fdari tumpukan lalu terbang ke nomor baris f.

Jalur 3 melambangkan Gereja TRUE. Ketika dieksekusi, muncul dua angka tdan fdari tumpukan lalu terbang ke nomor baris t.

Jalur 6, mewakili Gereja XOR, inovatif. Ketika dieksekusi, muncul dua angka adan bdari stack, dan kemudian terbang untuk sejalan adengan input stack NOT EXEC b. Jadi, jika amewakili Gereja TRUE, hasilnya a NOT EXEC badalah NOT b; dan jika amewakili Gereja FALSE, hasilnya a NOT EXEC badalah EXEC b.


Inilah versi yang tidak diserang dengan test harness. Pada baris 0, atur tumpukan dengan input Anda. Misalnya, 338berarti IMPLIES TRUE TRUE. Pastikan penutupan xmuncul tepat (x, y) = (0,15) atau tidak ada yang akan berhasil! Pastikan juga pengaturan tumpukan Anda dimulai ba, sehingga program akan benar-benar berakhir dengan beberapa keluaran.

Cobalah online!

>  ba 334  0f-1x
> >>1-0a-\x             Line 1: EXEC(x)(...) = goto x
> $^< <            <    Line 2: FALSE(t)(f)(...) = EXEC(f)(...)
> \$^                   Line 3: TRUE(t)(f)(...) = EXEC(t)(...)
> 3\^                   Line 4: OR(x)(y)(...) = EXEC(x)(TRUE)(y)(...)
> 3\2\^                 Line 5: NOT(x)(...) = EXEC(x)(FALSE)(TRUE)(...)
> 1\5\^                 Line 6: XOR(x)(y)(...) = EXEC(x)(NOT)(EXEC)(...)
> 2>24{\1u\1u\03-u}^    Line 7: AND(x)(y)(...) = EXEC(x)(y)(FALSE)(...)
> 3^                    Line 8: IMPLIES(x)(y)(...) = EXEC(x)(y)(TRUE)(...)

> "EURT",,,,@
> "ESLAF",,,,,@

Inilah versi yang byte-nya saya hitung.

>>>1-0a-\x
>$^<< }u-30\<
>\$^
>3\^\
>3\2^
>1\5^
>2>24{\1u\1u^
>3^

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 istilah NOTdan EXEC( 5dan 1). Tetapi semua "nama fungsi" saya hanya membutuhkan satu byte untuk diwakili. Jadi solusi ini tidak mendapat penyesuaian skor.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.