Este desafio é inspirado em um jogo de tabuleiro que joguei há algum tempo.
A história desse desafio não precisa necessariamente ser lida; o objetivo da seção de desafio deve explicar tudo o que é necessário.
A história
As pessoas estão trancadas dentro de uma grande sala com um monstro devorador de seres humanos. As paredes da sala estão encantadas, teleportando objetos pela sala quando tocadas. O referido monstro marcha pelo quarto, procurando carne. O primeiro humano à sua vista será consumido por seus dentes afiados.
O objetivo do desafio
Você recebe o mapa da sala, incluindo a localização das pessoas e do monstro.
%%%KLMNOPQRSTA%
%%J B
%I % C
H D
G %% E
F F
E % G
D H
C % I%
B J%%
%ATSRQPONMLK%%%
Vamos dividir os componentes do mapa.
- Cartas de
A
paraT
: Se o monstro pisar em uma delas, ele será teleportado para a segunda aparição dessa carta e não mudará de direção. Só haverá zero ou duas letras no quadro. %
: Revestimento de parede. Apenas para formatação e boa aparência.#
: A localização inicial do monstro.*
: A localização das pessoas.
Algumas coisas adicionais a serem observadas sobre o mapa:
- As dimensões do mapa e a localização do objeto não serão constantes; portanto, seu código precisará se adaptar dinamicamente a isso.
O monstro sempre seguirá na direção em que está atualmente (voltado para o oeste no início), a menos que encontre um humano; nesse caso, ele se volta para o humano mais próximo .
O monstro avista um humano se não houver azulejos de parede ou teletransportador em uma linha horizontal ou vertical reta entre ele e o humano.
Outra coisa a se notar é que, se o monstro estiver na frente de uma parede sólida ( %
) ou precisar decidir entre dois humanos, ele sempre priorizará da direita para a esquerda.
Se o monstro não conseguir virar à direita e dar um passo à frente por algum motivo, ele virará à esquerda .
Então, no final, a ordem em que o monstro prioriza as direções encaminhamos, direita, esquerda, para trás.
Entrada
- O mapa, incluindo a localização inicial do monstro e as posições das pessoas como seus respectivos personagens. Não deve haver outra entrada além da sequência do mapa, ou a matriz de sequências ou caracteres.
A entrada pode ser recebida em qualquer formato razoável; uma única sequência ou uma matriz de sequências para o mapa.
Resultado
A coordenada da pessoa que primeiro é comida pelo monstro.
As coordenadas começam no canto superior esquerdo e são indexadas em 0; portanto, o primeiro bloco terá as coordenadas (0 | 0). Se você estiver usando a indexação 1, especifique-a na sua resposta.
Regras
- Este é o code-golf , o código mais curto em bytes em qualquer idioma vence.
- As brechas padrão são proibidas.
- Você pode assumir que o monstro sempre será capaz de alcançar um humano.
Casos de teste
Entrada:
%%%KLMNOPQRSTA%
%%J B
%I %* C
H * D
G %% E
F # F
E % G
D * H
C % I%
B J%%
%ATSRQPONMLK%%%
Saída: (10,2)
como o monstro não pode ver as outras duas pessoas quando passa por elas, é teleportado para a outra F
parede, onde verá a última pessoa.
Entrada:
%%%KLMNOPQRSTA%
%%J B
%I * C
H %%% * D
G #% E
F %%% % F
E G
D % H
C * I%
B * J%%
%ATSRQPONMLK%%%
Resultado: (12,3)
Entrada:
%%%KLMNOPQRSTA%
%%J B
%I %%% C
H *%#% D
G E
F F
E % G
D H
C I%
B J%%
%ATSRQPONMLK%%%
Resultado: (6, 3)
Entrada:
%%%%%%%%%%%%%%%
%#% %%% %
%A%ABCD %*% %
%*F G %%% %
% %BC% FD %
% % % %%%%
% % % %%
% % %% G %
% %
%*% % % %
%%%%%%%%%%%%%%%
Resultado: (1,9)
Boa sorte!
Respostas:
Python 2 ,
565 .. 422 445 1 .. 444 463 2 .. 468467463 bytesExperimente online!
Economizou muitos bytes graças a Halvard , Ian e Jonathan
1: Tem mais tempo, a fim de corrigir o caso de virar duas vezes e encontrar a localização do monstro.
2: Ficou ainda mais tempo. O monstro não deve mudar de direção ao se teletransportar.
fonte
l.replace('#',' ')
->l.replace(*"# ")
.Perl 6 ,
343334333328322308 bytesExperimente online!
(Não há novas linhas no código real. Eu as inseri apenas para quebrar as linhas para facilitar a leitura.)
Não é possível lidar com mapas onde é possível ver fora dos limites do mapa. (Ou seja, mapeia com espaços vazios na borda.) Se isso importa, +5 bytes. Mas, como os teleportadores bloqueiam o LoS agora, não deveriam.
Explicação : É uma função que leva o mapa como uma lista de listas de caracteres. Vamos dividir em declarações:
my \m=%((^@^a X ^@a[0]).map:{.[0]i+.[1]=>@a[.[0]][.[1]]});
: Vamos criar um hash ("dicionário" para Pythonists) chamadom
(é uma variável sem sinal, portanto, precisamos ser explícitos sobre a atribuição de um hash%(...)
) que associa chaves complexas de formax+iy
a caracteres que estão nas colunas thy
e thownx
do mapa.my \a=m<>:k.classify({m{$_}});
: Isso cria um "dicionário inverso" dem
, chamadoa
: existe uma chave correspondente a cada valor emm
e o valor é uma lista de coordenadas complexas (entradasm
) que contêm esse caractere. Assim, por exemplo,a{"#"}
será apresentada uma lista de todas as coordenadas em que há uma#
no mapa. (Essa também é uma variável sem sinal, mas estamos com sorte, poisclassify
retorna um hash.)my$m=a<#>[0];my$d=-1
: Defina a posição inicial do monstro. Procuramos#
o hash inversoa
. Devemos usar,[0]
poisa<#>
ainda é uma lista, mesmo quando contém apenas 1 elemento. O$d
contém a direção do monstro; colocamos no oeste. (A direção também é um número complexo, assim-1
como o oeste.)OK, a próxima afirmação é bastante desagradável. Primeiro, vamos dar uma olhada no seguinte:
{$^q;first ?*,map {(((my$u=m{my$t=$m+$_*$q})~~"%")*(1+!($_-1))+($u~~"A".."Z"))*m+($u~~"*")*abs($t-$m)},^m}
Esta é uma rotina que avalia LoS na direção especificada. Se houver um humano nessa direção, ele retornará a distância para o humano. Se houver uma parede ou um teleporte nessa direção, ele retornará o número total de quadrados do mapa. (O objetivo é fornecer um número tão alto que seja maior que qualquer distância legítima de um humano.) Finalmente, se a parede estiver nessa direção e na distância 1, retornamos 2 × o número total de quadrados do mapa. (Como nunca queremos correr pelas paredes, elas precisam de uma pontuação ainda maior. Escolheremos o mínimo em breve.)Nós usamos isso na construção
$d=($d,i*$d,-i*$d,-$d).min( LoS deciding block );
. Como usamos números complexos para tudo, podemos obter facilmente direções que são relativas para a frente, direita, esquerda e para trás a partir da direção original apenas multiplicando-a por 1, i, -i (lembre-se de que oy
eixo segue o outro caminho que você pode usado para matemática) e -1, respectivamente. Então, formamos a lista de direções nessa ordem e encontramos a direção que tem a mínima "distância até um humano" (de acordo com o bloco acima), o que garante que qualquer humano bata em qualquer parede e qualquer coisa que bata em uma parede que seja correta sob o nariz do monstro. Usamos o fato de que amin
função fornece o primeirovalor mínimo. Se houver um empate na distância entre várias direções, o monstro preferirá avançar da direita para a esquerda para trás, o que é exatamente o que queremos. Então, temos uma nova direção que é então atribuída$d
.$m+=$d;
apenas faz o monstro pisar na nova direção.$m=$d+(a{m{$m}}∖~$m).pick while m{$m}~~"A".."Z"
cuida dos teleports. Digamos que o monstro esteja em um teletransporteA
. Primeiro, procuramosA
no hash inverso%a
e isso aumenta as duas posições do teletransporteA
, depois descartamos a posição atual usando o operador de diferença definida (que parece uma barra invertida). Como existem exatamente 2 ocorrências de cada teleporte no mapa e o monstro certamente está de pé em uma, a diferença será um conjunto com 1 elemento. Em seguida, usamos.pick
para escolher um elemento aleatório (acredite ou não, mas esta é a maneira mais curta de obter o elemento do conjunto de 1 elemento :—)). Esse tipo de coisa acontece até que o monstro acaba em algum lugar que não está em um portal.Tudo nos últimos 4 parágrafos descreve uma construção maciça de forma
{change direction; step; handle teleports}...{m{$m}~~"*"}
. Esta é uma sequência que chama o bloco à esquerda de...
até que a condição à direita da...
seja verdadeira. E isso é verdade quando o monstro está em um quadrado com um humano. A própria lista contém valores de retorno do bloco enorme à esquerda, que é lixo (provavelmente(Any)
) porque retorna o valor do loop while no final. Essencialmente, nós o usamos como um loop while mais barato. O valor da lista é descartado (e o compilador geme sobre um "uso inútil de...
um concurso de afundamento", mas quem se importa). Quando tudo estiver pronto, retornamos$m
- a posição do monstro depois que ele encontrou um humano, ainda como um número complexo (então, para o primeiro teste, damos10+2i
e assim por diante).fonte
JavaScript (ES6),
258245Menos golfe
Teste
fonte