Tetris Tangrams

13

Introdução

Tangrams são um quebra-cabeça clássico que envolve a organização / montagem de blocos em várias formas. Do chinês 七巧板 - literalmente significa "sete pranchas de habilidade". Vamos pegar essa idéia e usar as sete peças de Tetrominos para preencher uma grade.

Desafio

Escreva uma função ou programa que use uma matriz de coordenadas da grade como entrada e produza uma grade completa de 10 por 20 preenchida com peças do Tetris, exceto nas coordenadas especificadas.

Otimize sua pontuação tentando manter a distribuição das peças uniforme.

Critério

Use esta pasta de coordenadas para realizar sua tarefa. Existem cinco conjuntos de coordenadas. Sinta-se livre para modificar o formato em que as coordenadas são gravadas, mas não os valores.

O conjunto de dados nº 2 não pode ser resolvido - nesse caso, basta gerar a grade com as células de entrada preenchidas (ou seja, Xonde estão os orifícios).

Entrada

As coordenadas da grade representam 'furos' na grade. São células que não podem conter nenhuma parte de um Tetromino.

Coordenadas da grade:

(0,0), (1,0), (2,0), ... (9,0)
(0,1), (1,1), (2,1), ... (9,1)
.
.
.
(0,19), (1,19), (2,19), ... (9,19)
  • Use o estilo de matriz da sua linguagem de programação de escolha para inserir as coordenadas.

  • Represente orifícios na grade com um Xou outro ASCII imprimível .

Resultado

Usando um tamanho de grade Tetris padrão de 10 células de largura por 20 células de altura , imprima uma grade de solução se e somente se a grade puder ser preenchida completa e perfeitamente usando peças Tetromino.

Peças construídas com letras I, O, L, J, T, Z, Sda seguinte forma:

I          
I          L      J
I    OO    L      J     T     ZZ      SS
I    OO    LL    JJ    TTT     ZZ    SS

Exemplo

Exemplo de solução de saída sem coordenadas de entrada:

ZZIIIILLLI
JZZTTTLLLI
JJJSTLOOLI
SZZSSLOOLI
SSZZSLLJJI
TSOOSLLJII
TTOOSSLJII
TZOOSSLZII
ZZOOSSZZII
ZJJJJSZLLI
TTTJJOOILI
ITZJJOOILI
IZZTTTLIII
IZOOTZLIII
IJOOZZLLII
LJJJZSSTII
LLLTSSTTTI
LLLTTSSZJI
OOLTSSZZJI
OOIIIIZJJI

Com distribuição da seguinte forma:

I          
I          L      J
I    OO    L      J     T     ZZ      SS
I    OO    LL    JJ    TTT     ZZ    SS

11   6     8     6      6     7      6

Notas

As coordenadas representam um único Xe Yposição na grade. A grade é baseada em 0, ou seja, a coordenada (0,0)deve ser a célula superior esquerda ou inferior esquerda, a escolha do autor.

Os tijolos podem:

  • ser selecionado a critério do autor.
  • ser rotacionado como o autor entender.
  • ser colocado na grade em qualquer lugar, a critério do autor (também conhecido como: sem gravidade Tetris)

Os tijolos não podem:

  • ser colocado fora dos limites da grade.
  • sobreponha um tijolo ou furo existente na grade.
  • ser uma peça Tetris tetromino não padrão.

Pontuação

Sua pontuação está no formato:

(1000 - [bytes no código]) * (M / 10 + 1)

Onde M é um multiplicador para a distribuição de peças usadas em seus conjuntos de soluções.

Maior pontuação dos Ides de março vence.

Para calcular M, adicione o menor valor individual de distribuição de tetromino para cada conjunto e, em seguida, calcule M. a média arredondada para baixo.

Por exemplo:

Set 1: 5
Set 2: 4
Set 3: 5
Set 4: 6
Set 5: 3

6 + 4 + 5 + 4 + 4 = 21/5 = 4,6

Então você usaria 4como seu valor M.

Nota: Se um conjunto não tiver solução, não considere esse conjunto no cálculo de M, pois não haveria distribuição tetromino.

CzarMatt
fonte
4
Melhorar as perguntas depois que elas são publicadas geralmente é difícil, porque se as alterações forem substanciais invalidarão o trabalho de pessoas que já começaram a trabalhar no problema (ou pior, até publicaram o resultado). Eu recomendaria postar idéias de desafio na sandbox . Esse é o lugar para pedir feedback e polir as especificações antes que elas entrem em funcionamento. Dito isto, depois de uma rápida olhada, não vi nenhum problema evidente em seu desafio.
Martin Ender
@ MartinBüttner Observou devidamente, obrigado pelo feedback.
CzarMatt 7/03
2
Ides de março = 15 de março. Eu tive que procurar isso.
Level River St
Fiz algumas pequenas alterações para carregar a descrição da tarefa com antecedência, porque, caso contrário, é impossível entender o que nos pedem para fazer na primeira leitura. Eu acho que seria uma melhoria se você declarasse quais dos casos de entrada não podem ser resolvidos, para que funcionem como casos de teste, além de um conjunto de dados de pontuação.
Peter Taylor
@ PeterTaylor É justo, eu adicionei qual conjunto de soluções não pode ser resolvido. Obrigado pelo feedback.
CzarMatt

Respostas:

2

Python 3 , 819 bytes, M = 0, Pontuação = 181

Este é um programa DFS de força bruta. Ele cria uma matriz numpy e insere todos os furos inseridos. Ele pega o ladrilho não preenchido mais à esquerda na linha mais alta que possui um e coloca um tetromino. Recursivamente, agora fazemos de novo - quando não conseguimos encontrar uma solução ou recuamos e tentamos outra peça na primeira oportunidade.

Isso tem um M de 0, pois tenta usar as peças em uma ordem determinada e quase sempre encontra uma solução sem a última na lista. Tentei usar uma lista ordenada aleatoriamente a cada ciclo para fazer uma distribuição mais uniforme, mas obtive apenas um M de 2, que não valia os bytes necessários para importar random.shuffle .

Não posso comentar o código abaixo, pois no meu golfe eu esqueci o que faz muito dele. A ideia geral:

  • Importar produtos numpy e itertools, com nomes de uma letra
  • Renomeie alguns builtins para serem funções de 1 letra e defina um lambda para salvar bytes
  • Construa a matriz de possíveis tetrominos como nd-matrizes numpy, todas as rotações incluídas
  • Na função recursiva:
    • Obtenha a posição do ladrilho não preenchido desejado e percorra a lista de peças
    • Para cada peça, percorra as traduções (movendo-a para cima e para baixo)
    • Se algo não funcionar (peça sai do tabuleiro, bate em outra peça, bate em um buraco, etc.), tente a próxima tradução ou a próxima peça inteira
    • Se funcionar, ótimo. Experimente e chame recursivamente a função.
    • Se esse caminho não funcionar, ele retornará 'a', então apenas tentamos novamente. Se funcionou, devolve o quadro e passamos a linha.
  • Finalmente, o programa. Construímos a placa 10x20 como uma matriz numpy de 1's.
  • A entrada é da forma (x1, y1); (x2, y2); ... Colocamos um 9 para cada orifício e obtemos o resultado de executar a função nele.
  • A declaração de impressão exibe o resultado bem-sucedido ou o original vazio, linha por linha, substituindo as letras ou símbolos apropriados pelos números.
import numpy as n
from itertools import product as e
m,s=range,len
p=[n.rot90(a,k)for a,r in[([[2,2]]*2,1),([[3]*3,[1,3,1]],4),([[0]*4],2),([[1,1,6],[6]*3],4),([[7,1,1],[7]*3],4),([[4,4,1],[1,4,4]],2),([[1,5,5],[5,5,1]],2)]for k in m(r)]
o=lambda a:e(m(s(a)),m(s(a[0])))
def t(l,d=0):
	g=list(zip(*n.where(l==1)))[0]
	for a in p:
		for u,v in o(a):
			w,x=l.copy(),0
			for r,c in o(a):
				if a[r,c]!=1:
					i,j=g[0]+r-u,g[1]+c-v
					if any([i<0,i>19,j<0,j>9])or l[i,j]!=1:
						x=1
						break
					w[i,j]=a[r,c]
			if x==0:
				if len(w[w==1]):
					f=t(w,d+1)
					if type(f)==str:continue
					return f
				return w
	return'a'
b=n.ones((20,10))
b[list(zip(*[eval(k)[::-1]for k in input().split(';')]))]=9
a=t(b)
for r in(a,b)[type(a)==str]:
	print(''.join(map(dict(zip([0,2,3,4,5,6,7,9,1],'IOTZSLJX-')).get,r)))

Experimente online!

Teste de amostra:

In: (1,1);(8,1);(4,4);(5,8);(4,11);(5,15);(1,18);(8,18)
Out: 
IIIIOOOOLL
TXOOOOOOXL
TTOOOOOOTL
TOOIOOOOTT
TOOIXOOTTI
TTTITOOTTI
TTTITTTTII
OOTTTTTTII
OOTTTXOOII
TTTTOOOOII
TTTTOOOOII
TTTTXTOOII
ITTTTTTTII
ITTTTTTTII
IITTTLLTTI
IITOOXLTTI
IITOOTLTTI
IITTLTTTTI
IXTLLTJTXI
ILLLLLJJJI
Vedvart1
fonte
1
Oh meu - isso é incrível. Obrigado pela maravilhosa escrita e bom trabalho!
CzarMatt 5/11