Vamos fazer um mapa da masmorra


9

Há muito tempo, quando eu passava mais tempo jogando RPG, uma das questões que alguns jogadores tinham, era rastrear o movimento das partes e desenhar o mapa adequado. Então, eu tenho uma idéia, para verificar como vocês lidam com esse problema.

A tarefa é escrever uma função que, como lista de parâmetros de entrada das direções (passada como estrutura de sua escolha) ^v<>, exiba o mapa da masmorra. No exemplo para input: >>>vvv<<<^^^output será:

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

Casos de teste

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



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


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

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

Como é o desafio do código de golfe, o menor código vence.

Feliz golfe.

EDITAR Desculpe pela edição tardia, não tive muito tempo recentemente.

O mapa é gerado com base no movimento. Deve conter apenas corredores visitados durante a caminhada. Portanto, criar uma sala grande não será uma resposta válida.

Existem três símbolos válidos no mapa:

  • | parede vertical
  • | parede horizontal
  • + interseção da parede vertical e horizontal.

O comprimento máximo do caminho é de 255 caracteres (mas se você puder, não se limite).

Mais casos de teste:

 ><><><><

 +--+
 |  |
 +--+

 >^<v

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

Espero que agora esteja tudo claro.


3
Você precisa fornecer uma descrição da tarefa. Os dois casos de teste nem são tratados de uma maneira que pareça consistente - o primeiro adiciona uma região desconectada sem motivo aparente.
feersum 01/09/16

3
Seu segundo exemplo tem uma sala fechada, que eu pensava inicialmente que era porque a borda externa deveria ser retangular, mas o terceiro exemplo refuta essa ideia. Use a Sandbox para obter feedback sobre um desafio antes de postar.
El'endia Starman 01/09/16

2
Excelente. Eu ainda sugeriria ser explícito sobre como a masmorra é construída a partir dos movimentos.
El'endia Starman 01/09/16

11
O que você quer dizer com "mapa de exibição"? É permitido retornar o mapa de uma função?
Paul Schmitz

3
Isso parece interessante. Alguma chance de editar para reabrir? Aspectos a serem observados em particular: a partir dos exemplos, parece que você não se importa com espaço em branco extra ao redor da saída, mas seria bom esclarecer. Além disso, se você descrever explicitamente a aparência da parede e responder à pergunta do leite, ela deverá ficar suficientemente clara. Uma coisa que eu acho que você não tenha coberto é o que a saída vvv>>^^^<<produziria (cruzes tubos?)
Dave

Respostas:


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


Você pode remover o returnsubstituindo ;por ,e {}por()
Cyoce 19/09/16

@ Cyoce - Há um forloop lá que não pode ser incorporado dessa maneira.
Arnauld

em seguida, substitua {por eval("e }com ")para remover o retorno codegolf.stackexchange.com/a/80967/41042
Cyoce 20/16

@ Cyoce - Infelizmente, acho que precisaria escapar da quebra de linha literal como '\\n'se o fizesse. Se eu contar corretamente, isso levará a +1 byte. Ou existe uma maneira melhor de incorporar a quebra de linha na avaliação?
Arnauld

Você só precisaria, \npois as seqüências de modelo suportam novas linhas literais, mas isso ainda deixaria na mesma contagem de bytes. Oh bem
Cyoce 20/09/16

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;}

Recebe a entrada como caracteres separados, por exemplo:

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

Ou, mais convenientemente, este formato (intencionalmente não citado!):

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

Ou para entrada aleatória (bastante ineficiente):

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

E, finalmente, usar awkpara cortar o resultado significa que podemos ficar muito maiores:

./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)}}'

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

Saídas para stdout. Usa o fato de que o preenchimento é permitido ao redor do mapa (produz um mapa com o comprimento da aresta 2 * n + 1, colocando a posição final no meio).

Demolir

Isso funciona repetindo os argumentos em sentido inverso e movendo-se em sentido inverso. Na verdade, usa o fato de que arg 0 é o nome do programa; não importa qual é o nome, mas nos permite visitar a célula inicial e a última (assim como todas as células intermediárias) sem precisar de tratamento 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)
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.