ลำดับ Tetris ที่เป็นไปได้


11

เขียนโค้ดเพื่อหาว่าสามารถสร้างชิ้นส่วน Tetris ได้หรือไม่โดยอัลกอริทึมของ Tetris อย่างเป็นทางการ ไบต์ที่น้อยที่สุดจะเป็นผู้ชนะ


เกมเตตริสอย่างเป็นทางการสร้างลำดับของชิ้นส่วนล้มในวิธีพิเศษ เจ็ดชิ้นIJLOSTZจะลดลงตามลำดับแบบสุ่มจากนั้นการเปลี่ยนแปลงแบบสุ่มอีกครั้งจะลดลงและอื่น ๆ

JTLOISZ STJOLIZ LISJOTZ ...

ตัวอย่างนี้มีชิ้นส่วนที่ต่อเนื่องกัน

SZSTJOLIZLIS

โปรดทราบว่ามันตัดข้ามขอบเขตของกลุ่ม 7 แต่เรียกใช้ชิ้นส่วน

SZOTLZSOJSIT

ไม่สามารถเป็นสตริงย่อยของลำดับ Tetris ใด ๆ ดังนั้นจึงไม่สามารถมองเห็นได้ในเกม Tetris อย่างเป็นทางการ


: การป้อนข้อมูลIJLOSTZสตริงไม่ว่างเปล่าของตัวอักษร

เอาท์พุท:ค่าTruthy หรือ Falseyว่าอินพุตเป็นซับสตริงของลำดับที่สามารถสร้างขึ้นโดยเครื่องกำเนิดไฟฟ้าแบบสุ่มอย่างเป็นทางการของ Tetris หรือการเรียงลำดับของการเรียงสับเปลี่ยนของตัวอักษรเจ็ดตัว

กรณีทดสอบ:

จริง:

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)

เท็จ:

SZOTLZSOJSIT
ZZZ
ZIZJLJ
ZJLJLZITSOTLISOJT
JTLOISZSTJOLIZLISJOTZLJTSZLI
IOJZSITOJZST
LIJZTSLIJZTSL

ลีดเดอร์บอร์ด

มารยาทของมาร์ตินBüttner

คำตอบ:


6

Pyth, 16 15 ไบต์

sm*F.{Mc+>Gdz7T

พิมพ์ 0 สำหรับเท็จเป็นจำนวนเต็มบวกสำหรับจริง


6

CJam, 23 20 16 ไบต์

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

เครดิตถึง Sp3000 สำหรับการโกน 4 ไบต์!

มันพิมพ์พวงของตัวเลขเป็นค่าความจริงหรือไม่มีอะไรเป็นค่าเท็จ (ก่อนที่จะพิมพ์เหล่านี้จริง ๆ แล้วเป็นรายการที่ไม่ว่างเปล่าหรือเปล่าซึ่งเป็นความจริงและเท็จใน CJam)

ทดสอบที่นี่

คำอธิบาย

นี่แค่ตรวจสอบพาร์ติชั่นที่เป็นไปได้ทั้ง 7 ของอินพุตเป็นส่วน

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

เรติน่า , 61 55 ไบต์

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

เนื่องจากนี่เป็นเพียง regex เดียว Retina จะทำงานในโหมดจับคู่และรายงานจำนวนการจับคู่ที่พบซึ่งจะเป็น1ลำดับที่ถูกต้องและ0อื่น ๆ นี่ไม่ใช่การแข่งขันเมื่อเทียบกับภาษากอล์ฟ แต่ฉันค่อนข้างมีความสุขกับมันเพราะฉันเริ่มจากสัตว์ประหลาดขนาด 260 ไบต์

คำอธิบาย

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

บิตนี้ใช้ส่วนนำหน้าของตัวอักษรที่ไม่ซ้ำกันของความยาวผันแปรได้นั่นคือตรงกับชิ้นส่วนนำที่ไม่สมบูรณ์ lookbehind รับรองว่าอักขระใด ๆ ที่จับคู่ในบิตนี้ไม่ปรากฏในสตริงก่อน

ตอนนี้สำหรับส่วนที่เหลือของเราต้องการที่จะจับคู่ชิ้นของ 7 โดยไม่ต้องทำซ้ำตัวละคร เราสามารถจับคู่อันเช่นนี้:

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

นั่นคือเราจับคู่อักขระที่ไม่ปรากฏสำหรับอีก 6 ตัวอักษรจากนั้นตัวอักษรหนึ่งตัวที่ไม่ปรากฏอีก 5 ตัวอักษรเป็นต้น แต่สิ่งนี้ต้องใช้การทำซ้ำรหัสที่น่ากลัวมากและเราต้องแยกชิ้นส่วนต่อท้าย (อาจไม่สมบูรณ์) แยกต่างหาก

ปรับสมดุลกลุ่มเพื่อช่วยชีวิต! วิธีการจับคู่ที่แตกต่าง

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

คือการผลัก 5 แมตช์เปล่าลงในสแต็กการจับภาพและลองล้างมัน:

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

การ*อนุญาตให้ทำซ้ำขั้นต่ำเป็นศูนย์เช่นเดียวกับ{0,5}และเนื่องจากเราได้ผลักดันการจับห้าครั้งจึงไม่สามารถปรากฏได้มากกว่า 5 ครั้ง สิ่งนี้มีความยาวมากกว่าสำหรับอินสแตนซ์เดียวของรูปแบบนี้ แต่สิ่งนี้สามารถนำมาใช้ซ้ำได้มากกว่า เนื่องจากเรากำลัง popping ในlookahead เชิงลบสิ่งนี้จะไม่ส่งผลกระทบต่อ stack ที่แท้จริงเมื่อ lookahead เสร็จสิ้น ดังนั้นหลังจาก lookahead เรายังคงมี 5 องค์ประกอบในกองซ้อนไม่ว่าจะเกิดอะไรขึ้นภายใน นอกจากนี้เราสามารถป๊อปอัพองค์ประกอบหนึ่งจากสแต็คก่อนแต่ละ lookahead และเรียกใช้โค้ดในการวนรอบเพื่อลดความกว้างของ lookahead โดยอัตโนมัติจาก 5 ลงเหลือ 0 เพื่อให้บิตที่ยาวจริง ๆ นั้นสั้นลง

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

(คุณอาจสังเกตเห็นความแตกต่างสองประการ: เรากด 7 แทน 5 อีกหนึ่งการจับภาพเพิ่มเติมคือเนื่องจากเราป๊อปก่อนการทำซ้ำแต่ละครั้งไม่ใช่หลังจากนั้นอีกการจับคู่อื่นเป็นสิ่งที่จำเป็นจริง ๆ เพื่อให้เราสามารถป๊อปอัพได้จาก 7 ครั้ง วนซ้ำเพื่อรัน 7 ครั้ง) เราสามารถแก้ไขข้อผิดพลาดแบบ off-by-one ภายใน lookahead โดยตรวจสอบให้แน่ใจ\1ว่ามีองค์ประกอบอย่างน้อยหนึ่งองค์ประกอบที่เหลืออยู่ในสแต็ก)

ความงามของสิ่งนี้คือมันสามารถจับคู่กับชิ้นส่วนที่ไม่สมบูรณ์เนื่องจากเราไม่ต้องการให้ทำซ้ำ 7 ครั้ง (นั่นเป็นเพียงจำนวนสูงสุดที่จำเป็นเพราะเราไม่สามารถป๊อปอัพจากสแต็กบ่อยกว่านั้น) ดังนั้นสิ่งที่เราต้องทำคือห่อสิ่งนี้ในลูปอื่นและให้แน่ใจว่าเราถึงจุดสิ้นสุดของสตริงแล้ว

^((.)(?<!\2.+))*((){7}((?<-4>)(.)(?!(?<-4>.)*\4\6))*)*$
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.