Nhà thờ Booleans


33

Booleans nhà thờ

Một Giáo Hội boolean là một hàm trả về xcho đúng và ycho sai ở đâu xlà đối số đầu tiên với chức năng và ylà đối số thứ hai cho hàm. Các chức năng khác có thể được tạo từ các hàm này đại diện cho các hoạt động logic and not or xorimplies.

Thử thách

Xây dựng các phép toán luận Giáo Hội và and not or xorimpliescổng nhà thờ bằng một ngôn ngữ bạn đã chọn. and orxornên nhận hai chức năng (đại diện cho booleans của Giáo hội) và trả về một chức năng (đại diện cho một boolean khác của Giáo hội). Tương tự như vậy, notnên đảo ngược hàm cần có và impliescổng sẽ thực hiện boolean hàm ý logic trong đó đối số impliesthứ nhất là thứ hai.

Chấm điểm

Tổng chiều dài của tất cả các mã cần thiết để tạo ra Church truefalsebằng ngôn ngữ của bạn và các cổng Church and not or xorimplieskhông bao gồm tên hàm. (ví dụ, false=lambda x,y:ytrong Python sẽ là 13 byte). Bạn có thể sử dụng lại các tên này sau trong mã của mình với chúng đếm 1 byte cho tổng số byte của cổng đó.

Ví dụ mã giả:

Các hàm bạn tạo sẽ có thể được gọi sau trong mã của bạn như vậy.

true(x, y) -> x
false(x, y) -> y
and(true, true)(x, y) -> x
and(true, false)(x, y) -> y
# ... etc

2
Chúng ta có phải coi các đầu vào hàm (hoặc thay thế gần nhất) là các hàm hộp đen hay chúng ta có thể kiểm tra mã bên trong không? Và các giá trị trả về của các phép toán logic phải có cùng chức năng như được xác định trước đó là các booleans của Giáo hội, hoặc chúng có thể là một thứ khác làm điều tương tự không?
Chuỗi không liên quan

1
@Jonathan ALLan Tôi đã chỉnh sửa nó để nó chính xác. Lời nhắc là như bây giờ.
Ryan Schaefer

2
Chúng ta có thể lấy danh sách như các đối số (ví dụ true([x, y]), and([true, true])([x, y]))?
ar4093

2
@RyanSchaefer Tôi nghĩ bạn nên xem xét lại việc cho phép các đối số nằm trong danh sách có thứ tự, vì người ta có thể chỉ cần bọc các đối số ở đầu các giải pháp. Tôi không nghĩ rằng đòi hỏi phải làm bất cứ điều gì để cải thiện thử thách này (thực tế tôi nghĩ rằng nó hạn chế tiềm năng chơi golf thú vị). Tất nhiên, đây chỉ là ý kiến ​​của tôi và sẽ ổn nếu bạn không đồng ý.
FryAmTheEggman

1
Việc ghi bàn khá khó hiểu. Sẽ không tốt hơn nếu để mọi người gửi các chức năng ẩn danh, nhưng nếu họ sử dụng chúng trong các phần khác, họ phải gán chúng, giống như bình thường
Jo King

Câu trả lời:


14

Tính toán Lambda nhị phân , 13.875 12.875 byte (103 bit)

Ngôn ngữ tính toán nhị phân Lambda (BLC) của John Tromp về cơ bản là một định dạng tuần tự hóa hiệu quả cho phép tính lambda. Nó rất phù hợp cho nhiệm vụ này, vì ký hiệu của Giáo hội thậm chí là cách "thành ngữ" để làm việc với các booleans trong BLC.

Tôi đã sử dụng các hàm lambda sau đây cho các tổ hợp, một số trong số đó tôi đã sao chép và đánh gôn từ câu trả lời của Haskell:, được tìm thấy bởi một tìm kiếm toàn diện với giới hạn giảm 20 cho mỗi trường hợp. Có một cơ hội tốt những điều này là ngắn nhất có thể.

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

Chúng dịch sang các chuỗi mã BLC (nhị phân) sau:

 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

Các hàm trên có tổng số 111 bit dài (13.875 byte) dài 103 bit (12.875 byte). Chúng không cần phải được căn chỉnh theo các ranh giới byte để được sử dụng trong một chương trình, do đó, việc đếm các byte phân số có ý nghĩa.

Không có mã sử dụng lại giữa các tổ hợp, bởi vì không có biến / tham chiếu / tên trong BLC - mọi thứ phải được sao chép lại. Tuy nhiên, hiệu quả của mã hóa làm cho một đại diện khá ngắn gọn.


1
Tôi không biết blc, nhưng sẽ And: (\a \b a b a)làm việc?
tsh

Có nó hoạt động. Tôi thực sự đã sử dụng công thức này cho chuỗi mã của tôi. Tôi chỉ quên cập nhật chức năng lambda tương ứng (hiện đã được sửa). Hàm tương đương hoạt động cho Or : \a \b a a b. Nó dài hơn cái tôi đã sử dụng trong BLC.
Pavel Potoček

25

Haskell , 50 - 6 = 44 byte

-1 byte nhờ Khuldraeseth na'Barya và -1 byte nhờ Christian Sievers.

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

Hãy thử trực tuyến!


2
Mặt lưu ý: bạn có thể xác định Showcác trường hợp cho constconst idvà in boolean thờ trực tiếp. Hãy thử trực tuyến! .
nimi


4
Tại sao không ai sử dụng f=n t?
Christian Sievers

3
Bạn có thể lưu một byte bằng cách sử dụng t=purethay vì t=const.
Joseph Sible-Phục hồi lại

4
@JosephSible Tôi đã thử điều đó ban đầu. Thật không may, t=puresẽ gây ra một lỗi khi tôi cố gắng áp dụng a, o, x, hoặc iđể nó. Khai báo loại tđể sửa lỗi này tốn nhiều byte hơn là chỉ sử dụng t=const.
Nitrodon

9

Python 2 , (-3?)  101  95 byte

David Beazley ăn trái tim của bạn ra!

-6 cảm ơn Chas Brown (đã chuyển phần lặp lại :thành văn bản tham gia>. <)

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

Hãy thử trực tuyến!

Tôi nghĩ rằng nó có thể là 95 - 3bởi vì tôi không tái sử dụng các chức năng A, Xhoặc I, nhưng tôi sử dụng một đĩa đơn =để chuyển nhượng (trước lambda). Có lẽ tôi không thể loại bỏ bất kỳ; tôi thậm chí có thể loại bỏ 3,5?


@Ryan Schaefer Tôi có thể xóa ba hoặc sử dụng execnghĩa của tôi không? Tôi có thể thấy đi bằng bất kỳ cách nào - tôi không sử dụng lại A, X hoặc tôi nhưng mã sẽ không hoạt động nếu không có chúng. (Có lẽ tôi thậm chí còn xóa được 3,5?!)
Jonathan Allan


Cảm ơn @Chas! Dấu hai chấm trượt qua mạng :) Công việc tốt thay thế cho -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)

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm cơ bản. Chỉnh sửa: Đã lưu 6 9 byte nhờ @tsh.


1
dường như bạn không thể khẳng định điều này như -7 từ t, f, nđược sử dụng.
tsh

1
@tsh Đó không phải là cách tôi hiểu hệ thống tính điểm; nó loại trừ rõ ràng tên trong định nghĩa, mặc dù tên trong sử dụng có giá 1 byte.
Neil

@Neil bạn không thể yêu cầu bồi thường số tiền chiết khấu byte cho tên hàm được gọi bởi mã của bạn ( t, fntrong trường hợp của bạn).
46 phút

2
@asgallant không. Nó không có byte cho tên và 1 byte khi nó được sử dụng sau này. 'T fnaox i' không có byte thì 1 byte khi được sử dụng sau này. Tôi muốn cải thiện khả năng đọc nhưng bây giờ tôi nhận ra rằng tôi nên bỏ nó hoàn toàn và đã quá muộn để thay đổi nó ngay bây giờ
Ryan Schaefer

@RyanSchaefer quy tắc đó ở đâu? Tôi chưa bao giờ thấy nó được thực hiện như thế.
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:')

Hãy thử trực tuyến!

Không biết xấu hổ ăn cắp ý tưởng lén lút đằng sau câu trả lời của Jonathan Allan ; không có byte bị trừ mặc dù.


Tôi sẽ đăng một câu trả lời cho câu hỏi của riêng tôi nhưng tôi không chắc liệu điều này có được phép hay không và tôi nghĩ rằng điều này trái với tinh thần của nó. Vì vậy, tôi nghĩ rằng tôi sẽ chỉ hướng dẫn bạn đi cùng. Thay vì sử dụng danh sách, có cách nào bạn có thể sử dụng các hàm đang được tự nhập và cách thức cụ thể mà chúng trả về đầu vào của chúng để rút ngắn mã không?
Ryan Schaefer

Tôi cá rằng mặc dù câu trả lời là có, nhưng nó sẽ dài hơn đáng kể trong Python.
Chuỗi không liên quan

Tôi đứng chính xác
Chuỗi không liên quan

@ Mr.Xcoder bạn đúng, tôi đã sai số byte cho hàm ví dụ. Họ sẽ được phép xóa 6 byte mặc dù tên của các hàm.
Ryan Schaefer

@Ông. Xcoder: Được sửa đổi theo quan sát của bạn.
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['

Hãy thử trực tuyến!

Đáng chú ý:

Các hàm bậc cao hoạt động khác nhau trong J so với ngôn ngữ hàm. Để tạo một động từ mới từ 1 hoặc 2 động từ hiện có, bạn cần sử dụng một trạng từ (trong trường hợp 1) hoặc kết hợp (trong trường hợp 2).

Cú pháp, trạng từ đến sau một động từ và liên từ đi giữa chúng. Do đó, "không" một động từ fbạn làm f n, và "và" động từ fg, bạn f a g.


4

Ngôn ngữ Wolfram ( Mathicala ) , 61-7 = 54 byte

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

Hãy thử trực tuyến!

un-golfed: lấy cảm hứng từ 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]

Khá chắc chắn các dòng mới là cần thiết để phân tách các định nghĩa chức năng. Ngoài ra, bạn tham chiếu tf và n trong các định nghĩa hàm khác để bạn không thể khấu trừ những cái đó, vì vậy 61-4 = 57.
Jonathan Allan

@Jonathan ALLan Tôi đã đọc lại hướng dẫn chấm điểm và đồng ý rằng các dòng mới sẽ được tính, cảm ơn. Tôi không đồng ý với phần thứ hai của bạn: khi tôi sử dụng lại tên, tôi thực sự tính chúng là "1 byte đối với tổng byte của cổng đó", ẩn ở đây khi tôi sử dụng tên 1 byte. Khi tôi đọc hướng dẫn, tôi không đề cập đến việc tính thêm chúng dưới dạng một byte đối với tổng định nghĩa ban đầu. Vì vậy, tôi đang đi với N-7 byte. Ngoài ra, một nhận xét khác của OP làm rõ: "Không có byte nào cho tên và 1 byte khi nó được sử dụng sau này."
La Mã

Tôi đọc "1 byte sau" có nghĩa là việc sử dụng trong một chức năng khác có giá một byte. Điều này phù hợp với cách người khác đã ghi bàn quá.
Jonathan Allan

@Jonathan ALLan Tôi ít quan tâm đến việc chú giải và nhiều hơn về chơi golf mã 😀
Roman

4

Dưới tải , 56 52 byte

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

Hãy thử trực tuyến! (bao gồm một phần kiểm tra và văn bản xác định các phần của chương trình)

Điểm số này đáng ngạc nhiên tốt cho một esolang cấp rất thấp. (Chữ số của nhà thờ, booleans của Giáo hội, v.v ... thường được sử dụng trong Underload vì lý do này; ngôn ngữ không có số và booleans được xây dựng, và đây là một trong những cách dễ dàng hơn để mô phỏng chúng. mã hóa booleans là số Giáo hội 0 và 1.)

Đối với bất kỳ ai nhầm lẫn: Underload cho phép bạn xác định các hàm có thể sử dụng lại, nhưng không cho phép bạn đặt tên cho chúng theo cách thông thường, chúng chỉ sắp xếp trôi nổi trên ngăn xếp đối số (vì vậy nếu bạn xác định năm hàm và sau đó muốn gọi hàm đầu tiên bạn đã xác định, bạn cần phải viết một hàm mới có năm đối số và gọi thứ năm trong số chúng, sau đó gọi nó với không đủ nhiều đối số để nó tìm kiếm các đối số dự phòng để sử dụng). Gọi chúng phá hủy chúng theo mặc định nhưng bạn có thể sửa đổi cuộc gọi để khiến nó không bị phá hủy (trong trường hợp đơn giản, bạn chỉ cần thêm dấu hai chấm vào cuộc gọi, mặc dù các trường hợp phức tạp là phổ biến hơn vì bạn cần đảm bảo rằng các bản sao trên ngăn xếp không cản trở bạn), vì vậy hỗ trợ chức năng của Underload có tất cả các yêu cầu chúng tôi cần từ câu hỏi.

Giải trình

thật

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

Điều này khá đơn giản; chúng tôi thoát khỏi đối số mà chúng tôi không muốn và đối số chúng tôi muốn chỉ ở đó, đóng vai trò là giá trị trả về.

sai

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

Điều này thậm chí còn đơn giản hơn.

không phải

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

Điều này thú vị: notkhông gọi đối số của nó, nó chỉ sử dụng một thành phần chức năng. Đây là một mẹo phổ biến trong Underload, trong đó bạn hoàn toàn không kiểm tra dữ liệu của mình, bạn chỉ cần thay đổi cách thức hoạt động của nó bằng cách trước và sau khi soạn thảo mọi thứ với nó. Trong trường hợp này, chúng tôi sửa đổi hàm để hoán đổi các đối số của nó trước khi chạy, điều này phủ nhận rõ ràng một số của Giáo hội.

:((!)~^)*
 (     )   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

Câu hỏi cho phép xác định chức năng theo các chức năng khác. Chúng tôi xác định "và" tiếp theo vì gần đây "không" đã được xác định, càng dễ sử dụng nó. (Điều này không trừ đi điểm số của chúng tôi, bởi vì chúng tôi hoàn toàn không đặt tên "không", nhưng nó tiết kiệm byte bằng cách viết lại định nghĩa. Đây là lần duy nhất một chức năng đề cập đến một chức năng khác, bởi vì đề cập đến bất kỳ chức năng nào nhưng định nghĩa gần đây nhất sẽ tốn quá nhiều byte.)

Định nghĩa ở đây là and x y = (not x) false y. Nói cách khác, nếu not x, sau đó chúng ta trở lại false; nếu không, chúng tôi trở lại y.

hoặc là

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

@Nitrodon đã chỉ ra trong các bình luận or x y = x x ythường ngắn hơn or x y = x true yvà điều đó cũng đúng trong Underload. Một triển khai ngây thơ của điều đó sẽ là (:~^), nhưng chúng ta có thể bỏ qua một byte bổ sung bằng cách lưu ý rằng việc chúng ta chạy đối số đầu tiên ban đầu hay bản sao của nó không thành vấn đề.

Underload không thực sự hỗ trợ cà ri theo nghĩa thông thường, nhưng các định nghĩa như thế này làm cho nó trông giống như nó! (Bí quyết là các đối số không tiêu thụ chỉ bám xung quanh, do đó, hàm bạn gọi sẽ diễn giải chúng thành các đối số của chính nó.)

ngụ ý

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

Định nghĩa được sử dụng ở đây là implies x y = not (y false x). Nếu y là đúng, điều này đơn giản hóa not false, tức là true. Nếu y sai, điều này đơn giản hóa not x, do đó cung cấp cho chúng ta bảng chân lý mà chúng ta muốn.

Trong trường hợp này, chúng tôi đang sử dụng notlại, lần này bằng cách viết lại mã của nó thay vì tham chiếu nó. Nó chỉ được viết trực tiếp như (~)~*không có dấu ngoặc đơn xung quanh nó, vì vậy nó được gọi chứ không phải được định nghĩa.

xor

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

Lần này, chúng tôi chỉ đánh giá một trong hai đối số của chúng tôi và sử dụng nó để xác định nội dung nào sẽ được soạn thảo cho đối số thứ hai. Underload cho phép bạn chơi nhanh và lỏng lẻo với arity, vì vậy chúng tôi đang sử dụng đối số đầu tiên để chọn giữa hai hàm trả về hai đối số hai đối số; hoán đổi đối số trả về cả hai nhưng theo thứ tự ngược lại và hàm nhận dạng trả về cả hai theo cùng một thứ tự.

Do đó, khi đối số thứ nhất là đúng, do đó chúng tôi tạo ra một phiên bản chỉnh sửa của đối số thứ hai hoán đổi các đối số của nó trước khi chạy, tức là tiền mã hóa với "đối số hoán đổi", tức là not. Vì vậy, một đối số đầu tiên thực sự có nghĩa là chúng ta trả lại notđối số thứ hai. Mặt khác, một đối số đầu tiên sai có nghĩa là chúng ta soạn thảo với hàm nhận dạng, tức là không làm gì cả. Kết quả là một thực hiện xor.


or x y = x x ylưu một số byte trên or x y = x true y.
Nitrodon

Underload thường phản trực giác khi thay thế bằng chữ bằng các biến được sử dụng lại, nhưng trong trường hợp này, phép biến đổi đó hóa ra để tiết kiệm nhiều byte hơn dự kiến, thay vì ít hơn. Cảm ơn sự cải thiện!
ais523


3

Java 8, điểm: 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);

Điều này là khó khăn để thực hiện hơn tôi nghĩ khi tôi bắt đầu nó .. Đặc biệt là implies. Dù sao, nó hoạt động .. Có lẽ có thể được chơi golf một chút ở đây và ở đó. EDIT: Ok, không sử dụng lại các hàm mà chỉ cần sao chép cùng một cách tiếp cận thì rẻ hơn rất nhiều về mặt đếm byte cho Java .. Và tôi cũng nhận được phần thưởng đầy đủ -7 cho việc không sử dụng bất kỳ hàm nào.

Hãy thử trực tuyến.

Giải trình:

// 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

Các ngắt dòng là không cần thiết (trừ hai phần đầu).

#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_))

Hãy thử trực tuyến!

Đơn vị được thử nghiệm với các xác nhận như:

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

CẬP NHẬT: trước đây tôi đã có

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

nhưng câu trả lời của Roman đã chỉ đường cho phiên bản ngắn hơn. Lưu ý rằng bây giờ not_(std::plus<>)là không định hình, nơi trước đây nó tương đương với std::plus<>; nhưng vì std::plus<>không "đại diện cho một boolean của Giáo hội", tôi nghĩ rằng một trong hai hành vi đều ổn theo các quy tắc.


Không nên "khác với cái đầu tiên" được cập nhật thành "khác với cái đầu tiên"?
LF

@LF: Hoàn toàn chính xác. Cập nhật. :)
Quuxplusone

2

Forth (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 ;

Hãy thử trực tuyến!

-4 byte nhờ Quuxplusone

Ban đầu tôi đã vượt qua điều này một cách đáng kể, xem xét những thứ như macro và nghĩa đen, nhưng sau đó tôi nhận ra rằng nếu tôi định nghĩa mọi thứ theo đúng và sai (như tôi nên làm ở nơi đầu tiên), nó sẽ đơn giản hơn nhiều.

Giải thích mã

\ 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
Bạn lặp lại từ dài executeba lần. Xác định tốc ký : j execute ;sẽ giúp bạn tiết kiệm 4 byte.
Quuxplusone

1

Bộ kết hợp SKI-tính toán + C, 36 byte

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

Tôi thực sự không biết bất kỳ trình thông dịch nào cho phép bạn xác định các tổ hợp bổ sung theo các phiên dịch trước đó, vì vậy tôi phải kiểm tra điều này bằng cách sử dụng http://ski.aditsu.net/ bằng cách dán vào các tổ hợp mong muốn, ví dụ như CCKK(SK)pqđầu ra q, cho thấy rằng Kkhông ngụ ý SK.


1

Julia 1.0 , 36 byte

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

Tôi không biết nếu tính như vậy, tôi thực sự chỉ đang quá tải Boolloại bản địa để có thể gọi được, vì vậy tôi nhận được hầu hết các cổng logic miễn phí. Thật không may, Julia không có impliescổng, vì vậy tôi phải viết chức năng của riêng mình.

Hãy thử trực tuyến!


Tôi nghĩ rằng bạn vẫn cần bao gồm các nhà khai thác quá tải trong trình của mình ... nhưng việc tính điểm không tính họ, vì họ chỉ là tên? Vì vậy, nó sẽ là +6 byte từ các dòng mới? Tôi không chắc chắn cách ghi điểm hoạt động với thử thách này
Jo King

Tôi cũng không chắc chắn 100% nó hoạt động như thế nào, nhưng phải bao gồm mã mà theo nghĩa đen không có nghĩa gì với tôi.
dùng3263164

Ngay cả khi mã đã được khai báo, thì bạn vẫn phải đưa nó vào, nếu không, mọi trình đệ trình ngôn ngữ golf khác sẽ là 0 byte. Bạn không cần phải gán nó cho bất cứ điều gì
Jo King


1

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

Lấy cảm hứng từ những nhận xét-thảo luận về những gì được tính là một chức năng 2-ary dù sao, đây là một cà ri phiên bản của C trước đây của tôi ++ 17 giải pháp. Nó thực sự ngắn hơn vì chúng ta có thể sử dụng cùng một macro để định nghĩa not_như để xác định tất cả các hàm khác!

#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_))

Hãy thử trực tuyến!

Cái này được kiểm tra với các xác nhận như

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

Lưu ý rằng or_được định nghĩa là có hiệu quả

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

Chúng ta có thể định nghĩa or_"chính xác" hơn là

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

nhưng điều đó sẽ khiến chúng ta phải trả giá vì chúng ta sẽ không sử dụng Dmacro nữa.


Vì C ++ phân biệt chữ hoa chữ thường, nên sử dụng TrueFalsethay vì true_false_như thế nào? Và tương tự cho các nhà khai thác khác. Điều đó sẽ tiết kiệm 12 byte.
G. Sliepen

@ G.Sliepen: Thuật toán chấm điểm của OP đã tính đến việc số nhận dạng có hiệu quả dài một ký tự. Trích dẫn: "Tổng chiều dài của tất cả các mã cần thiết để biến Church thành đúng và sai trong ngôn ngữ của bạn và không hoặc xor và ngụ ý các cổng Church không bao gồm tên của hàm. (Ví dụ: false = lambda x, y: y trong Python sẽ là 13 byte). Bạn có thể sử dụng lại các tên này sau trong mã của mình với chúng đếm 1 byte cho tổng số byte của cổng đó. "
Quuxplusone

Ah, tôi đã bỏ lỡ điều đó.
G. Sliepen

0

APL (dzaima / APL) , 47 byte SBCS

Dựa trên giải pháp J của Jonah .

truefalselà các hàm infix, notlà một toán tử hậu tố và phần còn lại là các toán tử infix.

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

Theo OP, số này đếm tất cả mọi thứ từ và bao gồm đến cuối mỗi dòng và tính mỗi cuộc gọi một định nghĩa trước đó là một byte đơn.

Hãy thử trực tuyến!

đúng và sai là các chức năng nhận dạng bên trái và bên phải.

not chỉ cần hoán đổi các đối số của hàm toán hạng của nó.

Phần còn lại thực hiện cây quyết định:

andsử dụng hàm tay phải để chọn kết quả của hàm lefthand nếu đúng, khác với kết quả của falsehàm.

orsử dụng hàm lefthand để chọn trueif true, ngược lại là kết quả của hàm righthand .

xorsử dụng hàm tay phải để chọn kết quả phủ định của hàm lefthand ⍶notnếu đúng, khác với kết quả của hàm lefthand.

impliessử dụng hàm lefthand để chọn kết quả của hàm tay phải nếu đúng, khác với kết quả của truehàm.


0

Stax , 34 byte

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

Chạy và gỡ lỗi nó tại staxlang.xyz!

Đẩy một loạt các khối để ngăn xếp. Mỗi khối mong đợi đối số cuối cùng của nó ở trên ngăn xếp, theo sau theo thứ tự ngược lại với phần còn lại.

Giải nén (41 byte):

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

Mỗi cặp { }là một khối. Tôi đã sử dụng hai thanh ghi X và Y để giữ truenotvì vậy tôi có thể dễ dàng truy cập chúng sau này. Thật không may, falsekhông thể đơn giản là không hoạt động, vì điều đó sẽ khiến ngăn xếp lộn xộn và làm hỏng một trường hợp XOR duy nhất.

Bộ kiểm tra, nhận xét

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

Chơi xa hơn với khái niệm "chức năng" trong các ngôn ngữ không có chức năng ... đây là phiên bản Befunge-98 của booleans Church!

Trong phương ngữ bị ràng buộc này của Befunge-98, một chương trình bao gồm một loạt các "dòng" hoặc "hàm", mỗi hàm bắt đầu bằng một lệnh >(Đi bên phải) trong cột x = 0. Mỗi "hàm" có thể được xác định bằng số dòng của nó (tọa độ y). Các chức năng có thể nhận đầu vào thông qua ngăn xếp của Befunge , như thường lệ.

Dòng 0 là đặc biệt, vì (0,0) là IP bắt đầu. Để tạo một chương trình thực thi dòng L, chỉ cần đặt các hướng dẫn trên dòng 0, khi được thực thi, hãy di chuyển con trỏ lệnh tới (x = L, y = 0).

Phép thuật xảy ra trên dòng 1. Dòng 1, khi được thực thi, bật một số Ltừ ngăn xếp và nhảy sang số dòng L. (Dòng này trước đây đã được > >>0{{2u2}2}$-073*-\x, mà có thể "nhảy tuyệt đối" cho bất kỳ dòng, nhưng tôi chỉ nhận ra rằng kể từ khi tôi biết dòng này được cố định vào dòng 1, chúng ta có thể "nhảy tương đối" L-1. Dòng trong một heck của rất nhiều mã ít hơn)

Dòng 2 đại diện cho Giáo hội FALSE. Khi được thực thi, nó hiện ra hai số tftừ ngăn xếp rồi bay đến số dòng f.

Dòng 3 đại diện cho Giáo hội TRUE. Khi được thực thi, nó hiện ra hai số tftừ ngăn xếp rồi bay đến số dòng t.

Dòng 6, đại diện cho Giáo hội XOR, là sáng tạo. Khi được thực thi, nó hiện ra hai số abtừ ngăn xếp, rồi bay đến dòng avới đầu vào ngăn xếp NOT EXEC b. Vì vậy, nếu ađại diện cho Giáo hội TRUE, kết quả của a NOT EXEC bsẽ là NOT b; và nếu ađại diện cho Giáo hội FALSE, kết quả của a NOT EXEC bsẽ là EXEC b.


Đây là phiên bản không có bản quyền với khai thác thử nghiệm. Trên dòng 0, thiết lập ngăn xếp với đầu vào của bạn. Ví dụ, 338phương tiện IMPLIES TRUE TRUE. Đảm bảo đóng cửa xxuất hiện chính xác (x, y) = (0,15) nếu không sẽ không có gì hoạt động! Ngoài ra, hãy đảm bảo thiết lập ngăn xếp của bạn bắt đầu bằng ba, để chương trình thực sự kết thúc với một số đầu ra.

Hãy thử trực tuyến!

>  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",,,,,@

Đây là phiên bản có byte tôi đếm.

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

Lưu ý rằng để xác định một chức năng trong phương ngữ này, bạn hoàn toàn không đề cập đến tên của nó; "tên" của nó được xác định bởi vị trí nguồn của nó. Để gọi một chức năng, bạn có đề cập đến "tên" của nó; ví dụ: XOR( 6) được định nghĩa theo NOTEXEC( 51). Nhưng tất cả "tên hàm" của tôi đã chỉ mất một byte để biểu diễn. Vì vậy, giải pháp này không được điều chỉnh điểm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.