Este desafío está inspirado en un juego de mesa que jugué hace algún tiempo.
La historia de este desafío no necesariamente tiene que leerse, el objetivo de la sección desafío debe explicar todo lo necesario.
La historia
Las personas están encerradas dentro de una habitación grande con un monstruo devorador de humanos. Las paredes de la habitación están encantadas, teletransportando objetos a través de la habitación cuando se tocan. Dicho monstruo marcha a través de la habitación, buscando carne. El primer humano a la vista será consumido por sus afilados dientes.
El objetivo del desafío
Te dan el mapa de la habitación, que incluye la ubicación del pueblo y del monstruo.
%%%KLMNOPQRSTA%
%%J B
%I % C
H D
G %% E
F F
E % G
D H
C % I%
B J%%
%ATSRQPONMLK%%%
Analicemos los componentes del mapa.
- Cartas de
A
aT
: si el monstruo pisa uno de estos, se teletransportará a la segunda aparición de esta carta y no cambiará su dirección. Solo habrá cero o dos de cualquier letra en la pizarra. %
: Revestimientos. Solo por formato y aspecto agradable.#
: La ubicación inicial del monstruo.*
: Las ubicaciones de las personas.
Algunas cosas adicionales a tener en cuenta sobre el mapa:
- Las dimensiones del mapa y la ubicación del objeto no serán constantes, por lo que su código tendrá que adaptarse dinámicamente a eso.
El monstruo siempre irá en la dirección en la que se enfrenta actualmente (mirando hacia el oeste al comienzo) a menos que vea a un humano, en cuyo caso se girará hacia el humano más cercano .
El monstruo ve a un humano si no hay azulejos de pared o teletransportador en una línea recta horizontal o vertical entre él y el humano.
Otra cosa a tener en cuenta es que si el monstruo está frente a una pared sólida ( %
) o tiene que decidir entre dos humanos, siempre dará prioridad a la derecha sobre la izquierda.
Si el monstruo no puede girar a la derecha y dar un paso adelante por alguna razón, en su lugar , girará a la izquierda .
Entonces, al final, el orden en que el monstruo prioriza las direcciones sería hacia adelante, derecha, izquierda, hacia atrás.
Entrada
- El mapa, incluida la ubicación inicial del monstruo y las posiciones de las personas como sus respectivos personajes. No debe haber otra entrada que la cadena del mapa, o la matriz de cadenas o caracteres.
La entrada puede recibirse en cualquier formato razonable; una sola cadena o una matriz de cadenas para el mapa.
Salida
La coordenada de la persona que primero se come el monstruo.
Las coordenadas comienzan desde la esquina superior izquierda y están indexadas en 0, por lo que el primer mosaico tendrá las coordenadas (0 | 0). Si está utilizando la indexación 1, especifíquelo en su respuesta.
Reglas
- Este es el código de golf , gana el código más corto en bytes en cualquier idioma.
- Las lagunas estándar están prohibidas.
- Puedes suponer que el monstruo siempre podrá alcanzar a un humano.
Casos de prueba
Entrada:
%%%KLMNOPQRSTA%
%%J B
%I %* C
H * D
G %% E
F # F
E % G
D * H
C % I%
B J%%
%ATSRQPONMLK%%%
Salida: (10,2)
como el monstruo no puede ver a las otras dos personas cuando pasa corriendo, se teletransporta a la otra F
pared, donde verá a la última persona.
Entrada:
%%%KLMNOPQRSTA%
%%J B
%I * C
H %%% * D
G #% E
F %%% % F
E G
D % H
C * I%
B * J%%
%ATSRQPONMLK%%%
Salida: (12,3)
Entrada:
%%%KLMNOPQRSTA%
%%J B
%I %%% C
H *%#% D
G E
F F
E % G
D H
C I%
B J%%
%ATSRQPONMLK%%%
Salida: (6, 3)
Entrada:
%%%%%%%%%%%%%%%
%#% %%% %
%A%ABCD %*% %
%*F G %%% %
% %BC% FD %
% % % %%%%
% % % %%
% % %% G %
% %
%*% % % %
%%%%%%%%%%%%%%%
Salida: (1,9)
¡Buena suerte!
Respuestas:
Python 2 ,
565 .. 422 445 1 .. 444 463 2 .. 468467463 bytesPruébalo en línea!
Ahorré muchos bytes gracias a Halvard , Ian y Jonathan
1: Obtuve más tiempo para arreglar el caso de girar dos veces y encontrar la ubicación del monstruo.
2: Se hizo aún más largo ... Monster no debería cambiar de dirección cuando se teletransporta.
fuente
l.replace('#',' ')
->l.replace(*"# ")
.Perl 6 ,
343334333328322308 bytesPruébalo en línea!
(No hay nuevas líneas en el código real. Las inserté solo para ajustar las líneas para una lectura más fácil).
Esto no puede tratar con mapas donde es posible ver fuera de los límites del mapa. (I.e. Mapas con espacios vacíos en el borde). Si esto es importante, +5 bytes. Pero, dado que los teletransportadores bloquean LoS ahora, no debería.
Explicación : Es una función que toma el mapa como una lista de listas de caracteres. Vamos a dividirlo en declaraciones:
my \m=%((^@^a X ^@a[0]).map:{.[0]i+.[1]=>@a[.[0]][.[1]]});
: Hagamos un hash ("diccionario" para Pythonists) llamadom
(es una variable sin sigil, por lo que debemos ser explícitos sobre la asignación de un hash con él%(...)
) que asocia claves complejas de formax+iy
con caracteres que están en la columnay
th rown yx
th del mapamy \a=m<>:k.classify({m{$_}});
: Esto hace un "diccionario inverso" dem
, llamadoa
: hay una clave correspondiente a cada valor enm
, y el valor es una lista de coordenadas complejas (claves enm
) que contienen ese carácter. Entonces, por ejemploa{"#"}
, dará una lista de todas las coordenadas donde hay una#
en el mapa. (Esta también es una variable sin sigilo, pero tenemos suerte ya queclassify
devuelve un hash).my$m=a<#>[0];my$d=-1
: Establece la posición inicial del monstruo. Buscamos#
en el hash inversoa
. Debemos usar[0]
yaa<#>
que todavía es una lista, incluso cuando contiene solo 1 elemento. El$d
contiene la dirección del monstruo; lo ponemos al oeste. (La dirección también es un número complejo, también lo-1
es el oeste).OK, la siguiente declaración es bastante desagradable. Primero, echemos un vistazo a esto:
{$^q;first ?*,map {(((my$u=m{my$t=$m+$_*$q})~~"%")*(1+!($_-1))+($u~~"A".."Z"))*m+($u~~"*")*abs($t-$m)},^m}
esta es una rutina que evalúa LoS en la dirección dada. Si hay un humano en esta dirección, devuelve la distancia al humano. Si hay un muro o un teletransporte en esta dirección, devuelve el número total de cuadrados del mapa. (El punto es dar un número tan alto que sea mayor que cualquier distancia legítima a un humano.) Finalmente, si el muro está en esta dirección y en la distancia 1, devolvemos 2 × el número total de cuadrados del mapa. (Queremos nunca atravesar paredes, por lo que estos necesitan incluso un puntaje mayor. En breve elegiremos el mínimo).Usamos esto en la construcción
$d=($d,i*$d,-i*$d,-$d).min( LoS deciding block );
. Como utilizamos números complejos para todo, podemos obtener fácilmente direcciones que son relativas hacia adelante, derecha, izquierda y hacia atrás desde la dirección original simplemente multiplicándola por 1, i, -i (recuerde que ely
eje va en la dirección opuesta se utilizará de matemáticas) y -1, respectivamente. Por lo tanto, formamos la lista de direcciones en este orden, y encontramos la dirección que tiene la "distancia a un humano" mínima (de acuerdo con el bloque anterior), lo que asegura que cualquier humano derrote cualquier pared y que cualquier cosa venza a una pared que sea correcta debajo de la nariz del monstruo Usamos el hecho de que lamin
función da la primeravalor mínimo Si hay un empate en la distancia entre varias direcciones, el monstruo preferirá avanzar de derecha a izquierda o hacia atrás, que es exactamente lo que queremos. Entonces obtenemos una nueva dirección que luego se asigna$d
.$m+=$d;
solo hace que el monstruo avance en la nueva dirección.$m=$d+(a{m{$m}}∖~$m).pick while m{$m}~~"A".."Z"
se encarga de los teletransportes. Digamos que el monstruo está en un teletransporteA
. Primero buscamosA
en el hash inverso%a
y eso sube las dos posiciones del teletransporteA
, luego descartamos la posición actual usando el operador de diferencia de conjunto (que parece una barra invertida). Dado que hay exactamente 2 ocurrencias de cada teletransporte en el mapa y el monstruo seguramente está parado en uno, la diferencia será un conjunto con 1 elemento. Luego usamos.pick
para elegir un elemento aleatorio (lo creas o no, pero esta es la forma más corta de obtener el elemento del conjunto de 1 elemento :—)). Este tipo de cosas suceden hasta que el monstruo termina en algún lugar no en un portal.Todo en los últimos 4 párrafos describe una construcción masiva de forma
{change direction; step; handle teleports}...{m{$m}~~"*"}
. Esta es una secuencia que llama al bloque a la izquierda de...
hasta que la condición a la derecha de la...
sea verdadera. Y eso es cierto cuando el monstruo está en una plaza con un humano. La lista en sí contiene valores de retorno del bloque enorme a la izquierda, que es basura (muy probablemente(Any)
) porque devuelve el valor del ciclo while al final. Esencialmente, lo usamos como un ciclo while más barato. El valor de la lista se descarta (y el compilador se queja de un "uso inútil...
en un concurso de sumideros", pero a quién le importa). Cuando todo esto está hecho, regresamos$m
: la posición del monstruo después de encontrar un humano, aún como un número complejo (así, para la primera prueba, damos10+2i
y así sucesivamente).fuente
JavaScript (ES6),
258245Menos golf
Prueba
fuente