Inspirado por We do hopping de torre e relacionado a 2D Maze Minus 1D
Introdução
Sua tarefa é encontrar o caminho mais curto para sair de um labirinto de matrizes seguindo as regras especificadas.
Desafio
Uma matriz 1D a com n elementos pode ser considerada como um labirinto composto por n pontos, onde o ponto com o índice k é conectado aos pontos com k + a [ k ] ek - a [ k ] de maneira unidirecional. Em outras palavras, você pode pular para frente ou para trás exatamente a [ k ] etapas do ponto com o índice k . Pontos com um índice fora dos limites da matriz são considerados fora do labirinto.
Para ilustrar isso, considere a seguinte matriz,
[0,8,5,9,4,1,1,1,2,1,2]
Se estamos no 5º elemento agora, já que o elemento é 4, podemos pular 4 etapas para a frente para o 9º elemento ou 4 etapas para trás para o 1º elemento. Se fizermos o último, acabaremos com o elemento 0, que indica que não são possíveis outros movimentos. Se fizermos o primeiro, já que o 9º elemento é 2, podemos optar por pular para o 11º elemento, que é novamente um 2, e depois podemos pular novamente para o "13º elemento", que está fora dos limites do matriz e considerado uma saída para o labirinto.
Portanto, se começarmos do elemento do meio, uma maneira de sair do labirinto é dar um passo para trás, quatro passos para frente, dois passos para frente e novamente dois passos para frente, que podem ser expressos como a matriz [-1,4,2,2]
. Como alternativa, você pode expressá-lo com a matriz [4,8,10,12]
que registra o índice baseado em zero de todos os pontos intermediários e finais (o índice baseado em 1 também é bom) ou apenas os sinais [-1,1,1,1]
.
Escapar do labirinto a partir do final de baixo índice também é bom.
O uso da primeira notação e a partir do mesmo elemento [1,1,1,2,2]
também é uma solução, mas não é ideal, pois há 5 etapas em vez de 4.
A tarefa é descobrir o caminho mais curto para sair do labirinto da matriz e gerar o caminho. Se houver mais de um caminho ideal, você poderá gerar um ou todos eles. Se não houver solução, você deve gerar um valor falso escolhido por você que seja discernível a partir de um caminho válido (não produzir nenhuma saída também é bom).
Por simplicidade, o número de elementos na matriz é sempre um número ímpar e sempre começamos a partir do elemento no meio.
Casos de teste
Os casos de teste ilustram várias formas de saída, mas você não está limitado a elas.
Input
Output
[0,8,5,9,4,1,1,1,2,1,2]
[-1,4,2,2]
[2,3,7,1,2,0,2,8,9]
[2,9] (or [2,-5] or [[2,9],[2,-5]])
[0,1,2,2,3,4,4,4,3,2,2,3,0]
[1,-1,1,1]
[0,1,2,2,4,4,6,6,6,6,6,4,2,1,2,2,0]
[]
Especificações
Você pode escrever uma função ou um programa completo.
A matriz contém apenas números inteiros não negativos.
Você pode receber e enviar informações através de qualquer formulário padrão , mas especifique na sua resposta qual formulário você está usando.
Isso é código-golfe , o menor número de bytes vence.
Como sempre, as brechas padrão se aplicam aqui.
fonte
[0,8,5,9,4,1,1,1,2,1,2]
, saída[[-1,4,2,2]]
)[1,1,1,-1]
invés de[-1,1,1,1]
?Respostas:
JavaScript (ES6), 117 bytes
Retorna uma matriz de pontos intermediários e finais indexados a 0 ou uma matriz vazia, se não houver solução.
Experimente online!
Comentado
fonte
Casca , 22 bytes
Retorna uma lista de sinais ou uma lista vazia se uma solução não existir. Experimente online!
Explicação
Esta é uma solução de força bruta que verifica listas com
-1,0,1
comprimento cada vez maior e retorna a primeira que resulta em um salto para fora da matriz. Como é de tamanho mínimo, não conterá 0s.fonte
Python 3 ,
195188179 bytesExperimente online!
Editar:
all(..)and s => all(..)*s
:if u not in x => if{u}-x
O primeiro explora
boolean * list == int * list
, o último usa a diferença do conjunto (o conjunto vazio também é falso).Formato de saída: matriz aninhada de todas as respostas ideais, dados como índices baseados em zero de pontos intermediários e finais.
Por exemplo:
f([0,8,5,9,4,1,1,1,2,1,2]) == [[4, 8, 10, 12]]
.O algoritmo é simples BFS.
s
registra todos osi
caminhos de comprimento possível nai
iteração, excluindo os índices já visitados. Observe que a notação estendida em estrela é (ab) usada porque o acesso repetido à matriz é caro. Descobri que essa notação também pode reduzir alguns espaços em branco se usada corretamente.Também fiz uma versão recursiva (mas mais longa) da solução acima. Ambos
s and
eor s
são necessários, caso contrário, não funciona.Python 3 , 210 bytes
Experimente online!
fonte
Haskell ,
207202 bytes5 bytes salvos graças ao BMO .
Experimente online!
Esta é uma função que leva uma lista de
Int
como parâmetro e retorna uma lista de caminhos em que cada caminho é uma lista de saltos relativos feitos para sair da matriz.A versão não destruída:
fonte
C (gcc) , 269 bytes
Experimente online!
Inicialmente tentei uma pesquisa de retorno recursivo, porque usar
main
para recursão é sempre divertido. No final, embora uma pesquisa direta e não-recursiva de largura pudesse ser reduzida, é essa a versão. Este programa usa a matriz de entrada como argumentos de linha de comando, sem chaves, por exemplo,0 8 5 9 4 1 1 1 2 1 2
para o primeiro exemplo fornecido. O programa gera no stdout uma lista de indexadas em 1 com índices de matriz com vírgula e em ordem inversa, iniciando no índice final, fora dos limites / 'escapado' e retornando aos índices intermediários alcançados (ele não gera o centro, índice inicial). O programa não gera chaves ao redor da matriz e deixa uma vírgula à direita porque separaprintf
declarações têm muitos caracteres. A saída correspondente ao primeiro exemplo de teste acima é13,11,9,5,
, por exemplo.Se não houver rota de escape do labirinto de matrizes, o programa não emitirá nada.
Degolfed e explicado abaixo (fortemente degolfed com algumas mudanças para facilitar a leitura):
Como de costume no código C, a saída da compilação incluirá, obviamente, uma parede amigável de avisos e notas.
fonte
Perl 5 , -a: 73 bytes
(contagem de estilo antigo: 75 bytes,
+1
paraa
e+1
para substituir-//
por-/$/
e usar$`
para$'
)Dê a matriz de entrada como uma linha no STDIN, por exemplo
0 8 5 9 4 1 1 1 2 1 2
imprime as posições visitadas na ordem inversa, incluindo o ponto de partida, e depois trava
Imprime nada se não houver solução
Experimente online!
fonte
Ruby , 102 bytes
Experimente online!
Pega o labirinto de entrada como uma matriz e imprime o caminho de escape em sentido inverso, da saída ao ponto inicial (inclusive). Imprime nada se não houver escapatória.
Essa abordagem utiliza incorretamente o método map para iterar através de uma matriz temporária que armazena o histórico de caminhos, que é constantemente estendido em tempo real sempre que há outra etapa possível a ser executada.
Em princípio, eu poderia salvar outro byte usando em
return x
vez debreak p x
, mas isso significaria alegar que meu valor falso é igual a todo o lixo monstruoso armazenadob
. Provavelmente, isso seria demais, mesmo considerando a flexibilidade permitida da saída ...Passo a passo
fonte