Hagamos un mapa de mazmorra

9

Hace mucho tiempo, cuando pasaba más tiempo jugando juegos de rol, uno de los problemas que tenían algunos jugadores era rastrear el movimiento del grupo y dibujar el mapa adecuado. Así que vengo con una idea, para comprobar cómo ustedes lidian con este problema.

La tarea es escribir una función, que toma como parámetro de entrada la lista de direcciones (aprobada como estructura de su elección) ^v<>, muestra el mapa de la mazmorra. En el ejemplo para input: >>>vvv<<<^^^output será:

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

Casos de prueba

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



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


^^^^^vvv<<<^^vv>>>>>>>>vv>><<^^^^v>>>>v^<^

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

Como es un desafío de código de golf, gana el código más corto.

Feliz golf.

EDITAR Perdón por la edición tardía, no tuve mucho tiempo recientemente.

El mapa se genera en función del movimiento. Debe contener solo corredores que fueron visitados durante la caminata. Por lo tanto, crear una gran sala no será una respuesta válida.

Hay tres símbolos válidos en el mapa:

  • | pared vertical
  • | pared horizontal
  • + intersección de pared vertical y horizontal.

La longitud máxima de la ruta es de 255 caracteres (pero si puede, no se limite).

Más casos de prueba:

 ><><><><

 +--+
 |  |
 +--+

 >^<v

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

Espero que ahora todo esté claro.

usuario902383
fuente
3
Debe proporcionar una descripción de la tarea. Los dos casos de prueba ni siquiera se manejan de una manera que parezca consistente: el primero agrega una región desconectada sin razón aparente.
feersum
3
Su segundo ejemplo tiene una habitación cerrada, que inicialmente pensé que era porque el borde exterior debería ser rectangular, pero luego el tercer ejemplo refuta esa idea. Utilice el Sandbox para obtener comentarios sobre un desafío antes de publicar.
El'endia Starman
2
Excelente. Todavía sugeriría ser explícito sobre cómo se construye la mazmorra a partir de los movimientos.
El'endia Starman
1
¿Qué quieres decir con "mostrar mapa"? ¿Está permitido devolver el mapa desde una función?
Paul Schmitz
3
Esto se ve interesante. ¿Alguna posibilidad de editar para volver a abrirlo? Cosas a tener en cuenta en particular: a partir de los ejemplos, parece que no le importa el espacio en blanco adicional alrededor de la salida, pero sería bueno aclararlo. Además, si describe explícitamente el aspecto de la pared y responde a la pregunta de la leche, debería aclararla lo suficiente. Una cosa que creo que no ha cubierto es qué producción vvv>>^^^<<produciría (¿cruces? ¿Tuberías?)
Dave

Respuestas:

3

Javascript (ES6), 261 254 243 bytes

s=>{v=Array(w=32);p=526;b=n=>v[n>>5]&(1<<(n&31));B=(n,i)=>b(p+n)|b(p-n)?i:0;[...0+s].map(c=>v[(p+=[0,1,-1,w,-w]['0><v^'.indexOf(c)])>>5]|=1<<(p&31));for(z='',p=0;p<w*w;z+=' |-+'[b(p)?0:B(1,1)|B(w,2)||B(31,3)|B(33,3)],p++%w||(z+=`
`));return z}

JSFiddle

Arnauld
fuente
Puede eliminar el returnreemplazando el ;con ,y el {}con()
Cyoce
@Cyoce: hay un forbucle que no se puede incrustar de esa manera.
Arnauld
luego reemplace {con eval("y }con ")para eliminar el código de
Cyoce
@Cyoce - Desafortunadamente, creo que necesitaría escapar del salto de línea literal como '\\n'si lo hiciera. Si cuento correctamente, eso realmente conduce a +1 byte. ¿O hay una mejor manera de incrustar el salto de línea en la evaluación?
Arnauld
Solo necesitaría, \nya que las cadenas de plantilla admiten nuevas líneas literales, pero eso aún lo dejaría en el mismo recuento de bytes. Oh bien
Cyoce
3

C, 246 bytes

n,y,*g,*p;main(c,v)char**v;{for(n=c*2+3,g=calloc(n*n,8),p=g+(n+1)*(c+1);c--;y=*v[c],p-=(y>70?n:1)*(y%5%4?-1:1))*p=1;for(y=n-1;--y;)for(c=n-1;c--;putchar(c?" |-++|-+"[*p?0:p[1]|p[-1]|(p[n]|p[-n])*2|(p[1+n]|p[1-n]|p[n-1]|p[-n-1])*4]:10))p=g+y*n+c;}

Toma la entrada como caracteres separados, por ejemplo:

./mapper '>' '>' '>' 'v' 'v' 'v' '<' '<' '<' '^' '^' '^'

O más convenientemente, este formato (¡intencionalmente sin comillas!):

./mapper $(echo '>>>vvv<<<^^^' | fold -w1)

O para una entrada aleatoria (bastante ineficiente):

./mapper $(LC_CTYPE=C tr -dc '0-3' < /dev/urandom | tr '0123' '<>^v' | head -c 10 | fold -w1)

Y finalmente, usar awkpara recortar el resultado significa que podemos crecer mucho más:

./mapper $(LC_CTYPE=C tr -dc '0-3' < /dev/urandom | tr '0123' '<>^v' | head -c 500 | fold -w1) | awk '/[^ ]/{l=match($0,"\\+");if(l&&(l<L||!L))L=l;v[i++]=$0}END{for(;j<i;){l=v[j++];print substr(l,L,match(l," *$")-L)}}'

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

Salidas a stdout. Utiliza el hecho de que se permite el relleno alrededor del mapa (produce un mapa que tiene una longitud de borde 2 * n + 1, colocando la posición final en el medio).

Descompostura

Esto funciona al recorrer los argumentos en reversa y moverse en reversa. En realidad, utiliza el hecho de que arg 0 es el nombre del programa; no importa cuál sea el nombre, pero nos permite visitar tanto la celda inicial como la última (así como todas las celdas intermedias) sin necesidad de un manejo especial.

n,                                  // Size of internal grid
y,                                  // Loop counter / current character
*g,                                 // Internal grid memory
*p;                                 // Current working pointer
main(c,v)char**v;{                  // K&R style function declaration
    for(                            // Step 1: identify visited cells
        n=c*2+3,                    //  Set output grid size
        g=calloc(n*n,8),            //  Allocate map storage space
        p=g+(n+1)*(c+1);            //  Start at centre
        c--;                        //  Loop over directions in reverse
        y=*v[c],                    //  Get current direction
        p-=(y>70?n:1)*(y%5%4?-1:1)  //  Move in reverse
    )*p=1;                          //  Mark cell visited
    for(y=n-1;--y;)                 // For each row (except edges)
        for(c=n-1;c--;              //   For each column (except edges, +1 for \n)
            putchar(c?" |-++|-+"[   //   Print wall using lookup table
                *p?0:p[1]|p[-1]|(p[n]|p[-n])*2|(p[1+n]|p[1-n]|p[n-1]|p[-n-1])*4
            ]:10)                   //   Or newline
        )p=g+y*n+c;                 //   Set current cell (happens first)
}
Dave
fuente