O básico:
Considere os seguintes tetrominós e o campo de jogo vazio:
0123456789 IOZTLSJ [] [] # ## ## ### # ## # [] # ## ## # # ## # [] # ## ## [] # [] [==========]
As dimensões do campo de jogo são fixas. Os números no topo estão aqui apenas para indicar o número da coluna (veja também a entrada).
Entrada:
1 . Você recebe um campo de jogo específico (com base no acima) que já pode ser preenchido parcialmente com tetrominós (isso pode estar em um arquivo separado ou fornecido via stdin).
Entrada de amostra:
[] [] [] [] [# # #] [## #######] [==========]
2 . Você recebe uma string que descreve (separada por espaços) qual tetrominó inserir (e drop down) em qual coluna. Os tetrominós não precisam ser girados. A entrada pode ser lida em stdin.
Entrada de amostra:
T2 Z6 I0 T7
Você pode presumir que a entrada é 'bem formada' (ou produzir um comportamento indefinido quando não está).
Resultado
Renderize o campo resultante (as linhas 'completas' devem desaparecer) e imprima a contagem de pontuação (cada linha descartada representa 10 pontos).
Saída de amostra com base na entrada de amostra acima:
[] [] [] [# ###] [# ###] [###### ####] [==========] 10
Vencedora:
Solução mais curta (por contagem de caracteres de código). Os exemplos de uso são bons. Divirta-se jogando golfe!
Edit : adicionou uma recompensa de +500
reputação para chamar um pouco mais a atenção para os bons esforços que os respondentes já fizeram (e possivelmente algumas novas soluções para esta questão) ...
fonte
Respostas:
GolfScript - 181 caracteres
Novas linhas não são necessárias. A saída está na saída padrão, embora alguns erros estejam presentes em stderr.
\10
deve ser substituído pelo caractere ASCII correspondente para que o programa tenha 181 caracteres.Amostra de E / S:
Compressão Tetromino: As
peças são armazenadas como três dígitos de base 8. Esta é uma representação binária simples, por exemplo
T=[7,2,0], S=[6,3,0], J=[2,2,3]
.[1]
é usado para aI
parte em compressão, mas é explicitamente definido para[1,1,1,1]
mais tarde (ou seja,4*
no código). Todas essas matrizes são concatenadas em uma única matriz, que é convertida em um inteiro e, em seguida, em uma string (base 126 para minimizar caracteres não imprimíveis, comprimento e não encontrar utf8). Essa seqüência é muito curto:"R@1(XBc_"
.A descompressão é então direta. Primeiro fazemos uma conversão de base 126 seguida por uma conversão de base 8 (
"~\10"{base}/
ou seja, iteramos"~\10"
e fazemos uma conversão de base para cada elemento). O array resultante é dividido em grupos de 3, o array paraI
é fixo (3/~4*
). Em seguida, convertemos cada elemento para a base 2 e (após remover zeros) substituímos cada dígito binário pelo caractere daquele índice na string" #"
(2base{" #"=}%...-1%
- observe que precisamos inverter o array, caso contrário,2
se tornaria em"# "
vez de" #"
).Formato do tabuleiro / peça, soltando peças
O tabuleiro é simplesmente um conjunto de cordas, uma para cada linha. Nenhum trabalho é feito inicialmente nisso, então podemos gerá-lo com
n/(
a entrada. As peças também são arranjos de cordas, preenchidas com espaços à esquerda para sua posição X, mas sem espaços à direita. As peças são descartadas ao se anexar à matriz e testar continuamente se há uma colisão.O teste de colisão é feito iterando-se todos os personagens da peça e comparando-os com o personagem da mesma posição no tabuleiro. Queremos considerar
#
+=
e#
+#
como colisões, então testamos se ((piecechar & 3) & boardchar) é diferente de zero. Ao fazer essa iteração, também atualizamos (uma cópia de) o tabuleiro com ((piechar & 3) | boardchar), que define corretamente o valor dos pares#
+,
+
#
,+
[
. Usamos este tabuleiro atualizado se houver uma colisão após mover a peça para outra linha.Remover linhas preenchidas é bastante simples. Removemos todas as linhas para as quais
"= "&
retornam falso. A linha cheia terá nenhum=
ou, de modo que o conjunto será uma string em branco, o que equivale a falsa. Em seguida, contamos o número de linhas que foram removidas, adicionamos a contagem à pontuação e acrescentamos essa quantidade de
"[ ... ]"
s. Nós geramos isso compactamente pegando a primeira linha da grade e substituindo#
por.
Bônus
Como calculamos a aparência do tabuleiro em cada posição da peça conforme ela cai, podemos mantê-los na pilha em vez de excluí-los! Para um total de mais três caracteres, podemos imprimir todas essas posições (ou dois caracteres se tivermos os estados do tabuleiro com espaçamento simples).
fonte
Perl,
586 523 483 472 427 407 404 386 387 356353 caracteres(Necessita do Perl 5.10 para o
//
operador definido ou ).Recebe todas as entradas de stdin.
Ainda precisa de um golfe sério.Observe que ^ Q representa ASCII 17 (DC1 / XON), ^ C representa ASCII 3 e ^ @ representa ASCII 0 (NUL).
Versão comentada:
Editar 1: golfe sério, correção de bug de saída.
Edição 2: alguns inlining, mesclaram dois loops em um para uma economia líquida de (rufar de tambores ...) 3 caracteres, golfe diverso.
Editar 3: alguma eliminação de subexpressão comum, uma pequena fusão constante e um regex ajustado.
Edição 4: mudou a representação de tetrominós em um vetor de bits compactado, golfe diverso.
Edit 5: tradução mais direta da letra do tetromino para o índice do array, use caracteres não imprimíveis, golfe diverso.
Edição 6: linha superior de limpeza de bug corrigida, introduzida em r3 (edição 2), localizada por Nakilon. Use mais caracteres não imprimíveis.
Editar 7: use
vec
para obter dados de tetromino. Aproveite o fato de que o campo de jogo tem dimensões fixas.if
declaração =>if
modificador, a fusão de loops da edição 2 começa a dar frutos. Use//
para o caso de pontuação 0.Edit 8: corrigido outro bug, introduzido no r6 (edição 5), detectado por Nakilon.
Edição 9: não crie novas referências ao limpar linhas, apenas mova as referências por meio do corte de matriz. Mesclar dois
map
em um. Regex mais inteligente. "Mais inteligente"for
. Golfe diverso.Edit 10: array tetromino embutido, versão comentada adicionada.
fonte
Ruby -
427 408 398 369359fonte
Script shell Bash (
301304 caracteres)ATUALIZAÇÃO: Corrigido um bug envolvendo peças que se estendem até a linha superior. Além disso, a saída agora é enviada para a saída padrão e, como bônus, é possível executar o script novamente para continuar jogando (nesse caso, você deve somar a pontuação total).
Isso inclui caracteres não imprimíveis, portanto, forneci um dump hexadecimal. Salve-o como
tetris.txt
:Em seguida, no prompt de comando bash, de preferência com em
elvis
vez devim
instalado comovi
:Como funciona
O código se autoextrai de maneira semelhante à maneira como os programas executáveis compactados usando o
gzexe
script fazem. As peças do Tetromino são representadas como sequências de comandos do editor vi. A contagem de caracteres é usada para detectar colisões e a contagem de linhas é usada para calcular a pontuação.O código descompactado:
O código original antes de jogar golfe:
fonte
Python:
504519 caracteres(Solução Python 3)
Atualmente requer definir a entrada no formato mostrado na parte superior (o código de entrada não é contado). Expandirei para ler o arquivo ou stdin mais tarde.Agora funciona com um prompt, basta colar a entrada (8 linhas no total).Não tenho certeza se posso economizar muito mais lá. Muitos caracteres são perdidos na transformação para bitfields, mas isso salva muito mais caracteres do que trabalhar com as strings. Além disso, não tenho certeza se posso remover mais espaços em branco, mas vou tentar mais tarde.Não conseguirá reduzir muito mais; após ter a solução baseada em bitfield, eu fiz a transição de volta para strings, pois encontrei uma maneira de compactá-la mais (economizei 8 caracteres no bitfield!). Mas dado que esqueci de incluir o
L
e tive um erro com os pontos dentro, minha contagem de personagens só aumenta suspiro ... Talvez eu encontre algo mais tarde para comprimir um pouco mais, mas acho que estou perto do fim. Para o código original e comentado, veja abaixo:Versão original:
fonte
Ruby 1.9,
357355353339330310309 charsObserve que os
\000
escapes (incluindo os bytes nulos na terceira linha) devem ser substituídos por seus equivalentes reais não imprimíveis.Entrada de amostra:
Uso:
ou
fonte
?\s
.C,
727 [...] 596 581 556 517 496 471 461457 caracteresEste é meu primeiro código de golfe, acho que a contagem de caracteres pode ficar
muitomenor, seria bom se jogadores de golfe experientes pudessem me dar algumas dicas.A versão atual também pode lidar com campos de jogo com dimensões diferentes.A entrada pode ter quebras de linha nos formatos DOS / Windows e Unix.O código era bastante direto antes da otimização, os tetrominós são armazenados em 4 inteiros que são interpretados como uma matriz de (7 * 3) x4 bits, o campo de jogo é armazenado como está, as peças são descartadas e as linhas completas são removidas no início e após cada queda da telha.
Eu não tinha certeza de como contar caracteres, então usei o tamanho do arquivo do código com todas as quebras de linha desnecessárias removidas.
EDIT 596 => 581: Graças ao KitsuneYMG, tudo exceto a
%ls
sugestão funcionou perfeitamente, além disso, percebi que emputch
vez deputchar
pode ser usado (degetch
alguma forma não funciona) e removi todos os parênteses#define G
.EDIT 581 => 556: Não estava satisfeito com os loops restantes
for
e aninhadosF
, então houve alguma fusão, alteração e remoção de loops, bastante confuso, mas definitivamente valeu a pena.EDIT 556 => 517: Finalmente encontrei uma maneira de fazer
a
um array int. Alguns seN;
fundiramc
, nãobreak
mais.EDIT 496 => 471: Largura e altura do campo de jogo corrigidas agora.
EDIT 471 => 461: Pequenas modificações,
putchar
usado novamente comoputch
não é uma função padrão.EDIT: Correção de bug, linhas completas foram removidas antes da queda do ladrilho em vez de depois , então linhas completas poderiam ser deixadas no final. Fix não altera a contagem de caracteres.
fonte
for
como#define F(x,m) for(x=0;x++<m;)
? Funciona em C # ...: PF(x,3){printf("%i",x}
imprime ao12
invés de012
com essa mudança. Pode mudar parafor(x=-1;x++<m;)
, mas isso não salva nada :)(c=getchar())
e remover todas as linhas c = N economizando 6 caracteres. A menos que eu esteja errado sobre isso, você deve baixar para 585Python 2.6+ -
334322316 caracteres397368366 caracteres descompactados#coding:l1 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
As novas linhas devem ser no estilo Unix (somente alimentação de linha). Uma nova linha à direita na última linha é opcional.
Testar:
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] # notice that I rely on the first line being blank full = '[##########]\n' for piece in board.pop().split(): column = int(piece[1]) + 1 # "+ 1" to skip the '[' at the start of the line # explanation of these three lines after the code 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: # if the current cell should be a '#' x = column + i / 4 y = drop + i % 4 board[y] = board[y][:x] + '#' + board[y][x + 1:] while full in board: # if there is a full line, score += 10 # score it, board.remove(full) # remove it, board = blank + board # and replace it with a blank line at top 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. Azip
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 chamarzip
, para queindex
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 abin
função para transformá-la em uma sequência de uns e zeros. Abin
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). Abin
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. Masbin(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 omin
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, owhile
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.fonte
Python, 298 caracteres
Vence todas as soluções de linguagem não esotérica até agora (Perl, Ruby, C, bash ...)
... e nem mesmo usa a chicana code-zip.
No exemplo de teste
isso produz
PS. consertou um bug apontado por Nakilon ao custo de +5
fonte
Golfscript 260 chars
Tenho certeza que isso poderia ser melhorado, sou meio novo no Golfscript.
O fim das linhas é relevante (não deve haver uma no final). Enfim, aqui estão alguns dos casos de teste que usei:
Observe que não há fim de linha no arquivo de entrada, um fim de linha interromperia o script como está.
fonte
O'Caml
809782 Charsfonte
Lisp comum
667 657645 caracteresMinha primeira tentativa de golfe de código, então provavelmente há muitos truques que eu ainda não conheço. Deixei algumas novas linhas lá para manter alguma "legibilidade" residual (contei as novas linhas como 2 bytes, portanto, remover 6 novas linhas desnecessárias ganha mais 12 caracteres).
Na entrada, coloque primeiro as formas e depois o campo.
Testando
fonte
Ruby
505 479 474 442 439426 charsUma primeira tentativa. Fiz isso com IronRuby. Tenho certeza que pode ser melhorado, mas eu realmente deveria trabalhar um pouco hoje!
Testando
Edite agora usando rubi normal. Peguei a saída das paredes ..
fonte
Outro em Ruby,
: **573546 caracteresTeste:
fonte
a.each{|x|s=a.max_by(&:size).size;x[s-=1]||=' 'while s>0}