Python 2.6+ - 334 322 316 caracteres
397 368 366 caracteres descompactados
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')
A única nova linha é necessária e eu a contei como um caractere.
O mumbo jumbo da página de código do navegador pode impedir um copiar e colar desse código, portanto, você pode gerar o arquivo opcionalmente a partir deste código:
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()))
Testando
Intetris
[]
[]
[]
[]
[# # #]
[## #######]
[==========]
T2 Z6 I0 T7
As novas linhas devem ser no estilo Unix (somente alimentação de linha). Uma nova linha à direita na última linha é opcional.
Testar:
> python golftris.py <intetris
[]
[]
[]
[# ###]
[# ###]
[###### ####]
[==========]
10
Este código descompacta o código original e o executa com exec
. Este código descompactado pesa 366 caracteres e se parece com isto:
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
As novas linhas são obrigatórias e têm um caractere cada.
Não tente ler este código. Os nomes das variáveis são literalmente escolhidos ao acaso em busca da compressão mais alta (com nomes de variáveis diferentes, vi até 342 caracteres após a compressão). Uma versão mais compreensível a seguir:
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
O ponto crucial está nas três linhas crípticas que eu disse que explicaria.
A forma dos tetrominós é codificada no número hexadecimal lá. Cada tetronimo é considerado ocupar uma grade 3x4 de células, onde cada célula está em branco (um espaço) ou cheia (um sinal de número). Cada peça é então codificada com 3 dígitos hexadecimais, cada dígito descrevendo uma coluna de 4 células. Os dígitos menos significativos descrevem as colunas mais à esquerda e o bit menos significativo em cada dígito descreve a célula mais alta de cada coluna. Se um bit for 0, então essa célula está em branco, caso contrário, é um '#'. Por exemplo, o I tetronimo é codificado como 00F
, com os quatro bits do dígito menos significativo definido para codificar os quatro sinais numéricos na coluna mais à esquerda, e o T é131
, com o bit superior definido à esquerda e à direita e os dois bits superiores colocados no meio.
O número hexadecimal inteiro é então deslocado um bit para a esquerda (multiplicado por dois). Isso nos permitirá ignorar a parte inferior. Vou explicar por que em um minuto.
Assim, dada a parte atual da entrada, encontramos o índice neste número hexadecimal onde os 12 bits que descrevem sua forma começam, então mudamos isso para baixo de forma que os bits 1–12 (pulando o bit 0) da bits
variável descrevem a parte atual.
A atribuição de drop
determina quantas linhas do topo da grade a peça cairá antes de pousar em outros fragmentos da peça. A primeira linha encontra quantas células vazias existem no topo de cada coluna do campo de jogo, enquanto a segunda encontra a célula ocupada mais baixa em cada coluna da peça. A zip
função retorna uma lista de tuplos, onde cada tuplo consiste em o n ° de células de cada item na lista de entrada. Então, usando a placa de entrada de amostra, zip(board[:6] + [full])
retornará:
[
('[', '[', '[', '[', '[', '[', '['),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(']', ']', ']', ']', ']', ']', ']')
]
Selecionamos a tupla dessa lista correspondente à coluna apropriada e encontramos o índice da primeira '#'
na coluna. É por isso que acrescentamos uma linha "completa" antes de chamar zip
, para que index
tenha um retorno sensato (em vez de lançar uma exceção) quando a coluna estiver em branco.
Em seguida, para encontrar o mais baixo '#'
em cada coluna da peça, deslocamos e mascaramos os quatro bits que descrevem essa coluna e, em seguida, usamos a bin
função para transformá-la em uma sequência de uns e zeros. A bin
função retorna apenas bits significativos, portanto, precisamos apenas calcular o comprimento dessa string para encontrar a célula ocupada mais baixa (bit do conjunto mais significativo). A bin
função também precede '0b'
, então temos que subtrair isso. Também ignoramos o bit menos significativo. É por isso que o número hexadecimal é deslocado um bit para a esquerda. Isso leva em conta as colunas vazias, cujas representações de string teriam o mesmo comprimento de uma coluna com apenas a célula superior cheia (como a peça T ).
Por exemplo, as colunas da I tetromino, como mencionado anteriormente, são F
, 0
e0
. bin(0xF)
é '0b1111'
. Depois de ignorar o '0b'
, temos um comprimento de 4, o que é correto. Mas bin(0x0)
é 0b0
. Depois de ignorar o '0b'
, ainda temos o comprimento '1, o que é incorreto. Para explicar isso, adicionamos um bit adicional ao final, para que possamos ignorar esse bit insignificante. Conseqüentemente, o +3
no código está lá para explicar o comprimento extra ocupado pelo '0b'
no início e o bit insignificante no final.
Tudo isso ocorre em uma expressão geradora para três colunas ( (0,1,2)
), e pegamos o min
resultado para encontrar o número máximo de linhas que a peça pode perder antes de tocar em qualquer uma das três colunas.
O resto deve ser bem fácil de entender lendo o código, mas o for
loop após essas atribuições adiciona a peça ao tabuleiro. Depois disso, o while
loop remove as linhas inteiras, substituindo-as por linhas em branco no topo, e registra a pontuação. No final, o tabuleiro e a pontuação são impressos na saída.