Código um código Slidey Puzzle!

12

O quebra - cabeça deslizante mais reconhecível é o quebra-cabeça quinze . Ele tem uma grade de 4 por 4, 15 peças e um espaço de grade vazio. As peças só podem se mover para o espaço vazio e devem sempre estar alinhadas com a grade.

Vamos definir um quebra-cabeça deslizante generalizado como um W bidimensional de largura por H grade alta ( W , H ambos números inteiros positivos) que contém algum número de blocos idênticos não marcados (entre 0 e W × H ) encaixados na grade, organizados em de qualquer maneira (sem sobreposição), com espaços de grade vazios preenchendo o restante da área.

Por exemplo, se W e H são 3 e um bloco é Te um espaço vazio é Eum dos muitos arranjos possíveis de quebra-cabeças

TTT
TET
EET

Para estes enigmas existem 4 movimentos possíveis: empurrão tudo para cima , empurrão tudo para baixo , tudo empurrão esquerda , ou empurrão tudo certo . 'Empurrar' em alguma direção faz com que todas as peças viajem nessa direção o mais longe possível até atingirem outra peça ou o limite da grade. Às vezes, empurrar não altera o layout da grade,

Se a grade de exemplo for empurrada para a direita, o resultado será

TTT
ETT
EET

Empurrado para a esquerda, o resultado é

TTT
TTE
TEE

Empurrado para baixo, o resultado é

EET
TET
TTT

(observe que os dois mais à esquerda foram Tmovidos)

Empurrar para cima não altera o layout da grade neste caso.

Observe que, como os blocos são indistinguíveis, esses quebra-cabeças não têm estados 'resolvidos'. Observe também que um quebra-cabeça pode começar em um layout que é impossível retornar depois que um empurrão for feito (por exemplo, um bloco no meio de uma grade de 3 por 3).

Desafio

Usando apenas ASCII imprimível, grave dois blocos de código retangulares, com M caracteres de largura e N caracteres de altura (para quaisquer números inteiros positivos M , N ). Um bloco de código representará um bloco de um quebra-cabeça deslizante, o outro bloco de código representará um espaço de grade vazio.

Organizar esses dois blocos de código em uma grade W by H criará um quebra-cabeça deslizante representado por código que pode ser salvo como um arquivo de texto e executado como um programa normal. Quando executado, esse tipo de programa deve solicitar ao usuário via stdin um número de 1 a 4; 1 é para cima, 2 para baixo, 3 para a esquerda, 4 para a direita . Quando o usuário digita seu número e pressiona enter, o programa calcula como empurrar seus blocos de código-fonte nessa direção e salva o novo layout do quebra-cabeça em um arquivo (um novo arquivo ou no mesmo arquivo) e termina.

Esse processo pode ser repetido indefinidamente com o novo arquivo de código de quebra-cabeça deslizante gerado após cada empurrão.

Exemplo

Suponha que meu bloco de código de blocos seja assim

//   my
// tile

e meu bloco de código de espaço em grade vazio se parece com isso

//empty
//space

( M = 7, N = 2, é claro que este não é um código real)

Qualquer organização de quebra-cabeça deslizante válida desses dois blocos deve criar um programa no idioma que estou usando que pode ser executado para permitir que o usuário se mova em alguma direção.

A representação de código da grade de exemplo é:

//   my//   my//   my
// tile// tile// tile
//   my//empty//   my
// tile//space// tile
//empty//empty//   my
//space//space// tile

Então, executando isso e pressionando 2 (para baixo), então Enter gravaria isso em outro arquivo (ou no mesmo arquivo):

//empty//empty//   my
//space//space// tile
//   my//empty//   my
// tile//space// tile
//   my//   my//   my
// tile// tile// tile

Esse arquivo pode ser executado e empurrado da mesma maneira exata.

Notas

  • Qualquer representação de código de um quebra-cabeça deslizante W by H deve ser executável e poder se mover adequadamente. Isso inclui todos os tamanhos de grade de 1 por 1 a um máximo razoável (2 16 por 2 16 ou mais).

  • Um programa pode ler seu próprio código fonte. Não há restrições baseadas em quine. Comentários de qualquer tipo também são bons.

  • O programa deve solicitar uma direção para empurrar, mesmo que não haja peças para empurrar ou peças que não possam ser empurradas. O prompt é simplesmente um local para digitar um número, nenhuma mensagem é necessária.

  • Você pode assumir que a entrada é sempre válida (1, 2, 3 ou 4).

  • Preencher seus blocos de código com espaços é bom. Lembre-se de que eles só podem ser impressos em ASCII, isso significa que não há guias nem novas linhas (além das novas linhas que ajudam a formar os blocos de código).

  • Se o seu idioma não suportar stdin, use o método de entrada que parecer mais próximo.

  • Você pode exigir que uma nova linha esteja no final de seus arquivos de quebra-cabeças de código. (Ou exija que não esteja lá.)

  • Como você nomeia novos arquivos não é importante. f.txtou apenas festá bem.

  • Os dois blocos de código podem não ser idênticos.

Pontuação

O objetivo é fazer isso com o menor tamanho de código (é por isso que está marcado como code-golf). O envio com a menor área de bloco de código ( M × N ) é o vencedor. O desempatador vai para a resposta mais votada.

Relacionado: Código que executa o Jogo da Vida em si mesmo

Passatempos de Calvin
fonte
Portanto, o programa precisa funcionar quando há apenas espaços vazios e sem blocos de blocos (e vice-versa)?
grc
@grc Sim na sua primeira pergunta e lembre-se de que ainda é necessário solicitar um valor de shove, mesmo que totalmente vazio ou cheio. Não, os blocos não podem ser idênticos. Acho que se fossem, você poderia afirmar ter uma resposta bastante trivial. Então, eu vou mencionar isso.
Hobbies de Calvin
Posso especificar o nome do arquivo de origem original?
feersum
@feersum Como você pode assumir que é sempre f.txt? Sim.
Hobbies de Calvin
Os codeblocks não serão sempre uma linha? Os bloqueios de código de várias linhas parecem realmente complexos para mim e as linguagens 2D provavelmente não têm suporte para gravar arquivos.
Def

Respostas:

5

TECO , 153

Bloco vazio:

0T@^Ux#EBx#27@:^Ux##MxA1^QUq^T%d/51%w"G153UsZ/QqUlQq/153Un|Qq%s/153UlZ/QqUn'Qd&1UhQl<.UpQn<Qh-\"F%c'TRQs:C>QpJQn<D-%c"L%c1-Qh\|Qh\'RQs:C>Qw"GC|153%pJ'>EX

Bloco de azulejos:

1T@^Ux#EBx#27@:^Ux##MxA1^QUq^T%d/51%w"G153UsZ/QqUlQq/153Un|Qq%s/153UlZ/QqUn'Qd&1UhQl<.UpQn<Qh-\"F%c'TRQs:C>QpJQn<D-%c"L%c1-Qh\|Qh\'RQs:C>Qw"GC|153%pJ'>EX

O programa, que se modifica no local, deve ser salvo em um arquivo chamado x. Ele pode ser executado através do comando tecoc mung x.. O ponto é importante; sem ele, o TECO tentou encontrar um arquivo chamado x.tec. A nova linha à direita deve estar presente.

A restrição ASCII imprimível foi um pouco trabalhosa, pois a linguagem utiliza muitos caracteres não imprimíveis. A maioria deles pode ser substituída por uma sequência de dois bytes começando com um sinal de intercalação, mas "Escape" (ASCII 27) é o único caractere que é 'inescapável'; portanto, para obtê-lo, tive que colocar seu valor ASCII em uma string e exec it. Assim, os 4 bytes EBx<Esc>explodiram @^Ux#EBx#27@:^UX##Mx.

Isso pode ser bastante reduzido, principalmente dividindo o programa em duas partes, armazenando-os como seqüências de caracteres e executando apenas se as duas estiverem presentes.

feersum
fonte