No jogo Tetris , existem 7 tipos de tijolos ou tetr i Minoes , os quais são matematicamente conhecidos como tetr o Minoes porque eles são todos feitos com 4 segmentos quadrados:
Eles têm os nomes I, J, L, O, S, T e Z, que correspondem às suas formas aproximadas. Contando rotações de 90 °, existem 19 formas únicas no total:
I
I
I
I
IIII
J
J
JJ
JJJ
J
JJ
J
J
J
JJJ
L
L
LL
L
LLL
LL
L
L
LLL
L
OO
OO
SS
SS
S
SS
S
TTT
T
T
TT
T
T
TTT
T
TT
T
ZZ
ZZ
Z
ZZ
Z
Desafio
Escreva um bloco retangular de código que atue como o segmento base de onde são feitas essas 19 formas. Quando esse código é organizado em uma das formas, deve ser formado um programa que produza a única letra maiúscula associada a essa forma. Isso deve funcionar para todas as 19 formas.
As principais áreas vazias presentes em algumas das 19 formas são preenchidas inteiramente com espaços ( ). As áreas vazias à direita não são preenchidas com nada (portanto, os programas nem sempre são exatamente retangulares).
Exemplo
Suponha que este fosse seu bloco de código:
ABC
123
Então, qualquer disposição do bloco na peça S Tetris seria um programa que imprime S
:
ABCABC
123123
ABCABC
123123
ABC
123
ABCABC
123123
ABC
123
(Observe que todo o espaço vazio inicial é preenchido com caracteres de espaço e que nenhuma linha possui espaços à direita.)
A mesma idéia se aplica a todas as outras 6 peças e suas respectivas rotações.
Notas
- Todos os 19 programas finais devem ser executados na mesma linguagem de programação.
- Se desejar, você pode adicionar uma nova linha final à todos os programas (não apenas alguns, todos ou nenhum).
- Seu bloco de código pode conter caracteres (incluindo espaços) que não são terminadores de linha .
- Envie a carta para stdout (ou a alternativa mais próxima do seu idioma) com uma nova linha à direita opcional.
Pontuação
A submissão cujo bloco de código possui a menor área (largura x altura) vence. Isso significa essencialmente que o código mais curto vence, e é por isso que esse código é marcado como code-golf . O desempatador vai para a resposta mais votada .
O ABC\n123
exemplo tem a área 3 × 2 = 6.
Snippet
Dado um bloco de código, esse trecho irá gerar todos os 19 programas:
<script>function drawShape(X,n,v){for(var t="",e=0;e<v.length;e++)for(var l=0;l<n.length;l++){for(var r=0;r<v[e].length;r++)t+="X"===v[e][r]?n[l]:X[l];t+="\n"}return t}function go(){var X=document.getElementById("input").value;if(0!=X.length){var n=X.replace(/./g," ").split("\n");X=X.split("\n");for(var v="I (v1):|I (v2):|J (v1):|J (v2):|J (v3):|J (v4):|L (v1):|L (v2):|L (v3):|L (v4):|O:|S (v1):|S (v2):|T (v1):|T (v2):|T (v3):|T (v4):|Z (v1):|Z (v2):".split("|"),t="X\nX\nX\nX|XXXX| X\n X\nXX|XXX\n X|XX\nX\nX|X\nXXX|X\nX\nXX| X\nXXX|XX\n X\n X|XXX\nX|XX\nXX| XX\nXX|X\nXX\n X|XXX\n X|X\nXX\nX| X\nXXX| X\nXX\n X|XX\n XX| X\nXX\nX".split("|"),e="",l=0;l<v.length;l++)e+=v[l]+"\n\n"+drawShape(n,X,t[l].split("\n"))+"\n";e=e.substring(0,e.length-2),document.getElementById("output").value=e}}</script><style>html *{font-family: monospace;}</style>Code Block:<br><textarea id='input' rows='8' cols='64'>ABC
123</textarea><br><button type='button' onclick='go()'>Go</button><br><br>All 19 Programs:<br><textarea id='output' rows='24' cols='64'></textarea>
fonte
Respostas:
<> <(Peixe) - 12 * 32 = 384
Eu estava planejando buscar uma solução mais elegante, mas de alguma forma acabei com isso, que é bastante brutal:
É bem simples, verifica o código em um quadrado de 3x3 em busca de texto e usa os resultados para ver qual tetrimino corresponde à forma do código. Ainda não me esforcei muito para jogar golfe.
Experimente o código aqui (depois de usar o snippet para modelá-lo como um tetrimino)
Exemplo de código na forma Z (v1) aqui
fonte
C (gcc) ,
26x20 =52025x19 = 47523x17 = 391Fui informado recentemente dos atributos de função do GNU, e o mais interessante, o
constructor
atributo, que permite uma implementação mais concisa do que eu estava fazendo de uma maneira mais indireta na minha abordagem anterior a esse problema.O impulso da idéia é o mesmo de antes: Crie uma string e procure-a em uma lista para identificar em qual bloco de tetris o código está definido. Isso é feito chamando funções, cada uma adicionando um caractere à string. A complicação foi e continua sendo que o número de funções varia.
Definir uma função com
attribute((constructor(x)))
faz com que a função seja executada antes demain()
ser inserida, com o opcionalx
sendo a prioridade (menor significa que ela é executada anteriormente). Isso elimina a necessidade de ponteiros de função, o que nos permite eliminar uma macro, algumas declarações e a cadeia de chamada.O uso
__LINE__
da prioridade é duvidoso, pois os níveis de prioridade de 0 a 100 são reservados. No entanto, isso não resulta em erros, apenas avisos, e esses são muitos quando se joga, então o que é mais?Ajudaria a raspar outra coluna para não usar prioridades, mas a ordem de execução não parece estar definida. (Eles são revertidos neste caso, mas outros testes são inconclusivos.)
Exemplo de L v2 aqui
Abordagem mais antiga e mais portátil
Um dos meus problemas favoritos que resolvi neste site.
Comecei imaginando que cada bloco iria adivinhar suas próprias coordenadas de alguma forma. As linhas são fáceis de usar
__LINE__
e o número de blocos adjacentes horizontalmente pode ser encontrado usando o comprimento de uma cadeia de caracteres literal, assim:Pegue o comprimento da string resultante e divida por um número apropriado e você terá a largura. Infelizmente, qualquer espaço vazio antes do bloco é invisível por esse método. Eu ainda suspeitos cordas seria a solução, uma vez que os espaços em branco só tem sentido fora das cordas muito raramente, em coisas como
a+++b
vs.a+ ++b
. Eu considerei brevemente algo assim, mas não consegui encontrar nada útil. Outra possibilidade seria permitir que os identificadores fossem "colados" juntos onde os blocos se encontrassem:Eu não ficaria surpreso se isso ainda pudesse constituir uma solução interessante.
Apesar de sua simplicidade, levei algum tempo para encontrar a solução de string, baseada neste fragmento de bloco:
Se o fragmento não tiver vizinhos horizontais, a nova linha na segunda linha será escapada pela barra invertida, criando uma sequência de comprimento 2. Se, no entanto, tiver um vizinho, a barra invertida escapará da marca de aspas no início da linha 2 do próximo bloco:
Isso criará a string "\" "de comprimento 5.
Mais crucialmente, isso também permite a detecção de espaço vazio antes do bloco:
Novamente, a nova linha é escapada e o espaço em branco do bloco vazio à esquerda é incluído na sequência "" resultante de comprimento 6.
No total, existem sete configurações diferentes de blocos em uma linha com as quais precisamos nos preocupar, e todas elas formam cadeias de comprimentos únicos:
Obviamente, os blocos finais não terão tamanho tão curto, mas o princípio é o mesmo, independentemente do tamanho do bloco. Isso também tem o bônus de que um mecanismo separado para detectar a largura é desnecessário. Ao adicionar um caractere correspondente ao comprimento dessa string a uma string de resultados, cada uma das 19 configurações produz uma string única, que precisa ser comparada apenas a uma lista adequada depois que todos os blocos forem executados.
Depois que isso foi resolvido, o próximo grande problema foi como "visitar" cada linha de blocos. Em C, estamos muito limitados ao que pode ser feito fora das funções. Também precisamos
main()
aparecer, mas apenas uma vez. O último é facilmente alcançado por alguns#define
s, mas se queremos que o código dos blocos subseqüentes esteja dentromain()
, o problema de como saber quando colocar o colchete final de fechamento. Afinal, não sabemos quantas linhas de blocos serão realmente usadas. Então, precisamos termain()
estática e, de alguma forma, o resto para ser dinâmico.Se as outras linhas de bloco devem ser independentes, elas precisam ser funções, mas precisamos garantir que cada função tenha um nome exclusivo, além de ser previsível o suficiente para ser possível chamar
main()
. Também precisamos de um mecanismo para saber quais funções realmente existem para serem chamadas. A geração de nomes exclusivos é resolvida por macros auxiliares:A chamada
F
criará um identificador cujo nome começa com um f e termina com o número da linha.A
faz o mesmo, mas com um prefixo as, que é usado para a segunda parte da solução, que é ponteiros de função. Declaramos quatro desses indicadores:Como essas são declaradas como variáveis globais, elas são convenientemente definidas como NULL. Posteriormente, cada linha de bloco terá o seguinte trecho de código:
Isso primeiro declarará uma função, definirá o ponteiro de função apropriado para apontar para essa função (só podemos definir globais uma vez, mas a declaração anterior não contou como definição, mesmo se inicializou como NULL) e, em seguida, defina o real função. Isso permite
main()
chamar qualquer ponteiro de função que não seja NULL (a17 nunca será NULL):Fazer isso criará a string
r
, que é procurada na tabela de strings e, se encontrada, a letra apropriada será impressa.O único truque restante é que a lista de strings a serem comparadas era reduzida sempre que a ambiguidade pudesse ser evitada, ou strings sobrepostos podiam ser confundidos.
Exemplo de L v2 aqui
fonte
x86 opcode (.com),
8682 bytesTestador:
Fonte:
Executar em win7dos onde o init AX = 0, SI = 100, BX = 0 Referências
fonte
mov bx, 100h
no início.