No Twitch Plays Pokémon , um dos obstáculos mais irritantes que se pode enfrentar é um quebra-cabeça de gelo, onde você deve viajar de um lugar para outro deslizando todo o caminho em uma direção até atingir uma parede ou uma pedra.
Sua tarefa é criar um programa que gere um quebra-cabeça de gelo aleatório e difícil.
Seu programa vai aceitar três números, M
, N
, e P
, como entrada (com 10 <= M <= 30
, 15 <= N <= 40
e 0 <= P < 65536
):
12 18
e produzirá:
- Um
M
porN
grade consistindo em.
eO
, representando gelo e uma rocha, respectivamente. - Um marcador de posição que representa de onde o quebra-cabeça é inserido. Este marcador de posição consiste de uma letra
L
,R
,T
, ouB
, em representação da esquerda, direita, superior e inferior, seguida por um número que representa a posição (a partir da esquerda ou superior) em que o lado a ser introduzido a partir de. - Um marcador de posição semelhante que representa de onde o quebra-cabeça sai.
- A solução mais curto para o quebra-cabeças, que consiste de uma sequência de
L
,R
,U
, eD
, respectivamente.
Exemplo de saída:
..O...O...........
............O.....
..O...............
.......O..........
..................
...........O......
O..O...........O..
..........O.......
..O..........O....
........O.........
O....O.........O..
............O.....
R 4
B 5
LDLDRULD
(Note that this output is actually invalid because it is not actually long enough.)
Para uma entrada M
e N
, a solução do quebra-cabeça deve ter pelo menos min(M, N)
etapas e mover pelo menos 2 (M + N)
espaços totais. (Para referência, o quebra-cabeça acima move-se um total de 12 passos, movendo-se 69 espaços.) O gerador de quebra-cabeças deve gerar um diferente M
por N
quebra-cabeças com uma solução caminho diferente (isto é, uma sequência diferente de passos para cada solução) para cada semente P
.
- Observe que o requisito de um caminho de solução diferente é evitar soluções que tentam gerar sistematicamente caminhos de rochas, como a solução de Claudiu aqui . Se houver dois ou três pares de soluções idênticas devido a peculiaridades da aleatoriedade, tudo bem, desde que o programa não esteja tentando intencionalmente gerar sistematicamente quebra-cabeças com a mesma sequência de movimentos.
O código mais curto para executar as ações acima vence.
>
e<
(ou qualquer caractere) para a entrada e a saída? Os quebra-cabeças serão mais fáceis de ler.LDLDRULD
que é apenas 8 passos longaRespostas:
Python,
672548 caracteres, quebra-cabeças mais interessantesEmbora seguindo estritamente as regras, meu outro programa Python supera esse, decidi escrever um que gerasse quebra-cabeças mais interessantes de qualquer maneira. Aqui está:
Os níveis de recuo são espaço, tabulação, tabulação + espaço.
Amostras :
Ele é usado
P
como uma semente, para que cadaP
um gere o mesmo quebra-cabeça e cada um delesP
seja extremamente provável que seja diferente:Funciona razoavelmente rápido em tamanhos
M=25,N=40
anteriores, mas fica realmente lento. Teoricamente, deve funcionarM=30, N=40
se você permitir que ele funcione por tempo suficiente. Escrevi manualmente na trilha aqui, já que é difícil de seguir - o programa apenas mostra o quebra-cabeça.Explicação :
O programa faz um loop, gerando uma posição inicial aleatória no topo, uma posição final aleatória na parte inferior e uma grade aleatória com a
12.5%
chance de uma pedra em qualquer ponto. Em seguida, ele resolve o quebra-cabeça com uma busca pela primeira vez e, se a solução existe e é maior quemin(H,W)
, imprime e sai.fonte
Java - 2632
Enquanto admiro a pureza técnica da resposta de Claudiu , decidi tentar fazer quebra-cabeças um pouco mais difíceis;)
Etapas básicas (bastante simples):
Também marquei cada ponto como 'nogo' enquanto deslizava. Se eu acabar em um ponto nogo (ou bem na frente de um que significaria que uma pedra estava indo para lá), é um passo inválido.
Então, basicamente, a idéia é gerar aleatoriamente muitos mapas e manter o primeiro válido. Pretendo tornar isso mais inteligente (retorno, etc), mas funciona bem agora. Também pode reduzir alguns códigos redundantes, veremos.
Como é, gera mapas pequenos (15x10) quase instantaneamente, mapas médios (30x20) em alguns segundos e grandes (40x30) em uma quantidade aleatória de tempo entre 20 segundos e 20 minutos, dependendo da semente. Ele testa entre 300k-500k mapas / segundo na minha máquina, dependendo do tamanho.
Nota lateral: Às vezes, os mapas não são muito difíceis, simplesmente porque existem apenas tantas pedras quanto degraus e, a menos que o degrau o leve a uma parede, na maioria das vezes há apenas uma opção se você quiser bater em uma pedra real. Corrigirei isso mais tarde, colocando rochas "aleatórias" em locais seguros depois que todas as etapas forem traçadas. Como as manchas nogo já estão marcadas, isso deve ser bem simples. Por enquanto, aproveite estes exemplos:
Saída mostrando diferentes tamanhos / sementes:
Tamanho máximo 40x30:
Golfe:
Com quebras de linha:
fonte
while(o<3){...;o=...;}
estarfor(;o<3;o=...){...;}
salvando um byte?if(w%2<1)return new Point(f.x,f.y+i*d);else return new Point(f.x+i*d,f.y);
->return new Point(f.x+(w%2<1?0:i*d),f.y+(w%2<1?f.y:0));
.Python,
235206185176 caracteresUso :
A entrada é feita através do stdin do formulário
[M, N, P]
.Você disse que os mapas tinham que ser diferentes para cada semente
P
... e eles são:E um exemplo com um tamanho diferente:
Satisfaz todos os critérios objetivos fornecidos:
P
leva a um quebra-cabeça diferenteN + N%2
medidas, que são pelo menosN
2 (M + N)
total de espaçosExplicação :
Cada linha é construída repetindo um determinado elemento de string
W
vezes e limitando o comprimento aW
(eu usoH
e emW
vez deM
eN
).As duas primeiras linhas dependem
P
para tornar cada quebra-cabeça único. Basicamente, observe queP
se encaixa em um número inteiro não assinado de 16 bits. ConverterP
para binário, usando.
para 0 eO
para 1:O primeiro elemento da linha são os últimos 15 bits
t[1:]
, enquanto o segundo elemento da linha é o primeiro bitt[0]
,. Não pude colocar tudo em uma linha porque a largura mínima é 15, que não caberia em todos os 16 bits seP
> 32767. Portanto, as duas primeiras linhas representam exclusivamente cada um dos valores possíveis deP
.A terceira linha é uma parede completa, de modo que o valor de
P
não afeta a solução.Em seguida, siga os elementos reais do labirinto. Esta linha imprime todos eles, repetindo-os até o limite. O resultado é como você vê acima:
O resto foi apenas descobrir como resolver o labirinto gerado dinamicamente. Isso depende apenas da largura do labirinto. Observei que as soluções, para uma determinada largura, eram:
Por isso, é apenas
URDR
repetido e cortado no lugar certoW+W%2
,.fonte