Trình tự Tetris có thể


11

Viết mã để tìm hiểu xem một loạt các mảnh Tetris có thể được tạo ra bằng thuật toán Tetris chính thức hay không. Ít byte nhất sẽ thắng.


Các trò chơi Tetris chính thức tạo ra chuỗi các mảnh rơi theo một cách đặc biệt. Bảy mảnh IJLOSTZđược thả theo thứ tự ngẫu nhiên, sau đó một hoán vị ngẫu nhiên khác bị loại bỏ, v.v.

JTLOISZ STJOLIZ LISJOTZ ...

Ví dụ này chứa các phần chạy liền kề

SZSTJOLIZLIS

Lưu ý rằng nó cắt ngang ranh giới của một nhóm 7. Nhưng, việc chạy các mảnh

SZOTLZSOJSIT

không thể là một chuỗi con của bất kỳ chuỗi Tetris nào, vì vậy nó không bao giờ có thể được nhìn thấy trong một trò chơi Tetris chính thức.


Đầu vào: Một chuỗi các chữ cái không trống IJLOSTZ.

Output: Một Truthy hoặc Falsey giá trị cho dù đầu vào là một chuỗi con của một chuỗi có thể được tạo ra bởi các quan chức Tetris Generator ngẫu nhiên, ví dụ của một nối hoán vị trong bảy chữ.

Các trường hợp thử nghiệm:

Thật:

T
JJ                        (unique breakdown: J J)
JTJ                     (possible breakdown: JT J)
LTOZIJS
SZSTJOLIZLIS            (possible breakdown: SZ STJOLIZ LIS)
JTLOISZSTJOLIZLISJOTZ   (possible breakdown: JTLOISZ STJOLIZ LISJOTZ)  
LIJZTSLIJZTS              (unique breakdown: LIJZTS LIJZTS)

Sai:

SZOTLZSOJSIT
ZZZ
ZIZJLJ
ZJLJLZITSOTLISOJT
JTLOISZSTJOLIZLISJOTZLJTSZLI
IOJZSITOJZST
LIJZTSLIJZTSL

Bảng xếp hạng

Phép lịch sự của Martin Büttner .

Câu trả lời:


6

Bình thường, 16 15 byte

sm*F.{Mc+>Gdz7T

In 0 cho sai, một số nguyên dương cho đúng.


6

CJam, 23 20 16 byte

q7{\+_7/_Lf|=},&

Tín dụng cho Sp3000 để cạo 4 byte!

Nó in một loạt các chữ số là một giá trị trung thực hoặc không có gì là giá trị giả (trước khi in chúng thực sự là một danh sách không trống hoặc trống, thực sự là giả và sai trong CJam).

Kiểm tra nó ở đây.

Giải trình

Điều này chỉ cần kiểm tra tất cả 7 phân vùng có thể của đầu vào thành khối.

q      e# Read the input
7{     e# Select the numbers from 0 to 6 for which the following block is true.
  \+   e#   Prepend the number to the input. This shifts the string by one cell
       e#   without adding non-unique elements.
  _7/  e#   Make a copy and split into chunks of 7.
  _Lf| e#   Remove duplicates from each chunk.
  =    e#   Check if the last operation was a no-op, i.e. that there were no duplicates.
},
&      e# The stack now contains the input with [6 5 ... 1 0] prepended as well as a list
       e# of all possible splittings. We want to get rid of the former. To do this in one
       e# byte we take the set intersection of the two: since we've prepended all the
       e# integers to the list, this will always yield the list of splittings.

4

Võng mạc , 61 55 byte

^((.)(?<!\2.+))*((){7}((?<-4>)(.)(?!(?<-4>.)*\4\6))*)*$

Vì đây chỉ là một regex duy nhất, Retina sẽ chạy trong chế độ Kết hợp và báo cáo số lượng kết quả tìm thấy, sẽ 1dành cho các chuỗi hợp lệ và mặt 0khác. Điều này không cạnh tranh so với các ngôn ngữ chơi gôn, nhưng tôi khá hài lòng với nó, khi thấy tôi bắt đầu với một con quái vật 260 byte.

Giải trình

^((.)(?<!\2.+))*

Bit này tiêu thụ một tiền tố của các chữ cái duy nhất có độ dài thay đổi, nghĩa là nó khớp với đoạn đầu có khả năng không hoàn chỉnh. Giao diện đảm bảo rằng bất kỳ ký tự nào khớp trong bit này chưa xuất hiện trong chuỗi trước đó.

Bây giờ đối với phần còn lại của đầu vào, chúng tôi muốn khớp các khối 7 mà không lặp lại các ký tự. Chúng ta có thể ghép một đoạn như thế này:

(.)(?!.{0,5}\1)(.)(?!.{0,4}\2)(.)(?!.{0,3}\3)...(.)(?!.?\5).

Tức là chúng ta ghép một ký tự không xuất hiện cho 6 ký tự khác, sau đó một ký tự không xuất hiện cho 5 ký tự khác, v.v. Nhưng điều này đòi hỏi sự lặp lại mã khá khủng khiếp và chúng ta phải ghép một đoạn riêng (có khả năng chưa hoàn thành) một cách riêng biệt.

Cân bằng các nhóm để giải cứu! Một cách khác nhau để phù hợp

(.)(?!.{0,5}\1)

là đẩy 5 trận đấu trống vào ngăn xếp chụp và thử làm trống nó:

(){5}(.)(?!(?<-1>.)*\2)

Việc này *cho phép tối thiểu 0 lần lặp lại, giống như {0,5}, và vì chúng tôi đã đẩy năm lần bắt, nó sẽ không thể bật hơn 5 lần. Cái này dài hơn cho một ví dụ của mẫu này, nhưng cái này có thể tái sử dụng nhiều hơn. Vì chúng ta đang thực hiện popping trong một cái nhìn tiêu cực , điều này không ảnh hưởng đến ngăn xếp thực tế sau khi cái nhìn hoàn thành. Vì vậy, sau khi nhìn, chúng ta vẫn có 5 yếu tố trên ngăn xếp, bất kể chuyện gì xảy ra bên trong. Hơn nữa, chúng ta có thể chỉ cần bật một phần tử từ ngăn xếp trước mỗi cái nhìn và chạy mã trong một vòng lặp, để tự động giảm độ rộng của cái nhìn từ 5 xuống còn 0. Vì vậy, bit thực sự dài có thể rút ngắn thành

(){7}((?<-1>)(.)(?!(?<-1>.)*\1\3))*

(Bạn có thể nhận thấy hai điểm khác biệt: chúng tôi đang đẩy 7 thay vì 5. Một lần chụp bổ sung là vì chúng tôi bật trước mỗi lần lặp chứ không phải sau đó. Điều khác thực sự cần thiết để chúng tôi có thể bật từ ngăn xếp 7 lần (vì chúng tôi muốn vòng lặp để chạy 7 lần), chúng ta có thể sửa lỗi tắt đó bên trong giao diện bằng cách đảm bảo \1rằng vẫn còn ít nhất một phần tử còn lại trên ngăn xếp.)

Cái hay của việc này là nó cũng có thể khớp với đoạn không hoàn chỉnh, bởi vì chúng tôi không bao giờ yêu cầu nó lặp lại 7 lần (đó chỉ là mức tối đa cần thiết, bởi vì chúng tôi không thể bật ra khỏi ngăn xếp thường xuyên hơn thế). Vì vậy, tất cả những gì chúng ta cần làm là bọc cái này trong một vòng lặp khác và đảm bảo chúng ta đã đến cuối chuỗi để có được

^((.)(?<!\2.+))*((){7}((?<-4>)(.)(?!(?<-4>.)*\4\6))*)*$
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.