Python 2.6+ - 334 322 316 символів
397 368 366 символів без стиснення
exec'xÚEPMO!½ï¯ i,P*Ýlš%ì‰=‰Ö–*†þz©‰:‡—Lò¾fÜ”bžAù,MVi™.ÐlǃwÁ„eQL&•uÏÔ‹¿1O6ǘ.€LSLÓ’¼›î”3òšL¸tŠv[ѵl»h;ÁºŽñÝ0Àë»Ç‡ÛûH.ª€¼âBNjr}¹„V5¾3Dë@¼¡•gO. ¾ô6 çÊsÃЮürÃ1&›ßVˆùZ`Ü€ÿžcx±ˆ‹sCàŽ êüRô{U¯ZÕDüE+³ŽFA÷{CjùYö„÷¦¯Î[0þøõ…(Îd®_›â»E#–Y%’›”ëýÒ·X‹d¼.ß9‡kD'.decode('zip')
Потрібен єдиний рядок, і я зарахував його як один символ.
Мумбо-джамбо кодової сторінки браузера може перешкодити успішному копіюванню та вставленню цього коду, тому ви можете за бажанням створити файл із цього коду:
s = """
23 63 6F 64 69 6E 67 3A 6C 31 0A 65 78 65 63 27 78 DA 45 50 4D 4F 03 21
10 BD EF AF 20 69 2C 50 2A 02 DD 6C 9A 25 EC AD 07 8D 89 07 3D 89 1C D6
96 2A 86 05 02 1B AD FE 7A A9 89 3A 87 97 4C F2 BE 66 DC 94 62 9E 41 F9
2C 4D 56 15 69 99 0F 2E D0 6C C7 83 77 C1 16 84 65 51 4C 26 95 75 CF 8D
1C 15 D4 8B BF 31 4F 01 36 C7 98 81 07 2E 80 4C 53 4C 08 D3 92 BC 9B 11
EE 1B 10 94 0B 33 F2 9A 1B 4C B8 74 8A 9D 76 5B D1 B5 6C BB 13 9D 68 3B
C1 BA 8E F1 DD 30 C0 EB BB C7 87 DB FB 1B 48 8F 2E 1C AA 80 19 BC E2 42
4E 6A 72 01 7D B9 84 56 35 BE 33 44 8F 06 EB 40 BC A1 95 67 4F 08 2E 20
BE F4 36 A0 E7 CA 73 C3 D0 AE FC 72 C3 31 26 9B DF 56 88 AD F9 5A 60 DC
80 FF 9E 63 78 B1 88 8B 73 43 E0 8E A0 EA FC 52 F4 7B 55 8D AF 5A 19 D5
44 FC 45 2B B3 8E 46 9D 41 F7 7B 43 6A 12 F9 59 F6 84 F7 A6 01 1F AF CE
5B 30 FE F8 F5 85 28 CE 64 AE 5F 9B E2 BB 45 23 96 59 25 92 9B 94 EB FD
10 D2 B7 58 8B 64 BC 2E DF 39 87 6B 44 27 2E 64 65 63 6F 64 65 28 27 7A
69 70 27 29
"""
with open('golftris.py', 'wb') as f:
f.write(''.join(chr(int(i, 16)) for i in s.split()))
Тестування
intetris
[]
[]
[]
[]
[# # #]
[## ######]
[==========]
T2 Z6 I0 T7
Нові рядки повинні бути в стилі Unix (лише подача лінії). Кінцевий новий рядок на останньому рядку необов’язковий.
Тестувати:
> python golftris.py <intetris
[]
[]
[]
[# ###]
[# ###]
[##### ####]
[==========]
10
Цей код розпаковує оригінальний код і виконує його за допомогою exec
. Цей розпакований код важить 366 символів і виглядає так:
import sys
r=sys.stdin.readlines();s=0;p=r[:1];a='[##########]\n'
for l in r.pop().split():
n=int(l[1])+1;i=0xE826408E26246206601E>>'IOZTLSJ'.find(l[0])*12;m=min(zip(*r[:6]+[a])[n+l].index('#')-len(bin(i>>4*l&31))+3for l in(0,1,2))
for l in range(12):
if i>>l&2:c=n+l/4;o=m+l%4;r[o]=r[o][:c]+'#'+r[o][c+1:]
while a in r:s+=10;r.remove(a);r=p+r
print''.join(r),s
Нові рядки обов’язкові, і вони мають по одному символу.
Не намагайтеся прочитати цей код. Імена змінних буквально вибираються випадковим чином у пошуках найвищого стиснення (з різними іменами змінних я побачив аж 342 символи після стиснення). Далі йде зрозуміліша версія:
import sys
board = sys.stdin.readlines()
score = 0
blank = board[:1]
full = '[##########]\n'
for piece in board.pop().split():
column = int(piece[1]) + 1
bits = 0xE826408E26246206601E >> 'IOZTLSJ'.find(piece[0]) * 12
drop = min(zip(*board[:6]+[full])[column + x].index('#') -
len(bin(bits >> 4 * x & 31)) + 3 for x in (0, 1, 2))
for i in range(12):
if bits >> i & 2:
x = column + i / 4
y = drop + i % 4
board[y] = board[y][:x] + '#' + board[y][x + 1:]
while full in board:
score += 10
board.remove(full)
board = blank + board
print ''.join(board), score
Суть у трьох загадкових лініях, про які я сказав, що поясню.
Форма тетроміно кодується там у шістнадцяткове число. Вважається, що кожен тетронімо займає сітку клітин 3x4, де кожна клітинка або порожня (пробіл), або повна (знак цифри). Потім кожен фрагмент кодується 3 шістнадцятковими цифрами, кожна цифра описує один 4-клітинний стовпець. Найменш значущі цифри описують крайні ліві стовпці, а найменш значущі біти в кожній цифрі описують саму верхню комірку в кожному стовпці. Якщо біт дорівнює 0, тоді ця комірка порожня, інакше це "#". Наприклад, I тетронімо кодується як 00F
, причому чотири біти найменш значущої цифри встановлені для кодування чотирьох цифрових знаків у крайньому лівому стовпці, а T дорівнює131
, причому верхній біт встановлений ліворуч і праворуч, а два верхні біти встановлені посередині.
Потім шістнадцяткове число зміщується на один біт вліво (множиться на два). Це дозволить нам ігнорувати найнижчий біт. Поясню, чому через хвилину.
Отже, враховуючи поточний фрагмент із вхідних даних, ми знаходимо індекс цього шістнадцяткового числа, де починаються 12 бітів, що описують його форму, а потім зміщують його вниз, щоб біти 1–12 (пропускаючи біт 0) bits
змінної описували поточний фрагмент.
Призначення drop
визначає, скільки рядів зверху сітки впаде шматок до посадки на інші фрагменти шматка. Перший рядок знаходить, скільки порожніх комірок є вгорі кожного стовпця ігрового поля, тоді як другий - найнижче зайняту комірку в кожному стовпці фігури. zip
Функція повертає список кортежів, де кожен кортеж складається з п - й клітини від кожного елемента в списку введення. Отже, використовуючи зразок плати введення, zip(board[:6] + [full])
поверне:
[
('[', '[', '[', '[', '[', '[', '['),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(']', ']', ']', ']', ']', ']', ']')
]
Вибираємо кортеж із цього списку, що відповідає відповідному стовпцю, і знаходимо індекс першого '#'
в стовпці. Ось чому ми додали "повний" рядок перед викликом zip
, так що index
він матиме розумне повернення (замість викиду винятку), коли стовпець порожній.
Потім, щоб знайти найнижчий '#'
у кожному стовпці фрагмента, ми зміщуємо та маскуємо чотири біти, що описують цей стовпець, а потім використовуємо bin
функцію, щоб перетворити це на рядок одиниць та нулів. bin
Функція повертає тільки значущі біти, так що нам потрібно тільки обчислити довжину цього рядка , щоб знайти найнижчу зайняту комірку (найбільш значимого набір біт). bin
Функція також приєднує '0b'
, тому ми повинні відняти це. Ми також ігноруємо найменш значущий біт. Ось чому шістнадцяткове число зміщується на один біт вліво. Це враховує порожні стовпці, подання рядків яких мали б таку саму довжину, як стовпець, лише із заповненою верхньою коміркою (наприклад, шматок Т ).
Наприклад, стовпці I Tetromino, як згадувалося раніше, є F
, 0
і 0
. bin(0xF)
є '0b1111'
. Після ігнорування '0b'
ми маємо довжину 4, що є правильною. Але bin(0x0)
є 0b0
. Після ігнорування '0b'
ми все ще маємо довжину '1, що є неправильним. Щоб це врахувати, ми додали додатковий біт до кінця, щоб ми могли ігнорувати цей незначний біт. Отже, +3
код у коді є для врахування зайвої довжини, зайнятої '0b'
на початку, і незначного біта в кінці.
Все це відбувається в виразі генератора для трьох стовпців ( (0,1,2)
), і ми беремо min
результат, щоб знайти максимальну кількість рядків, які фрагмент може скинути, перш ніж він торкнеться в будь-якому з трьох стовпців.
Решта має бути досить легко зрозуміти, читаючи код, але for
цикл, що слідує цим завданням, додає шматок на дошку. Після цього while
цикл видаляє цілі рядки, замінюючи їх пустими рядками вгорі, і підсумовує рахунок. В кінці дошка та партитура друкуються на виході.