Dadas 2 entradas inteiras que representam o tamanho do campo x
e y
, produz um caminho através do campo.
Exemplo de saída para 5, 4
:
#
#
# ###
### #
O campo inteiro é 5 por 4, e há um caminho feito de hashmarks cruzando o campo.
O caminho deve sempre começar no canto superior esquerdo e ir para o canto inferior direito. Todo o caminho deve ser randomizado toda vez que o programa é executado. Todo caminho válido deve ser uma saída possível.
As regras para caminhos são:
Feito de hashmarks
Todo hash é conectado apenas a outros 2 hashes (ou seja, o caminho não se cruza ou corre ao lado dele)
Os espaços não hash podem ser preenchidos com qualquer outro caractere, mas devem ser consistentes (ou seja, todos os espaços, todos os períodos etc.)
Exemplos:
2, 2
##
#
3, 4
##
##
#
#
5, 5
#####
#
#
#
#
6, 5
## ###
# # #
## # #
# ## #
### #
7, 9
#######
#
#### #
# # #
# # #
# # #
# ####
#
#######
Esse tipo de caminho é semelhante a um passeio aleatório que evita auto-evitação, no entanto, não pode ser adjacente a si mesmo, diferente de uma verdadeira SAW.
A continuidade e o toque do caminho são definidos sem diagonais.
Respostas:
MATLAB,
316 305 300293 bytesObrigado @LuisMendo por várias sugestões e um monte de bytes =)
Experimente online! (Sem garantia: observe que foram necessários alguns ajustes para executá-lo no Octave: primeiro, preciso remover a
function
palavra - chave e codificar os valores; depois: os espaços não são impressos corretamente como no Matlab. Também não verifique os comandos de convolução do Octave, que podem agir de maneira diferente.)Exemplo de saída para entrada
(7,10)
(já pode demorar um pouco):Explicação
Isso gera caminhos seqüencialmente da parte superior esquerda para a parte inferior direita com a conectividade 4 desejada e, em seguida, usa a amostragem de rejeição para rejeitar caminhos que violam o critério de que você não pode ter peças adjecentes.
Ah e como sempre:
fonte
Anterior, 344 bytes
Experimente online!
Como o @flawr mencionado na resposta do MATLAB, isso pode levar algum tempo se o tamanho do campo for de qualquer tamanho não trivial. Na verdade, é muito fácil entrar em uma situação em que não vale a pena tentar esperar que termine, porque é bem provável que você espere até o fim dos tempos.
Para entender por que isso acontece, é útil visualizar o programa em execução em um dos muitos "depuradores visuais" do Befunge. Como dados e código são a mesma coisa no Befunge, você poderá visualizar o caminho à medida que muda com o tempo. Por exemplo, aqui está uma curta animação mostrando como pode ser uma parte de uma corrida em um caminho lento.
Uma vez que o algoritmo decide fazer aquela fatídica curva para a esquerda na parte inferior do limite do campo, ele essencialmente se condenou a uma vida inteira de perambulação sem objetivo. A partir desse ponto, ele deve seguir todos os caminhos possíveis naquela área cercada antes que possa recuar e tentar a curva à direita. E o número de caminhos em potencial nesses casos pode facilmente se tornar astronômico.
Conclusão: se parece que está demorando muito tempo, provavelmente é uma boa idéia abortar a execução e começar de novo.
Explicação
Este é basicamente um algoritmo recursivo, tentando todos os caminhos possíveis através do campo e, em seguida, desenrolando as etapas que já foram seguidas sempre que ele fica preso. Como o Befunge não tem o conceito de funções, uma função recursiva está fora de questão, mas podemos emular o processo rastreando o estado na pilha.
Isso funciona preenchendo a pilha com possíveis coordenadas que podemos seguir. Depois, puxamos um conjunto da pilha e verificamos se ele é adequado (ou seja, dentro do intervalo e não se sobrepõe a um caminho existente). Depois de termos um bom lugar, escrevemos um
#
no campo de jogo nesse local e adicionamos esses detalhes à pilha, caso precisemos voltar mais tarde.Em seguida, colocamos mais quatro conjuntos de coordenadas na pilha (em ordem aleatória), indicando os possíveis caminhos que podemos seguir a partir desse novo local e voltamos ao início do loop. Se nenhum dos caminhos possíveis for possível, chegaremos ao ponto da pilha em que salvamos o local da
#
gravação, então desfazeremos essa etapa e continuaremos tentando coordenadas em potencial a partir de uma etapa anterior.É assim que o código se parece com as várias partes do componente destacadas:
Leia a largura e a altura do campo e empurre as coordenadas de início junto com um
0
marcador de tipo para indicar um caminho potencial em vez de um local de retorno.Verifique se há locais de retorno (indicados por um
1
marcador de tipo) que são revertidos com ump
comando simples , pois eles são armazenados no formato exato necessário para gravar um espaço no campo de jogo.Verifique se as coordenadas ainda estão dentro do campo de jogo. Se estiverem fora do alcance, solte-os da pilha e retorne para tentar as próximas coordenadas em potencial.
Se estiverem dentro do intervalo, obtenha os dois próximos valores da pilha, que é o local da etapa anterior (necessária no teste a seguir).
Verifique se as coordenadas entrarão em contato com um segmento existente do caminho. A localização da etapa anterior é obviamente ignorada nessa verificação.
Se todos os testes forem bem-sucedidos, escreva um
#
no campo de jogo e verifique se chegamos ao local de destino.Se tivermos, escreva o caminho final e saia.
Caso contrário, salve as coordenadas na pilha com um
1
marcador de tipo para retroceder posteriormente.Isso é interrompido com um cálculo de número aleatório que precisaremos em breve.
Envie quatro destinos em potencial que podem ser alcançados a partir do local atual. O número aleatório determina a ordem em que eles são enviados e, portanto, a ordem em que serão seguidos.
Volte ao início do loop principal e processe os próximos valores na pilha.
fonte
QBasic, 259 bytes
Eu com certeza amo
GOTO
.Estratégia básica: em cada etapa, imprima
#
a no local atual e mova-se em uma direção aleatória. Uma matriza
de 0s e 1s mantém o controle de onde estivemos. Se a mudança for legal e nos levar ao terminal,GOTO 9
para sair do loop e imprimir a final#
. Caso contrário, se a mudança for legal, dê outro passo. Senão, limpe a tela e comece de novo (muito mais golfe do que codificar um algoritmo de retorno!).Testado no meu laptop no QB64, isso geralmente produz um resultado
9, 9
em cinco segundos ou menos. As execuções10, 10
demoraram entre três e 45 segundos. Teoricamente, todos os caminhos legais têm probabilidade diferente de zero, mas a probabilidade de um caminho com grandes curvas é muito pequena. Ocasionalmente, vi caminhos com uma ou duas pequenas curvas:Versão ungolfed e / ou explicação detalhada disponíveis mediante solicitação.
fonte
R, 225 bytes
Explicação:
Geramos um gráfico não-direcionado (reticulado) [x * y] regular com pesos aleatórios nas arestas e, em seguida, encontramos o caminho mais curto do início ao fim. No entanto, no caminho gerado, pode haver células que tenham mais de dois vizinhos, por exemplo:
Portanto, devemos aplicar o algoritmo de caminho mais curto duas vezes. Na segunda vez, definimos todos os pesos para 1, exceto aqueles que estão no caminho encontrado atual e definido como 0;
resultado
Ungolfed:
fonte
JavaScript (ES7),
333331330329324 324318312 bytesExpansão:
#
s são colocados aleatoriamente na matriz até que um caminho seja encontrado através do campo usando uma pesquisa pela primeira vez; o primeiro e, portanto, o caminho mais curto, é produzido; isso garante que o caminho não se cruze. Observe que, especialmente para campos maiores, é possível exceder a pilha do mecanismo JS antes que um caminho seja encontrado. Ungolfed:fonte