BlockScript - 535
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
BlockScript là một ngôn ngữ dựa trên ngăn xếp spaghetti tầm thường mà tôi đã tạo riêng cho thử thách này. Trình thông dịch cơ sở là blockscript.c .
Chương trình mẫu (in 15 số Fibonacci đầu tiên):
{[B?B10/A!B10%d&:0}
{[B0<?'-.0B-A!:{B?Bh!{[B?B[A]A!B[B]'0+.:}!:'0.}!10.}
{[B?Dd!DC+B1-CecA!:}
0 1 15d!
;
Trình thông dịch đọc cả mã nguồn và đầu vào chương trình từ đầu vào tiêu chuẩn, theo thứ tự đó. Điều này có nghĩa là để chạy trình thông dịch trong trình thông dịch trong trình thông dịch, chỉ cần sao chép và dán:
# Level 1
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
# Level 2
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
# Level 3
{[B?B10/A!B10%d&:0}
{[B0<?'-.0B-A!:{B?Bh!{[B?B[A]A!B[B]'0+.:}!:'0.}!10.}
{[B?Dd!DC+B1-CecA!:}
0 1 15d!
;
Giống như bộ phim Inception , bạn gần như không thể đi sâu hơn ba cấp độ. Đó không phải là vấn đề thời gian, mà là không gian. BlockScript rò rỉ bộ nhớ rất nhiều và điều này liên quan đến cách ngôn ngữ được thiết kế.
Ngôn ngữ tham khảo:
Nhận thông dịch viên ở đây
Trong BlockScript, "ngăn xếp" không phải là một mảng được ghi đè bởi các hoạt động tiếp theo như bạn có thể được sử dụng. Nó thực sự được thực hiện như một danh sách liên kết bất biến, và một ngăn xếp vẫn tồn tại trong suốt thời gian của chương trình. Ngoài ra, không có toán tử (ngoại trừ @
) loại bỏ các giá trị khỏi ngăn xếp. Tuy nhiên, sửa đổi ngăn xếp chỉ ảnh hưởng đến khối mà chúng xảy ra.
Lựa chọn giá trị
a
xuyên qua z
Lấy mục 0-25 từ ngăn xếp và đẩy nó vào ngăn xếp. a
đề cập đến đầu, hoặc vật phẩm được đẩy gần đây nhất của ngăn xếp.
A
xuyên qua Z
Lấy mục 0-25 của khung hiện tại và đẩy nó vào ngăn xếp.
[
Mở "khung" để chọn các mục từ tham chiếu ngăn xếp (xem bên dưới) trên đầu ngăn xếp. [
không yêu cầu khớp ]
, nhưng các khung có phạm vi từ vựng. Trong BlockScript, "scope" được xác định bởi dấu ngoặc ( {
... }
) tạo thành khối. Do đó, việc mở một khung bên trong một khối sẽ không ảnh hưởng đến mã bên ngoài khối.
]
Đóng khung hiện tại, trở về khung trước đó (nếu có).
Khối
{
... }
Tạo một "khối" và đẩy nó vào ngăn xếp. Bên trong một khối, ngăn xếp sẽ bắt đầu ở vị trí trước khối, ngoại trừ ngăn xếp của người gọi sẽ được đẩy lên trên. Các ngăn xếp là liên tục và bất biến trong BlockScript, vì vậy các khối là các bao đóng. Thành ngữ {[
có nghĩa là mở một khối, sau đó mở một khung để bắt đầu chọn đối số (sử dụng A
thông qua Z
). Giá trị trả về của một khối là phần đầu của ngăn xếp khi }
đạt được.
Thí dụ:
'3 '2 '1 {[ b. d. f. B. C. D. A! } 'D 'C 'B d!;
Bản in này 123BCD123DCB123BCD123DCB…
. Các chữ cái viết thường đề cập đến các giá trị ngăn xếp, trong khi các chữ cái viết hoa đề cập đến các đối số (vì khung được đặt thành ngăn xếp của người gọi). A!
lấy đầu của người gọi (được đảm bảo là khối được gọi) và gọi nó. Nếu bạn đang tự hỏi tại sao nó lại đảo ngược BCD
mọi lúc, thì đó là vì B. C. D.
đẩy các đối số đó theo thứ tự ngược lại ngay trước khi khối tự gọi.
!
Gọi một khối. Đẩy giá trị trả về ngăn xếp.
Tài liệu tham khảo ngăn xếp
&
Tạo một tham chiếu ngăn xếp và đẩy nó vào ngăn xếp. Hãy nghĩ về điều này như là "siêu khuyết điểm", vì nó thực sự lấy mọi vật phẩm trên ngăn xếp và tạo thành một "tuple" từ nó. Các thành ngữ &[
có nghĩa rằng bất cứ a
, b
, c
gọi trước khi bây giờ có thể được truy cập với A
, B
, C
(đối với phần còn lại của khối hoặc cho đến khi ]
bắt gặp).
Một phần vì &
thu được nhiều giá trị hơn mức cần thiết, BlockScript rò rỉ bộ nhớ theo thiết kế.
@
Chuyển sang ngăn xếp được trỏ đến bởi tham chiếu ngăn xếp a
. Toán tử này khá kỳ lạ, nhưng trình tự thông dịch BlockScript sử dụng nó một vài lần để tránh phải đẩy các đối số tương tự hai lần. Các ảnh hưởng của @
(hoặc bất kỳ hoạt động ngăn xếp nào, đối với vấn đề đó) được giới hạn trong khối mà nó được gọi. Ngoài ra, khung không bị ảnh hưởng bởi @
vì vậy khung có thể được sử dụng để lấy các giá trị bạn cần sau khi chuyển ngăn xếp.
Biểu thức điều kiện
?
<trên đúng> :
<trên sai>
Biểu thức điều kiện, giống như toán tử ternary trong C. Nghĩa là, nếu a
là "true" (nghĩa là không bằng số nguyên 0), thì hãy làm <on true> , nếu không thì làm <on false> .
Tôi / O
Lưu ý: Đầu vào và đầu ra được thực hiện trong UTF-8. "Ký tự" là một số nguyên tương ứng với chỉ mục Unicode.
,
Lấy ký tự tiếp theo của đầu vào và đẩy nó vào ngăn xếp. Nếu kết thúc đầu vào đạt được, thay vào đó hãy ấn -1.
.
Xuất ký tự trên đầu ngăn xếp.
Số nguyên / ký tự
Lưu ý: Số nguyên và ký tự là cùng một thứ trong BlockScript.
Số học
Các toán tử này chỉ hoạt động trên các giá trị số nguyên.
+
Tính b
+ a
(đẩy kết quả, nhưng không loại bỏ một trong hai giá trị).
-
Tính toán b
- a
.
*
Tính b
* a
.
/
Tính b
/ a
(chia số nguyên; làm tròn về vô cực âm).
%
Tính b
% a
(mô đun nguyên; làm tròn về vô cực âm).
Toán tử quan hệ
Các toán tử này chỉ hoạt động trên các giá trị số nguyên.
<
Nếu b
nhỏ hơn a
, đẩy 1, khác đẩy 0.
>
=
Linh tinh
#
Nhận xét đến cuối dòng
- Chương trình phải kết thúc bằng
;
- Tất cả các nhân vật khác được bỏ qua.
/usr/bin/cat
) còn Turing-đầy đủ thì sao?