Escapar del laberinto!

20

Estás atrapado en este laberinto de 5x5: cada habitación está etiquetada del 1 al 25 y la salida está en la habitación 1.

ingrese la descripción de la imagen aquí

Se le da como entrada la sala en la que se encuentra actualmente. Su tarea es generar la secuencia más corta de movimientos (norte, este, sur, oeste) necesaria para llegar a la sala 1.

Los movimientos se pueden generar en cualquier formato que desee (lista, cadena, matriz ...) siempre que utilice los caracteres n,w,e,s.

Aquí están todos los casos de prueba:

1 => empty string/list
2 => w
3 => ww
4 => swwnw
5 => wswwnw
6 => seenwnw
7 => nw
8 => wnw
9 => wwnw
10 => swwnwnw
11 => eenwnw
12 => enwnw
13 => nwnw
14 => wnwnw
15 => wwnwnw
16 => enenwnw
17 => nenwnw
18 => wnenwnw
19 => nwnwnw
20 => wnwnwnw
21 => nenenwnw
22 => enwnenwnw
23 => nwnenwnw
24 => wnwnenwnw
25 => nwnwnwnw

¡La respuesta más corta en bytes gana!

Arnaud
fuente
3
¿Qué tan flexible es el etiquetado / entrada de la sala? ¿Podemos 0-index en lugar de 1-index? ¿Podemos tomar el número de habitación como un personaje (pensando, como en la base 36)?
Chas Brown
2
@Therandomguy no, debes manejar este laberinto específico.
Arnaud
66
Como es posible, creo que todos los casos posibles deberían incluirse en los casos de prueba.
Jonathan Frech
1
@UnrelatedString Esta pregunta toma 1 entrada y genera una ruta diferente en función de su entrada. Creo que este requisito no se ajusta a la etiqueta kolmogorov-complex .
tsh
2
Alguien necesita dar una respuesta en Labyrinth .
Draco18s

Respuestas:

20

Python 2 , 64 bytes

def f(n):d=0x1211252b5375>>2*n-4&3;print"nwes"[d];f(n+d*3+d%2-5)

Pruébalo en línea!

Una función que imprime una dirección por línea, terminando con error.

La constante 0x1211252b5375codifica en la base 4 la dirección en la dque viajamos desde cada número de habitación como un número del 0 al 3. El dígito de extracción >>2*n-4&3también está diseñado para dar un error de desplazamiento negativo al n=1terminar el código. Actualizamos el número de habitación a ntravés de un desplazamiento que se calcula desde la dirección dcomo d*3+d%2-5, que asigna:

d   d*3+d%2-5
0  -> -5
1  -> -1
2  ->  1
3  ->  5 
xnor
fuente
1
No estoy seguro de si esto es válido tal como está, las funciones tienen que ser reutilizables y necesita captura de errores ( try/ except) para poder continuar la ejecución después de llamar a esta función.
Erik the Outgolfer
10

Python 2 , 95 93 bytes

f=lambda n:n>1and Q[n]+f(n+[-5,5,1,-1]['nsew'.find(Q[n])])or''
Q='  wwswsnwwseenwwenwnwnenwn'

Pruébalo en línea!

Podría reducir 3 2 bytes si se permite el etiquetado de sala indexada en 0.

Chas Brown
fuente
89 bytes
Arnauld
6

05AB1E , 30 29 bytes

-1 byte gracias a una coincidencia milagrosa con números primos

[Ð#•θzƶ‰`Ó•4вsè<DˆØ·5-+}'‹™¯è

Pruébalo en línea!

[                      }    # infinite loop:
 Ð                          #  triplicate the room number (initially, the input)
  #                         #  break if room number == 1
   •θzƶ‰`Ó•4в               #  compressed list 202232302231102210202010
             sè             #  use the room number to index into that list
               <            #  decrement
                Dˆ          #  add a copy to the global array
                  Ø         #  nth prime (-1 => 0, 0 => 2, 1 => 3, 2 => 5)
                   ·        #  double
                    5-      #  subtract 5
                      +     #  add that to the room number
'‹™                         # dictionary string "western"
   ¯                        # push the global array
    è                       # index (wraps around, so -1 => n, 0 => w, 1 => e, 2 => s)
Mugriento
fuente
1
Esto genera 1una entrada1 , en lugar de una cadena vacía (una solución fácil sería agregar un interlineado õ?). Aparte de eso, buena respuesta!
Kevin Cruijssen
1
@KevinCruijssen gracias por señalar ese error! Encontré una solución de un solo byte.
Grimmy
5

Ruby , 72 62 bytes

f=->n{n<2?'':' en  sw'[x=4*18139004[n]+6*4267088[n]-5]+f[n+x]}

Pruébalo en línea!

¿Cómo?

El truco aquí es usar 2 constantes para construir el siguiente paso para cada celda, y luego resolver el problema de forma recursiva.

Las 2 constantes 18139004 y 4267088 son cadenas binarias que dan la dirección del siguiente movimiento, extrayendo un solo bit de ambas para cada celda, podemos obtener:

"n" = 4*0+6*0-5 = -5
"w" = 4*1+6*0-5 = -1
"e" = 4*0+6*1-5 = +1
"s" = 4*1+6*1-5 = +5

Más fácil que desplazarse y enmascarar un solo número binario grande en mi humilde opinión.

Cuando obtenemos la dirección, extraemos la letra correspondiente de la cadena "en sw":

  1   5
  |   |
" en  sw"
   |   |
  -5  -1

Y proceder recursivamente en la celda [n + x]

GB
fuente
3

Perl 5 ( -n), 94 bytes

-5 bytes gracias a Grimy

@A=map/./g,__wwswsnwwseenwwenwnwnenwn;%H=(n,-5,s=>5,e,1,w,-1);$_+=$H{$,=$A[$_]},say$,until$_<2

TIO

Nahuel Fouilleul
fuente
-8
Grimmy
-2
Grimmy
-5
Grimmy
1
¿Quiere decir que debería publicarlo como una respuesta separada?
Grimmy
1
Sí, porque parece que hiciste la mayor parte del trabajo, fue interesante ver cómo siempre podemos ahorrar espacio
Nahuel Fouilleul
2

JavaScript, 80 73 71 bytes

Adaptado de la solución Python de Chas, así que por favor también a +1él.

f=n=>--n?(d=" wwswsnwwseenwwenwnwnenwn"[n])+f(n+~~{n:-4,s:6,e:2}[d]):``

Pruébalo en línea!

1 byte guardado gracias a Arnauld .

Lanudo
fuente
Gracias, @Arnauld :) También lo había visto yo también.
Shaggy
2

Carbón , 43 40 bytes

NθW⊖θ«≔I§”)“⊞x⟧∧⎚⁵2”ιι§nwesι≧⁺⁻⁺﹪ι²×³ι⁵θ

Pruébalo en línea! El enlace es a la versión detallada del código. Basado en las respuestas de @ ChasBrown y @ xnor. Explicación:

Nθ

Entra en la habitación.

W⊖θ«

Establezca la variable de bucle ien uno menos que el número de habitación y repita mientras no sea cero.

«≔I§”)“⊞x⟧∧⎚⁵2”ιι

Extraiga la dirección de la cadena comprimida 0113130113220112010102010. (El inicio 0es solo un dígito de relleno).

§nwesι

Imprime la dirección.

≧⁺⁻⁺﹪ι²×³ι⁵θ

Use la fórmula de @ xnor para calcular el nuevo número de habitación.

Neil
fuente
2

Jalea , 30 29 bytes

“þ&ƊĿñ÷°e’b6Ḥ_5Ż⁸+ị¥ƬI‘ị“®ȯẹ»

Pruébalo en línea!

Un enlace monádico que toma la celda inicial y devuelve una cadena con las instrucciones.

¡Me encanta el hecho de que el diccionario de Jelly tiene una palabra como 'Kennesaw' (una ciudad al noroeste de Atlanta, Georgia), que se usa aquí porque indexarlo con [5, 1, -5, -1] + 1da nesw!

Explicación

“þ...e’                    | Base-250 integer 1962789844189344852  
       b6                  | Convert to base 6 (2, 2, 5, 2, 5, 0, 2, 2, 5, 3, 3, 0, 2, 2, 3, 0, 2, 0, 2, 0, 3, 0, 2, 0)
         Ḥ                 | Double
          _5               | Subtract 5
            Ż              | Prepend 0
             ⁸  ¥Ƭ         | Using this as the right argument and the original link argument as the left argument, loop the following as a dyad until there is no change, collecting up results
              +            | - Add the left argument to:
               ị           |   - The left argument indexed into the right argument
                  I        | Differences between consecutive numbers
                   ‘       | Increment by 1
                    ị“®ȯẹ» | Index into "Kennesaw"
Nick Kennedy
fuente
2

PHP , 110 bytes

Una solución que no es un puerto de gran respuesta de Chas Brown o gran respuesta de XNOR . ¡Sé que esto es más largo pero quería tener una solución diferente!

for($n=$argn;$n>1;$n=ord($s[$n*2+1])%30)echo($s='0000w<w sEw"s)n w%w&s-e*e+n&w+w,e/n*w/n,w1n.e5n0w5n2')[$n*2];

Pruébalo en línea!

He creado una cadena de mapeo que tiene 2 caracteres para cada celda en el tablero. El primer carácter para cada celda es un movimiento (n / e / s / w) o 0el código ASCII mod 30 del segundo carácter devolverá otro número de celda que deberíamos seguir su movimiento en modo recursivo hasta que salgamos de la celda ( cell < 2).

Por ejemplo para la entrada de 8:

  • 2 caracteres para la celda 8son:w%
  • Significa imprimir wy continuar con movimientos para la celda de%
  • El código ASCII de %es 37, cuyo mod 30 será 7, por lo que la siguiente celda a seguir es 7.
  • 2 caracteres para la celda 7son: n (el último carácter es espacio, código ASCII = 32)
  • Significa imprimir ny continuar con movimientos para la celda de 32 mod 30 que es 2.
  • 2 caracteres por celda 2 son: w<(código ASCII del último carácter = 60)
  • Significa imprimir w y continuar con movimientos para la celda de 60 mod 30 que es0 .
  • Si el número de celda es menor que 2 , ¡el ciclo se detiene!
  • Resultado final impreso: wnw

PHP , 75 bytes

Esta versión está escrita por Grimy , ¡es 35 bytes más corta que mi respuesta original porque él / ella es más inteligente! Comentario de Grimy: "4 * 25 <256, por lo que solo necesita 1 byte por celda, no 2"

for($n=$argn;$n=ord("0\0~f;6o4R:s%ql&rup*@^tIDbx"[$n%25]);)echo news[$n%4];

Pruébalo en línea!


PHP , 71 bytes

Este puerto de la respuesta de Arnauld, que es el puerto de la respuesta de xnor , pero como un bucle en lugar de una función recursiva, ya que resulta ser más corto en PHP.

for($n=$argn;--$n;$n+=$d*3+$d%2-4)echo nwes[$d=79459389361621/4**$n&3];

Pruébalo en línea!

Noche2
fuente
2
4 * 25 <256, por lo que solo necesita 1 byte por celda, no 2: ¡ Pruébelo en línea!
Grimmy
1
@ Grimy, increíble, creo que tienes que publicarlo como una respuesta separada, es lo suficientemente diferente.
Noche2
1
No voy a hacer eso, así que eliges incorporarlo en tu respuesta o dejarlo como un comentario.
Grimmy
1
@Grimy, agregó su versión con su nombre. Gracias de todos modos.
Noche2
2

C (clang) , 81 bytes

v;f(p){p-1&&putchar(v="00wwswsnwwseenwwenwnwnenwn"[p])+f(p+=v%5?6-v%8:v%2?5:-5);}

Pruébalo en línea!

Gracias a @ Tommylee2k sugerencia -8! + llamada recursiva

C (clang) , 90 bytes

v;f(p){for(char*l="00wwswsnwwseenwwenwnwnenwn";p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v=l[p]);}

Pruébalo en línea!

Similar a todas las soluciones no comprimidas.

AZTECCO
fuente
1
se puede acortar:v;f(p){for(;p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v="00wwswsnwwseenwwenwnwnenwn"[p]);}
Tommylee2k
1

05AB1E , 45 43 bytes

õ?[Ð#.•DUo¢ê`Ω÷‰₂¡)R€ûK•¦sè©?Ž₁9₂в6-'€Ã®kè+

Puerto de @ChasBrown Python 2 .

Pruébalo en línea o verifique todos los casos de prueba .

Explicación:

õ?               # Output an empty string
                 # (to overwrite the implicit output if the input is 1)
[                # Start an infinite loop:
 Ð               #  Triplicate the top of the stack
                 #  (which is the (implicit) input in the first iteration)
  #              #  If it's exactly 1: stop the infinite loop
  .•DUo¢ê`Ω÷‰₂¡)R€ûK
                 #  Push compressed string "a  wwswsnwwseenwwenwnwnenwn"
   ¦             #  Remove the first character
    sè           #  Swap to get the number, and use it to index into the string
      ©          #  Store it in variable `®` (without popping)
       ?         #  Print it without trailing newline
  Ž₁9            #  Push compressed integer 22449
     ₂в          #  Convert to base-26 as list: [1,7,5,11]
       6-        #  Subtract 6 from each: [-5,1,-1,5]
         '€Ã    '#  Push dictionary string "news"
            ®k   #  Get the index in this string of character `®`
              è  #  And use that to index into the integer-list
               + #  And add it to the originally triplicated integer

Vea este consejo 05AB1E mío (las cuatro secciones) para entender por qué .•DUo¢ê`Ω÷‰₂¡)R€ûK•es "a wwswsnwwseenwwenwnwnenwn"; Ž₁9es 22449; Ž₁9₂вes [1,7,5,11]; y '€Ães "news".

Kevin Cruijssen
fuente
1
¡Esa conveniente cadena de diccionario debe haber sido una buena noticia!
Neil
@Neil definitivamente. :) Aunque aparentemente la cadena del diccionario westernes mejor. ; p
Kevin Cruijssen
1

Bash , 120 bytes

S=__wwswsnwwseenwwenwnwnenwn
N=n-5w-1s05e01
for((i=$1;$i>1;i+=$j)){ d=${S:$i:1};j=${N:`expr index $N $d`:2};printf $d; }

Pruébalo en línea!

Jugué por un tiempo tratando de empacar la cadena como mordiscos, pero la decodificación requeriría más caracteres que el número guardado.

Cómo funciona:

S=__wwswsnwwseenwwenwnwnenwn

La cadena $ S contiene un solo carácter (n, w, s, e) para cada habitación que muestra qué dirección tomar para mover una habitación hacia la salida, omitiendo las habitaciones 0 y 1.

N=n-5w-1s05e01

La cadena $ N tiene el delta para sumar / restar del número de habitación actual para cada cambio de dirección (n: -5, w: -1, s: +5, e: +1)

for((i=$1;$i>1;i+=$j)){ d=${S:$i:1};j=${N:`expr index $N $d`:2};printf $d; }

Comience con $ i igual al número de habitación dado en la línea de comando ($ 1). Asigne el carácter en el índice $ i en la cadena $ S a $ d. Recupere el valor delta de $ N para la dirección a la siguiente habitación, asignándolo a $ j.

Imprima la siguiente dirección para obtener $ d.

Suma / resta el delta en $ j a / desde $ i.

Haga un bucle hasta que salgamos de la habitación # 2 (mientras $ i> 1).

golpear
fuente
1

Kotlin , 112 bytes

val d="  113130113220112010102010"
fun p(r:Int):String=if(r>1)"nwes"[d[r]-'0']+p("046:"[d[r]-'0']-'5'+r)
else ""

Pruébalo en línea!

JohnWells
fuente