Caminar por el laberinto

15

O tal vez no es realmente un laberinto, pero aún así.

Reglas:

  1. De entrada es una cadena de dos líneas, que consiste en *, 1, xy X. Esa cuerda es un laberinto para caminar. Las líneas tienen la misma longitud .

    Puede tomar la entrada como una cadena con ,(coma) o cualquier separador conveniente entre estas dos líneas. O podría tomar ambas líneas como argumentos separados para su función.

  2. La salida es el número de pasos que debe seguir para salir de la cadena (el último paso es el paso que lo mueve fuera de la cadena).

  3. Empiezas en la esquina superior izquierda (la línea superior), antes del primer símbolo.

  4. Para cada paso, se mueve hacia adelante por un símbolo (de n-ésimo (n + 1) ésima posición ). Luego, dependiendo del personaje que pises, el resultado es diferente. Esto es lo que hace cada personaje:

    • *- nada. Simplemente lo pisas normalmente.
    • x- una vez que lo pisó, cambie la línea, pero permanezca en la misma distancia horizontal desde el principio. Por ejemplo, pisó la tercera posición de la línea superior y encontró una minúscula xaquí. Luego te mueves inmediatamente a la línea inferior, pero nuevamente en la tercera posición.
    • X- cambie la línea y pase a la siguiente posición. El ejemplo es el mismo allí, pero también te mueves de la tercera a la cuarta posición (por lo tanto, estás en la segunda línea en la cuarta posición).
    • 1 - Solo avance una posición más.

Una vez que cada personaje hace su trabajo, se reemplaza con un espacio y ya no "funciona".

Siguen ejemplos.

  1. Entrada :

    x
    *
    

    Como se dijo antes, comienza antes del primer símbolo de la primera línea. El primer paso te mueve en letra xy esta letra te cambia a la segunda línea. La letra xya no funciona como x, sino que se reemplaza con *. Esto será más relevante en los últimos ejemplos. Ahora estás en un asterisco en la línea inferior, y no te hizo nada.

    El segundo paso es avanzar y salir de la cadena, por lo que se completa el laberinto, y tomó 2 pasos.

    Salida 2 .

  2. Entrada :

    xX*
    x1*
    

    1er paso : avanzas x, lo que te mueve en la xlínea inferior. Aquí viene la regla que dice que el carácter usado se reemplaza con un asterisco. Luego retrocede en la primera línea, pero ya no está xallí, ya que se ha utilizado y se convirtió en un asterisco. Entonces, se mueve con seguridad en este asterisco y se completa el paso (ahora está en la primera posición de la primera línea).

    Segundo paso : sigues adelante X, te empuja a la línea inferior y luego te empuja hacia adelante. Ahora reside en la tercera posición de la segunda línea (asterisco), sin haber visitado nunca la segunda posición (que contiene 1).

    3er paso : avanzas, saliendo de la cuerda.

    Salida : 3.

Casos de prueba:

  1. Entrada:

    *1*
    xxx
    

    Salida: 3. (porque 1te hace saltar en la tercera posición). Allí nunca visita la segunda línea, pero se requiere parte de la entrada.

  2. Entrada:

    *X*1*x
    x*1xx*
    

    Salida: 4.

  3. Entrada:

    1x1x
    ***X
    

    Salida: 3.

  4. Entrada:

    1*x1xxx1*x
    x*x1*11X1x
    

    Salida: 6.

  5. Entrada:

    xXXXxxx111*
    **xxx11*xxx
    

    Salida: 6.

nicael
fuente
Una cadena vacía no debería ser una entrada válida, ya que no es una cadena de dos líneas
edc65
@edc Jaja, me estoy contradiciendo. Si, de hecho.
nicael
"\n\n"es una línea de dos cuerdas ...
Feersum
@feersum, entonces creo que la salida debería ser 1, cuando comienzas antes de la primera línea, luego avanzas un paso y luego terminas el laberinto ...
Amit Gold

Respuestas:

5

Caracoles, 34 bytes

A^
\1r|\xud|\Xaa7},(\*|\xud=\x)r},

Expandido:

{
    {
        \1 r |
        \x ud |
        \X aa7
    },
    (\* | \x ud =\x)
    r
},

Para una ruta que toma N pasos, el programa encuentra una coincidencia exitosa para cada recorrido de 0 pasos, 1 pasos, ..., N - 1 pasos.

Feersum
fuente
3

Haskell, 68 66 65 bytes

(a:b)#l@(c:d)|a<'+'=1+b#d|a>'w'=l#('*':b)|a>'W'=d#b|1<2=b#d
_#_=1

La función #toma ambas líneas como parámetros separados. Ejemplo de uso: "1x1x" # "***X"-> 3.

Solo tenemos que contar las estrellas *que pisamos más 1 para irnos.

(a:b)#l@(c:d)             -- bind: a -> first char of first line
                                   b -> rest of first line
                                   l -> whole second line
                                   c -> first char of second line (never used)
                                   d -> rest of second line
   |a < '+' = 1+b#d       -- stepped on a *, so add 1 and go on
   |a > 'w' = l#('*':b)   -- x switches lines and replaces the x with *
   |a > 'W' = d#b         -- X switch lines and go on
   |1<2     = b#d         -- the rest (-> 1) simply walks forward
_#_=1                     -- base case: the empty string counts 1 for leaving

Editar: @feersum guardó un byte. ¡Gracias!

nimi
fuente
Probablemente podría proporcionar una demostración funcional (en ideone.com sería conveniente), no soy un programador de Haskell pero me gustaría jugar con él.
nicael
1
@nicael: mira aquí
nimi
¿Podría usar, por ejemplo, en a>'a'lugar de a=='x'?
feersum
No me he dado cuenta de eso, pero en realidad la cadena vacía es una entrada no válida (ya que me he declarado que la entrada es una cadena de dos líneas), por lo que podría eliminar la validación para este caso límite :)
nicael
@feersum: sí, eso funciona. ¡Gracias!
nimi
2

JavaScript (ES6), 119

l=>{z=-~l.search`
`,l=[...l+' '];for(n=p=0;(c=l[p%=2*z])>' ';p+=c>'X'?z:c>'1'?z+1:c>'0'?1:(++n,1))l[p]='*';return-~n}

Menos golf

l=>{
  z=1+l.search`\n`;
  l=[...l+' '];
  for( n = p = 0; 
       (c=l[p%=2*z])>' '; 
       p += c>'X' ? z : c>'1' ? z+1 : c>'0'? 1 : (++n,1) )
    l[p] = '*';
  return 1+n
}

Prueba

f=l=>{z=-~l.search`
`,l=[...l+' '];for(n=p=0;(c=l[p%=2*z])>' ';p+=c>'X'?z:c>'1'?z+1:c>'0'?1:(++n,1))l[p]='*';return-~n}

[['x\n*',2]
,['xX*\nx1*',3]
,['*1*\nxxx',3]
,['*X*1*x\nx*1xx*',4]
,['1x1x\n***X',3]
,['1*x1xxx1*x\nx*x1*11X1x',6]
,['xXXXxxx111*\n**xxx11*xxx',6]
].forEach(t=>{
  var i=t[0],k=t[1],r=f(i) 
  console.log('Test result '+r+(r==k?' OK ':' KO (expected '+k+')')+'\n'+i)
})  
 

edc65
fuente
2

TSQL (sqlserver 2012+), 276 bytes

Golfizado:

DECLARE @i VARCHAR(99)=
'xXXXxxx111*'+CHAR(13)+CHAR(10)+
'**xxx11*xxx'

,@t BIT=0,@c INT=1,@ INT=1WHILE @<LEN(@i)/2SELECT @t-=IIF(a like'[1*]'or'xx'=a+b,0,1),@c+=IIF(a='*'or'xx'=a+b,1,0),@+=IIF(a='x'and'x'>b,0,1)FROM(SELECT SUBSTRING(d,@t*c+@,1)a,SUBSTRING(d,(1-@t)*c+@,1)b FROM(SELECT LEN(@i)/2+1c,REPLACE(@i,'X','q'COLLATE thai_bin)d)x)x PRINT @c

Sin golf:

DECLARE @i VARCHAR(99)=
'xXXXxxx111*'+CHAR(13)+CHAR(10)+
'**xxx11*xxx'

,@t BIT=0,@c INT=1,@ INT=1
WHILE @<LEN(@i)/2
  SELECT
    @t-=IIF(a like'[1*]'or'xx'=a+b,0,1),
    @c+=IIF(a='*'or'xx'=a+b,1,0),
    @ +=IIF(a='x'and'x'>b,0,1)
  FROM
    (
      SELECT
        SUBSTRING(d,@t*c+@,1)a,
        SUBSTRING(d,(1-@t)*c+@,1)b
      FROM 
        (SELECT LEN(@i)/2+1c,REPLACE(@i,'X','q'COLLATE thai_bin)d)x
    )x

PRINT @c

Violín

t-clausen.dk
fuente
1

JavaScript, 211 bytes

Estoy pensando en hacer una versión que muestre cada paso jugado uno tras otro, que se muestre en una página web.

(x,y)=>{t=0;l=0;n=1;while(t<x.length){c=(l?x:y);if(c[t]=='x'){l=!l;if(l){x=x.slice(0,t-2)+'*'+x.slice(t-1);}else{y=y.slice(0,t-2)+'*'+y.slice(t-1);}}if(c[t]=='X'){l=!l;t++;}if(c[t]=='1'){return n}

Se utiliza más bytes de lo que esperaba a la hora de sustituir xa *causa de JS inmutable Strings. Se agradecen las sugerencias para mejorar, especialmente con la pieza de repuesto.

hierba carbonizada
fuente