¿El camino a pescado tiene un final?

13

Me encanta> <>,> <> es la vida! ¡Los idiomas 2D son increíbles! En este desafío, tendrá que decir si un camino "sospechoso" tiene un final, mientras que el golf de código.

Definición

Se construye un camino sospechoso con azulejos, que incluyen los siguientes:

v (go down)
> (go right)
^ (go up)
< (go left)
/ (mirror)
\ (mirror)

Cualquier otro personaje (excepto -|+) puede considerarse una distracción, como algunas flores (o cabezas de peces) en el borde del camino.

Una carretera siempre comienza en la esquina superior izquierda de una cuadrícula rectangular, delimitada por -|+símbolos. El camino tiene un final si, al seguirlo, termina en un borde, de lo contrario, quedará atrapado en un camino infinito.

Encontrar su camino en el camino se logra siguiendo las instrucciones dadas por v>^<y los espejos. Un espejo se reflejará 90 ° dependiendo de dónde vienes. Así es como funciona (usando v>^<para mostrar indicaciones):

 ^    ^
>/<  >\<
 v    v
</>  <\>
 ^    ^

Un camino podría verse así si termina:

+--------------------+
|>\/  this way >\/>  | this one ends here
| v^            \/   |
| v^   ^.^           |
| \/\         >v     |
| /\/         ^<     |
+--------------------+

Un bucle infinito:

+--------+
|>>\ This|
|\\   is |
|  \\ a  |
| \ /trap| 
+--------+

Detalles específicos

Un camino no consiste necesariamente solo en instrucciones. Se pueden usar espacios o letras para completarlo. Esto significa que debes continuar moviéndote en la misma dirección, excepto si cruzas un personaje <v^>-|.

Siempre habrá uno v>^<en la esquina superior izquierda, <o ^implica que este camino termina.

Puede enviar una función tomando una cadena como parámetro, o un programa independiente usando STDIN / lo que sea la alternativa más cercana en su idioma.

Su envío debe devolver o imprimir en los valores de verdad / falsedad de STDOUT cuando esté listo. Los valores de verdad significan que el camino tiene un final, mientras que falso significa que es un bucle infinito.

Casos de prueba

+--------------------+
|>\/  this way >\/>  | this one ends here
| v^            \/   |
| v^   ^.^           |
| \/\         >v     |
| /\/ ><>     ^<     |
+--------------------+
    True

+--------+
|>>\ This|
|\\   is |
|  \\ a  |
| \ /trap| 
+--------+
    False

+--+
|<v|
|^<|
+--+
    True

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

+----------+
|v Hello \ |
|\\/\/   / |
| \/\\   \ |
|/  // >\  |
|  ^/\>\\/ |
|\  /\/\/  |
+----------+
    False

+-----+
|>\/\\|
|//\\/|
|\/\\\|
|//\//|
|\/\/ |
+-----+
    True

2 test cases added as suggested by @MartinBüttner
+----+
|v   |
|\\  |
|//\ |
|\\v |
| \/ |
+----+
    False

+----+
|v   |
|\\  |
|//\ |
|\\^ |
| \/ |
+----+
    False

Test case inspired by @ETHproductions
+-------------------------+
|><>                      |
|something smells fishy...|
+-------------------------+
    False

Las lagunas estándar están prohibidas (como siempre).

El ganador será el que tenga el código más corto en bytes. (sería increíble ver una> <> respuesta :))

Katenkyo
fuente
1
Es mejor obtener una respuesta> <> ...
aplaudir el
@ConfusedMr_C Me pondría encima si supiera este idioma: /. Tal vez si encuentro tiempo ^^ '
Katenkyo
Supongo que transformar la entrada en> <> y luego llamar al intérprete> <> (sin incluir el código de eso en el conteo) sería una laguna.
Paŭlo Ebermann
1
@ PaŭloEbermann Para que no sea una escapatoria, necesitaría contar el personaje en el intérprete, o usar un idioma con un intérprete> <> incorporado, y no creo que exista ^^.
Katenkyo

Respuestas:

4

JavaScript, ES6, 177 161 145 bytes

f=(s,i=1,M=[],D)=>D==5||!~M[O="indexOf"](D+i)&&f(s,i-[M.push(D+i),L=s[O]('|'),-L,1,-1][D=`431255${5-D+'X3412'[D]}`['><^v-|/\\'[O](s[i+L])]||D],M,D)

Podemos detectar un ciclo atravesando el camino y detectando una repetición de la tupla

  • ubicación
  • dirección de llegada

Es decir, si estamos entrando en alguna posición (x,y)proveniente de alguna dirección Dpor segunda vez, sabemos que este ciclo se repetirá para siempre. Por lo tanto, el código realiza un seguimiento de todas las ubicaciones que se visitaron y desde qué dirección, y comprueba ese registro cada vez que se visita un nuevo espacio.

A las direcciones arriba, abajo, izquierda y derecha se les asignan los números 1,2 , 3, y 4. El código considera el símbolo actual que se está visitando ( s[i+L]) y cambia la dirección actual ( D), luego la nueva dirección se usa para llamar recursivamente a la función y evaluar el siguiente espacio. 5como una dirección indica un muro y una trueterminación del programa.

Aquí hay una explicación del código menos golfizado:

f=
(s,     // input string
 i=1,   // current location as offset string index
 M=[],  // record of previously visited spaces
 D      // current direction
  )=>(
    L=s[O="indexOf"]('|'), // find arena width `L` by index of first `|`

    // if D is 5, return true, or...
    D==5 ||

    // if direction + position is not new, return false
    !~M[O](D+i) &&

    // otherwise, save this direction + position
    M.push(D+i) &&

    // recursively call `f` with new direction and position
    f(s,
      i-[,L,-L,1,-1][D=            // modify position based on active direction
        `431255${5-D+'X3412'[D]}`  // from these possible directions...
          [                        // chose the one at the index...
            '><^v-|/\\'[O](        // based on the index of the symbol 
                           s[i+L]  // of the current character
                                 )
          ]
        ||D     // or preserve old D if symbol is not directional
      ],
      M,D)

La cadena de plantilla `431255${5-D+'X3412'[D]}` tiene una expresión anidada que maneja los espejos: debido a que las direcciones son números, también se pueden usar como índices. La expresión se 'X3412'[D]evalúa como el octavo carácter en la cadena de dirección posible y, por lo tanto, corresponde al \octavo carácter en la cadena de símbolo '><^v-|/\\'). La expresión dice:

  • Si la dirección actual D es 1(arriba), entonces la nueva dirección al golpear un \espejo será 3(izquierda)
  • Si la dirección actual D es 2(abajo), entonces la nueva dirección al golpear un \espejo será 4(derecha)
  • etc.

El otro espejo /usaría la expresión 'X4321'[D], pero como se trata simplemente de una cuenta regresiva ordenada 4, podemos expresarla de manera más simple como 5-D.

apsillers
fuente
5

No conforme> <> respuesta

¡Querías> <>, te doy> <>!

Creo que la única forma sensata de hacer esto en> <> es copiar la entrada en el espacio de código y dejar que el intérprete decida por sí mismo si la entrada lleva a algún lado. Como> <> ya no implementa el enhebrado, eso nos deja con un gran problema: si la entrada tiene un bucle, nos quedaremos atrapados en él.

Teniendo en cuenta estas consideraciones, decidí hacer una solución compatible con > <> el intérprete en línea para que sea posible afirmar si el intérprete está atascado en la entrada o simplemente tarda años en hacer todo. También tuve que agregar líneas finales al código para que el intérprete en línea muestre el código agregado y no se bloquee al intentar escribir en él.

Ah, y dado que ahora estoy claramente descalificado, no me molesté en jugar el código.

Sin más preámbulos, el código en todo su esplendor:

50i:0(?v   :"^"=?v:"v"=?v:">"=?v:"<"=?v:"/"=?v:"\"=?v:"|"=?v:"-"=?va=?v1+10.
>.!603f<         v"."~                                     <      <   >~1+010.
>.!01+1p}:$}:}v! <      <      <      <      <      <
  ;oooo"true" <<
              ^

Para usarlo, cópielo en el intérprete en línea, agregue suficientes líneas finales para manejar su entrada, envíe el código, dele la entrada como ;líneas separadas y disfrute del viaje.

Algunas pruebas:

Con

+--------------------+
|>\/  this way >\/>  | this one ends here
| v^            \/   |
| v^   ^.^           |
| \/\         >v     |
| /\/         ^<     |
+--------------------+` 

Espacio de código final:

50i:0(?v   :"^"=?v:"v"=?v:">"=?v:"<"=?v:"/"=?v:"\"=?v:"|"=?v:"-"=?va=?v1+10.
>.!603f<         v"."~                                     <      <   >~1+010.
>.!01+1p}:$}:}v! <      <      <      <      <      <
  ;oooo"true" <<
            ^
 ....................
.>\/           >\/>  .                   
. v^            \/   .
. v^   ^ ^           .
. \/\         >v     .
. /\/         ^<     .
 ....................

Emite "verdadero" y se detiene.


Con

+--------+
|>>\ This|
|\\   is |
|  \\ a  |
| \ /trap| 
+--------+

Espacio de código final:

50i:0(?v   :"^"=?v:"v"=?v:">"=?v:"<"=?v:"/"=?v:"\"=?v:"|"=?v:"-"=?va=?v1+10.
>.!603f<         v"."~                                     <      <   >~1+010.
>.!01+1p}:$}:}v! <      <      <      <      <      <
  ;oooo"true" <<
            ^
 ........ 
.>>\     .
.\\      .
.  \\    .
. \ /    .
 ........

Bucles para siempre.

Aaron
fuente
Incluso si no cumple, ¡me encanta tu fuente! Gracias por esta entrada! Es triste que se repita para siempre cuando debería ser saludable, pero de todos modos es un buen trabajo ^^.
Katenkyo
Actualicé el intérprete de peces en línea. Ahora admite entrada multilínea
Suppen
@Suppen ¡Hola, bien! Gracias por el aumento de la velocidad máxima también!
Aaron