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.