Mueve las flechas a lo largo de un contorno

28

Caja de arena

Dado un conjunto de contornos 2D no superpuestos cerrados (separados por al menos un espacio, incluso en diagonales) con flechas orientadas consistentemente en el mismo sentido horario o antihorario (cada contorno tiene su propia dirección) y un número positivo n, mueva las flechas npasos a lo largo de los contornos en la dirección respectiva. Las flechas están representadas > v < ^respectivamente por las direcciones derecha, abajo, izquierda y arriba. Allí los otros caracteres son -(horizontal), |(vertical) y +(esquina). Cuando una flecha está en una esquina, mantiene su dirección actual y la cambia solo después de tomar el turno.

Siempre habrá un segmento recto (o un espacio) entre dos esquinas (como +-+para la horizontal y similar para la vertical); en otras palabras, las Ucurvas cerradas están prohibidas. Los segmentos entre las esquinas son verticales u horizontales y la curva en una esquina es siempre de 90 grados.

Entrada:

  • un entero positivo - n- número de pasos
  • una representación ASCII de los contornos: puede ser una cadena de varias líneas, una lista de cadenas, una lista de caracteres, etc.

Salida:

Los mismos contornos con todas las flechas cambiaron los npasos en la dirección general de cada contorno.

Casos de prueba:

1)

Entrada:

n = 1

 +----->->            
 |       |            
 |       v---+        
 |           |        
 +---<-------+      

Salida:

 +------>+
 |       v
 |       +>--+
 |           |
 +--<--------+

2)

Entrada:

n = 2

 +-----+ +---+        
 |     | |   |        
 +-->--+ |   v  
         |   | 
 +--->---+   |        
 |           |         
 +------<<---+       

Salida:

 +-----+ +---+
 |     | |   |
 +---->+ |   |
         |   | 
 +----->-+   v
 |           |     
 +----<<-----+        

3)

Entrada:

n = 3

 +---+   +---+   +-------+      
 |   |   |   v   |       |      
 ^   |   |   |   +-<-+   |      
 |   |   ^   |       |   v      
 |   +---+   +-->----+   |      
 |                       |      
 |   +-------+   +---+   |      
 |   |       |   v   |   |      
 +---+       +---+   +---+      

Salida:

 +>--+   ^---+   +-------+
 |   |   |   |   ^       |
 |   |   |   |   +---+   |
 |   |   |   |       |   |
 |   +---+   v----->-+   |
 |                       |
 |   +-------+   +---+   v 
 |   |       |   |   |   |
 +---+       +-<-+   +---+  

4)

Entrada:

n = 1

+--+ 
|  |
|  +---+
|      |     
+----+ |
     | |
     +-+ 

Salida:

+--+ 
|  |
|  +---+
|      |     
+----+ |
     | |
     +-+ 

5)

Entrada

n = 4

^>>>>
^   v
^   v>>>>
^       v           
<<<<<<<<v

Salida:

^>>>>
^   v
^   v>>>>
^       v           
<<<<<<<<v

6)

Entrada:

n = 1

^->
^ v
<<v

Salida:

^>+
^ v
<<v

Escriba una función o un programa para resolver la tarea anterior. El código más corto en bytes en cada idioma gana. No se desanime por los idiomas de golf. La explicación del algoritmo y el código es muy apreciada.

Galen Ivanov
fuente
¿Pueden dos contornos tocar sus esquinas en diagonal, o un contorno puede tocarse así?
xnor
44
"Dado un conjunto de contornos 2D no superpuestos cerrados ... con flechas orientadas consistentemente en el mismo sentido horario o antihorario", me parece que cada contorno está orientado en la misma dirección, mientras que en los casos de prueba, parece que las flechas solo deben ser consistentes dentro de un contorno.
xnor
3
@xnor ¡Gracias por tus comentarios! - No, los contornos no pueden tocarse entre sí / en diagonal. - Cada contorno tiene su propio directon. Actualizaré la descripción.
Galen Ivanov
2
¿Es posible la entrada sin espacio entre las paredes? Por ejemplo: ¡ Pruébelo en línea! . Sé que dijiste "separados por al menos un espacio", pero no estaba claro si eso se aplicaba solo a bucles independientes o si también se aplicaba a un solo bucle.
Jonás
1
@ Jonás No, no es posible:There will always be a straight segment (or a space) between any two corners (like +-+ for the horizontal and similar for the vertical) - in other words the sharp U turns are forbidden.
Galen Ivanov

Respuestas:

14

JavaScript (ES6),  210 ... 182  180 bytes

Toma entrada como (m)(n), donde es una lista de listas de caracteres. Devuelve el resultado en el mismo formato.m

m=>g=n=>n?g(n-1,m=m.map((r,y)=>r.map((c,x)=>(i=0,h=$=>~$?(m[Y=y+($-2)%2]||0)[X=x+~-$%2]>h?"-|+"[n+=`;m[${Y}][${X}]=S[${$}]`,i?2:$&1]:h($^++i):c)((S="<^>v").indexOf(c)))),eval(n)):m

Pruébalo en línea!

¿Cómo?

Puede seguir este enlace para ver una versión formateada de la fuente.

Envoltura

La función recursiva solo se usa como una envoltura que invoca el código principal para mover todas las flechas en 1 paso y sigue llamándose con hasta .gn1n=0

Método de actualización

No podemos mover con seguridad cada flecha una a la vez porque correríamos el riesgo de sobrescribir las flechas no actualizadas con las actualizadas. En cambio, primero eliminamos todas las flechas y calculamos sus nuevas posiciones. Aplicamos las nuevas posiciones en una segunda vez.

Esto se hace reutilizando como una cadena para almacenar las actualizaciones de posición como código JS.n

Por ejemplo, en el primer caso de prueba, se establece en:n

"1;m[0][7]=S[2];m[1][8]=S[3];m[2][9]=S[2];m[4][3]=S[0]"

(Tenga en cuenta que el número inicial, que es el valor original de , es inofensivo).n

Las nuevas posiciones se aplican simplemente haciendo eval(n).

Direcciones

Cada flecha se convierte en una dirección (nombrada en el código), utilizando la siguiente brújula:d$

10+23

Los valores correspondientes de y se calculan de esta manera:dxdy

 d | dx = (d - 1) % 2 | dy = (d - 2) % 2
---+------------------+------------------
 0 |        -1        |         0
 1 |         0        |        -1
 2 |        +1        |         0
 3 |         0        |        +1

Esquinas

Si el siguiente personaje en la dirección identificada es un espacio o está fuera de los límites, significa que estamos ubicados en una esquina y tenemos que dar un giro de 90 ° o 270 °. Esta es la razón por la cual la función auxiliar está probando hasta 3 direcciones distintas: , y .hddxor1dxor3

Si estamos ubicados en una esquina, sobrescribimos la celda con +. De lo contrario, lo sobrescribimos con uno -o |, dependiendo de la paridad de .d

Nota : el parámetro deh$h"$""$""$"

Versión animada

Arnauld
fuente
¡Gracias por la explicación!
Galen Ivanov
8

K (NGN / K) , 183 161 157 bytes

{A:"^>v<";D,:-D:(-1 0;!2);s:(#x;#*x);c:~^x;r:" -+|"c*+/'3'0,c,0;$[#p:+s\&~^t:A?,/x;;:r];q:q@'*'&'~^x ./:/:q:+p+/:D@4!(t^0N)+/:0 1 3;s#@[,/r;s/+q;:;A@D?q-p]}/

Pruébalo en línea!

{ }/cuando se llama con un int left arg n, esto aplicará la función en { }n veces a la derecha arg

A:"^>v<" flechas

D,:-D:(-1 0;!2) ∆y, ∆x para las 4 direcciones cardinales

s:(#x;#*x) forma de la entrada: altura, ancho

c:~^x countours - matriz booleana que muestra dónde están los no espacios

r:" -+|"c*+/'3'0,c,0recrear la matriz de caracteres con un conteo pero sin flechas, contando self + upper + lower para cada celda cy reemplazando 1-> -, 2-> +, 3->|

t:A?,/xtipos de flechas: 0 1 2 3 para ^>v<, todas las demás celdas se representan como 0N(nulo)

p:+s\&~^t coordenadas de las flechas

$[#p ;;:r] si no hay flechas, regrese r

q:+p+/:D@4!(t^0N)+/:0 1 3 las 3 nuevas posiciones posibles para cada flecha: si sigue avanzando, si gira a la izquierda y si gira a la derecha

q:q@'*'&'~^x ./:/:q para cada flecha, elija la primera opción que aterrice en el país

@[,/r;s/+q;:;A@D?q-p]aplanar ry poner sobre él las flechas en sus nuevas posiciones y con sus nuevas direcciones

s# remodelar a la forma original

ngn
fuente
2
¡Eres rápido! Espero que expliques el código después de terminar de jugarlo.
Galen Ivanov
¡Gracias por la explicación!
Galen Ivanov
4

Carbón , 105 bytes

W¬ΦυΣκ⊞υS≔⊟υη≔⪫υ⸿θ≔⟦⟧υ≔>^<vζPθFθ¿№ζι«⊞υ⟦⌕ζιⅉⅈ⟧§+|-↨EKV›κ ²»ιFυ«J⊟ι⊟ι≔⊟ιιFIη«≔⊟Φ⁴∧﹪⁻⊖ι⊕λ⁴›§KV⁻⁵λ ιM✳⊗黧ζι

Pruébalo en línea! El enlace es a la versión detallada del código. Incluye 22 bytes utilizados para evitar requerir un formato de entrada engorroso. Explicación:

W¬ΦυΣκ⊞υS≔⊟υη≔⪫υ⸿θ≔⟦⟧υ

Ingrese convenientemente los contornos y la cantidad de pasos.

≔>^<vζ

Los caracteres de dirección se usan varias veces, por lo que la cadena se almacena en caché aquí. El índice de un carácter de dirección en esta cadena se conoce como su dirección.

Pθ

Imprima los contornos originales sin mover el cursor.

Fθ

Recorre los personajes en el contorno.

¿№ζι«

Si los caracteres actuales son un carácter de dirección ...

⊞υ⟦⌕ζιⅉⅈ⟧

... luego guarde la dirección y la posición en una lista ...

§+|-↨EKV›κ ²

... y reemplace el carácter con el carácter de línea apropiado.

»ι

De lo contrario, muestre el carácter y pase al siguiente carácter.

Fυ«

Recorrer las posiciones guardadas.

J⊟ι⊟ι

Salta a la posición guardada.

≔⊟ιι

Extraer la dirección guardada.

FIη«

Pase el número apropiado de pasos.

≔⊟Φ⁴∧﹪⁻⊖ι⊕λ⁴›§KV⁻⁵λ ι

Encuentre la dirección del siguiente paso, que es cualquier dirección que no sea inversa ni vacía.

M✳⊗ι

Da un paso en esa dirección. (Los índices de dirección de carbón para el Movecomando son dos veces el valor de mi dirección).

»§ζι

Imprima el carácter de dirección apropiado.

Neil
fuente
¡Gracias por la explicación!
Galen Ivanov