Можливі послідовності тетрісу


11

Напишіть код, щоб визначити, чи можна запускати фрагменти Tetris за допомогою офіційного алгоритму Tetris. Виграє найменше байт.


Офіційні ігри на тетріс по-особливому генерують послідовність падаючих шматочків. Сім штук IJLOSTZвипадають у випадковому порядку, потім випадає інша випадкова перестановка тощо.

JTLOISZ STJOLIZ LISJOTZ ...

Цей приклад містить суцільний пробіг штук

SZSTJOLIZLIS

Зауважте, що він прорізає межі групи 7. Але пробіг штук

SZOTLZSOJSIT

не може бути підрядкою будь-якої послідовності Tetris, тому її ніколи не можна побачити в офіційній грі Tetris.


Введення: Непорожній рядок літер IJLOSTZ.

Вихід: Truthy або Falsey значення для того , вхідний подстрока послідовності , яка може бути згенерована з допомогою офіційного Тетриса генератора випадкових чисел, тобто конкатенації перестановок з семи букв.

Тестові приклади:

Правда:

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

Таблиця лідерів

Людство Мартіна Бюттнера .

Відповіді:


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))*)*$

Оскільки це всього лише один регулярний вираз, Retina запуститься в режимі Match та повідомить про кількість знайдених відповідностей, що 1стосується дійсних послідовностей та в 0іншому випадку. Це не є конкурентоспроможним порівняно з мовами для гри в гольф, але я цілком задоволений цим, побачивши, що я почав чудовисько з 260 байт.

Пояснення

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

Цей біт споживає префікс унікальних літер змінної довжини, тобто відповідає потенційно неповному провідному фрагменту. Позадача забезпечує те, що жоден символ, відповідний цьому біту, раніше не з'являвся в рядку.

Тепер для решти даних ми хочемо зіставити шматки 7 без повторення символів. Ми можемо порівняти такий шматок, як цей:

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

Тобто ми співставляємо символ, який не з’являється для інших 6 символів, потім той, який не з’являється для інших 5 символів тощо. Але для цього потрібно досить жахливе повторення коду, і нам доведеться окремо узгоджувати кінцевий (потенційно неповний) фрагмент.

Балансуючі групи на допомогу! Інший спосіб узгодження

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

полягає в тому, щоб натиснути 5 порожніх сірників на стек захоплення і спробувати випорожнити його:

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

*Дозволяє як мінімум нуль повторень, точно так само як {0,5}, і тому , що ми штовхнув п'ять захоплень, він не зможе вискочити більш ніж в 5 разів або. Це більше для одного екземпляра цього шаблону, але це набагато більше для багаторазового використання. Оскільки ми робимо спливаюче вікно у негативному пошуку , це не впливає на фактичний стек після завершення пошуку. Отже, після пошуку, у нас все ще є 5 елементів на стеці, незалежно від того, що сталося всередині. Крім того, ми можемо просто вивести один елемент зі стека перед кожним lookahead та запустити код у циклі, щоб автоматично зменшити ширину lookahead від 5 до 0. Так що дійсно довгий біт там насправді може бути скорочений до

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

(Ви можете помітити дві різниці: ми натискаємо на 7 замість 5. Одне додаткове захоплення - це те, що ми з'являємося перед кожною ітерацією, а не після неї. Інша насправді необхідна, щоб ми могли вискакувати зі стека 7 разів (оскільки ми хочемо цикл, який потрібно виконати 7 разів), ми можемо виправити цю похибку по черзі всередині lookahead, гарантуючи, \1що в стеку залишився хоча б один елемент.)

Краса цього полягає в тому, що він також може відповідати останньому неповному фрагменту, тому що ми ніколи не вимагали, щоб він повторювався 7 разів (це просто необхідний максимум, тому що ми не можемо вискакувати зі стека частіше за все). Отже, все, що нам потрібно зробити, це загорнути це в інший цикл і переконатися, що ми дійшли до кінця рядка

^((.)(?<!\2.+))*((){7}((?<-4>)(.)(?!(?<-4>.)*\4\6))*)*$
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.