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()))
Тестирование
Интетрис
[]
[]
[]
[]
[# # #]
[## ######]
[==========]
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 tetronimo кодируется как 00F
, с четырьмя битами наименее значимой цифры, установленными для кодирования четырех числовых знаков в крайнем левом столбце, а T - это131
, с верхним битом, установленным слева и справа, и двумя верхними битами, установленными в середине.
Затем все шестнадцатеричное число сдвигается на один бит влево (умножается на два). Это позволит нам игнорировать самый нижний бит. Я объясню почему через минуту.
Таким образом, учитывая текущий фрагмент из входных данных, мы находим индекс в этом шестнадцатеричном числе, где начинаются 12 бит, описывающих его форму, затем сдвигаем его вниз так, чтобы биты 1–12 (пропускающий бит 0) bits
переменной описывали текущий фрагмент.
Присваивание drop
определяет, на сколько рядов от вершины сетки упадет фигура, прежде чем она приземлится на другие фрагменты. Первая строка определяет, сколько пустых ячеек находится в верхней части каждого столбца игрового поля, а вторая находит самую низкую занятую ячейку в каждом столбце фигуры. zip
Функция возвращает список кортежей, где каждый кортеж состоит из п - й клетки от каждого элемента в списке ввода. Итак, используя образец платы ввода, zip(board[:6] + [full])
вернемся:
[
('[', '[', '[', '[', '[', '[', '['),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(']', ']', ']', ']', ']', ']', ']')
]
Мы выбираем кортеж из этого списка, соответствующий соответствующему столбцу, и находим индекс первого '#'
в столбце. Вот почему мы добавили «полную» строку перед вызовом zip
, чтобы index
получить разумный возврат (вместо выдачи исключения), когда столбец в противном случае пуст.
Затем, чтобы найти наименьшее значение '#'
в каждом столбце фрагмента, мы сдвигаем и маскируем четыре бита, которые описывают этот столбец, а затем с помощью bin
функции превращаем его в строку из единиц и нулей. bin
Функция возвращает только значащие биты, так что нам нужно только вычислить длину этой строки , чтобы найти самую низкую занятую ячейку (наиболее значимого набор бит). bin
Функция также присоединяет '0b'
, поэтому мы должны вычесть это. Мы также игнорируем младший бит. Вот почему шестнадцатеричное число сдвигается на один бит влево. Это необходимо для учета пустых столбцов, строковые представления которых будут иметь ту же длину, что и столбец с заполненной только верхней ячейкой (например, T- фрагмент).
Например, столбцы I Tetromino, как упоминалось ранее, являются F
, 0
и 0
. bin(0xF)
есть '0b1111'
. После игнорирования '0b'
мы получаем длину 4, что правильно. Но bin(0x0)
есть 0b0
. После игнорирования '0b'
мы все еще имеем длину 1, что неверно. Чтобы учесть это, мы добавили в конец дополнительный бит, чтобы мы могли игнорировать этот незначительный бит. Следовательно, +3
в коде нужно учесть дополнительную длину, занимаемую '0b'
в начале, и незначительный бит в конце.
Все это происходит в выражении генератора для трех столбцов ( (0,1,2)
), и мы берем min
результат, чтобы найти максимальное количество строк, которое кусок может отбросить, прежде чем он коснется любого из трех столбцов.
Остальное должно быть довольно легко понять, прочитав код, но for
цикл, следующий за этими назначениями, добавляет фрагмент на доску. После этого while
цикл удаляет полные строки, заменяя их пустыми наверху, и подсчитывает счет. В конце концов, доска и счет распечатываются на выходе.