(~!)(!)((~)~*):((!)~^)*(:^)(~(!)~^(~)~*)(()~(~)~^~*)
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ị: not
khô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.
và
:((!)~^)*
( ) 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 y
thường ngắn hơn or x y = x true y
và đ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 not
lạ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
.