Hexagony , 920 722 271 byte
Sáu loại vòng trái cây khác nhau, bạn nói gì? Đó là những gì Hexagony đã được thực hiện cho.
){r''o{{y\p''b{{g''<.{</"&~"&~"&<_.>/{.\.....~..&.>}<.._...=.>\<=..}.|>'%<}|\.._\..>....\.}.><.|\{{*<.>,<.>/.\}/.>...\'/../==.|....|./".<_>){{<\....._>\'=.|.....>{>)<._\....<..\..=.._/}\~><.|.....>e''\.<.}\{{\|./<../e;*\.@=_.~><.>{}<><;.(~.__..>\._..>'"n{{<>{<...="<.>../
Được rồi, không phải vậy. Chúa ơi, tôi đã làm gì với chính mình ...
Mã này bây giờ là một hình lục giác có độ dài cạnh 10 (bắt đầu từ 19). Nó có thể có thể được đánh gôn nhiều hơn, thậm chí có thể tới cỡ 9, nhưng tôi nghĩ công việc của tôi đã được thực hiện ở đây ... Để tham khảo, có 175 lệnh thực tế trong nguồn, nhiều trong số đó là các gương không cần thiết (hoặc đã được thêm vào để hủy ra một lệnh từ một con đường cắt ngang).
Mặc dù tuyến tính rõ ràng, mã thực sự là hai chiều: Hexagony sẽ sắp xếp lại thành một hình lục giác thông thường (cũng là mã hợp lệ, nhưng tất cả các khoảng trắng là tùy chọn trong Hexagony). Đây là đoạn mã chưa được mở trong tất cả ... tôi không muốn nói "vẻ đẹp":
) { r ' ' o { { y \
p ' ' b { { g ' ' < .
{ < / " & ~ " & ~ " & <
_ . > / { . \ . . . . . ~
. . & . > } < . . _ . . . =
. > \ < = . . } . | > ' % < }
| \ . . _ \ . . > . . . . \ . }
. > < . | \ { { * < . > , < . > /
. \ } / . > . . . \ ' / . . / = = .
| . . . . | . / " . < _ > ) { { < \ .
. . . . _ > \ ' = . | . . . . . > {
> ) < . _ \ . . . . < . . \ . . =
. . _ / } \ ~ > < . | . . . . .
> e ' ' \ . < . } \ { { \ | .
/ < . . / e ; * \ . @ = _ .
~ > < . > { } < > < ; . (
~ . _ _ . . > \ . _ . .
> ' " n { { < > { < .
. . = " < . > . . /
Giải trình
Tôi thậm chí sẽ không thử và bắt đầu giải thích tất cả các đường thực thi phức tạp trong phiên bản chơi gôn này, nhưng thuật toán và luồng điều khiển tổng thể giống hệt với phiên bản không được phép này có thể dễ nghiên cứu hơn cho người tò mò thực sự sau khi tôi giải thích thuật toán:
) { r ' ' o { { \ / ' ' p { . . .
. . . . . . . . y . b . . . . . . .
. . . . . . . . ' . . { . . . . . . .
. . . . . . . . \ ' g { / . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . > . . . . < . . . . . . . . .
. . . . . . . . . . . . . . > . . ) < . . . . .
. . . . . . . . . . / = { { < . . . . ( . . . . .
. . . . . . . . . . . ; . . . > . . . . . . . . . <
. . . . . . . . . . . . > < . / e ; * \ . . . . . . .
. . . . . . . . . . . . @ . } . > { } < . . | . . . . .
. . . . . / } \ . . . . . . . > < . . . > { < . . . . . .
. . . . . . > < . . . . . . . . . . . . . . . | . . . . . .
. . . . . . . . _ . . > . . \ \ " ' / . . . . . . . . . . . .
. . . . . . \ { { \ . . . > < . . > . . . . \ . . . . . . . . .
. < . . . . . . . * . . . { . > { } n = { { < . . . / { . \ . . |
. > { { ) < . . ' . . . { . \ ' < . . . . . _ . . . > } < . . .
| . . . . > , < . . . e . . . . . . . . . . . . . = . . } . .
. . . . . . . > ' % < . . . . . . . . . . . . . & . . . | .
. . . . _ . . } . . > } } = ~ & " ~ & " ~ & " < . . . . .
. . . \ . . < . . . . . . . . . . . . . . . . } . . . .
. \ . . . . . . . . . . . . . . . . . . . . . . . < .
. . . . | . . . . . . . . . . . . . . . . . . = . .
. . . . . . \ . . . . . . . . . . . . . . . . / .
. . . . . . > . . . . . . . . . . . . . . . . <
. . . . . . . . . . . . . . . . . . . . . . .
_ . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
Thú thật, trong đoạn đầu tiên tôi chỉ nói đùa một nửa. Việc chúng ta xử lý một chu kỳ gồm sáu yếu tố thực sự là một sự trợ giúp tuyệt vời. Mô hình bộ nhớ của Hexagony là một lưới lục giác vô hạn trong đó mỗi cạnh của lưới chứa một số nguyên có độ chính xác tùy ý được ký, được khởi tạo về 0.
Dưới đây là sơ đồ bố trí bộ nhớ tôi đã sử dụng trong chương trình này:
Bit thẳng dài bên trái được sử dụng như một chuỗi 0 chấm dứt a
có kích thước tùy ý được liên kết với chữ r . Các đường đứt nét trên các chữ cái khác đại diện cho cùng một loại cấu trúc, mỗi đường được xoay 60 độ. Ban đầu, con trỏ bộ nhớ trỏ vào cạnh có nhãn 1 , hướng về phía bắc.
Bit tuyến tính đầu tiên của mã đặt "ngôi sao" bên trong của các cạnh thành các chữ cái roygbp
cũng như đặt cạnh ban đầu thành 1
, để chúng ta biết nơi chu kỳ kết thúc / bắt đầu (giữa p
và r
):
){r''o{{y''g{{b''p{
Sau này, chúng tôi trở lại trên cạnh có nhãn 1 .
Bây giờ ý tưởng chung của thuật toán là:
- Đối với mỗi chữ cái trong chu trình, hãy tiếp tục đọc các chữ cái từ STDIN và, nếu chúng khác với chữ cái hiện tại, hãy thêm chúng vào chuỗi liên kết với chữ cái đó.
- Khi chúng tôi đọc bức thư chúng tôi hiện đang tìm kiếm, chúng tôi có lưu trữ
e
ở cạnh có nhãn không? , bởi vì miễn là chu trình chưa hoàn thành, chúng ta phải cho rằng chúng ta cũng sẽ phải ăn nhân vật này. Sau đó, chúng ta sẽ di chuyển vòng vòng đến nhân vật tiếp theo trong chu kỳ.
- Có hai cách mà quá trình này có thể bị gián đoạn:
- Hoặc là chúng tôi đã hoàn thành chu kỳ. Trong trường hợp này, chúng tôi thực hiện một vòng nhanh chóng khác trong chu kỳ, thay thế tất cả những người
e
trong ? cạnh với n
s, bởi vì bây giờ chúng ta muốn chu kỳ đó vẫn còn trên vòng cổ. Sau đó, chúng tôi chuyển sang in mã.
- Hoặc chúng tôi nhấn EOF (mà chúng tôi nhận ra là mã ký tự âm). Trong trường hợp này, chúng ta viết một giá trị âm vào ? cạnh của ký tự hiện tại (để chúng ta có thể dễ dàng phân biệt nó với cả hai
e
và n
). Sau đó, chúng tôi tìm kiếm cạnh 1 (để bỏ qua phần còn lại của chu trình có khả năng chưa hoàn thành) trước khi chuyển sang in mã.
- Mã in lại tiếp tục chu trình: đối với mỗi ký tự trong chu trình, nó sẽ xóa chuỗi được lưu trữ trong khi in một
e
ký tự cho mỗi ký tự. Sau đó, nó di chuyển đến ? cạnh gắn liền với nhân vật. Nếu đó là tiêu cực, chúng tôi chỉ cần chấm dứt chương trình. Nếu nó tích cực, chúng tôi chỉ cần in nó và chuyển sang ký tự tiếp theo. Khi chúng tôi hoàn thành chu trình, chúng tôi quay lại bước 2.
Một điều thú vị khác là cách tôi triển khai các chuỗi có kích thước tùy ý (vì đây là lần đầu tiên tôi sử dụng bộ nhớ không giới hạn trong Hexagony).
Hãy tưởng tượng chúng ta đang ở một thời điểm nào mà chúng ta vẫn đang đọc ký tự cho r (vì vậy chúng tôi có thể sử dụng sơ đồ như là) và a [0] và một 1 đã được lấp đầy với các nhân vật (tất cả mọi thứ về phía tây bắc của họ vẫn là zero ). Ví dụ, có lẽ chúng ta vừa đọc hai ký tự đầu tiên og
của đầu vào vào các cạnh đó và hiện đang đọc a y
.
Các nhân vật mới được đọc vào trong cạnh. Chúng tôi sử dụng ? cạnh để kiểm tra xem nhân vật này có bằng không r
. (Có một mẹo nhỏ tiện lợi ở đây: Hexagony chỉ có thể dễ dàng phân biệt giữa tích cực và không tích cực, do đó, kiểm tra sự bình đẳng thông qua phép trừ là khó chịu và yêu cầu ít nhất hai nhánh. Nhưng tất cả các chữ cái đều nhỏ hơn 2 nhân tố với nhau, vì vậy chúng ta có thể so sánh các giá trị bằng cách lấy modulo, giá trị này sẽ chỉ bằng 0 nếu chúng bằng nhau.)
Bởi vì y
khác với r
, chúng tôi di chuyển cạnh (không ghi nhãn) bên trái vào và sao chép y
ở đó. Bây giờ chúng ta di chuyển xa hơn xung quanh hình lục giác, sao chép nhân vật một cạnh hơn mỗi lần, cho đến khi chúng ta có y
cạnh trên đối diện trong . Nhưng bây giờ đã có một ký tự trong [0] mà chúng ta không muốn ghi đè lên. Thay vào đó, chúng tôi "kéo" các y
xung quanh hình lục giác tiếp theo và kiểm tra một 1 . Nhưng cũng có một nhân vật ở đó, vì vậy chúng tôi đi xa hơn một hình lục giác. Bây giờ [2] vẫn bằng không, vì vậy chúng tôi sao chépy
vào nó Con trỏ bộ nhớ bây giờ di chuyển trở lại dọc theo chuỗi về phía vòng trong. Chúng tôi biết khi nào chúng tôi đạt đến điểm bắt đầu của chuỗi, bởi vì các cạnh (không ghi nhãn) giữa một [i] đều bằng không ? tích cực.
Đây có lẽ sẽ là một kỹ thuật hữu ích để viết mã không tầm thường trong Hexagony nói chung.