让我们制作一个地牢地图


9

很久以前,当我花更多时间玩RPG时,一些玩家遇到的问题之一是跟踪聚会的活动并绘制正确的地图。因此,我提出了一个想法,以检查你们如何处理这个问题。

任务是编写一个函数,该函数将方向作为输入参数列表(作为您选择的结构传递)^v<>,显示地牢地图。在输入示例中,>>>vvv<<<^^^输出为:

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

测试用例

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



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


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

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

因为这是高尔夫球比赛的挑战,所以最短的比赛胜出。

快乐打高尔夫球。

编辑 很抱歉,您不能进行后期编辑,最近我没有太多时间。

地图是根据运动生成的。它应该只包含在步行过程中访问过的走廊。因此,创建一个大房间将不是一个有效的答案。

地图中有三个有效符号:

  • | 垂直墙
  • | 水平墙
  • + 纵横墙的交点。

路径的最大长度为255个字符(但如果可以,请不要限制自己)。

更多测试用例:

 ><><><><

 +--+
 |  |
 +--+

 >^<v

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

我希望现在一切都清楚了。


3
您需要提供任务说明。甚至没有以看起来一致的方式来处理这两个测试用例-第一个没有明显的原因添加了一个断开的区域。
feersum'9

3
您的第二个示例有一个封闭的房间,我最初认为这是因为外边界应为矩形,但随后的第三个示例则反驳了这一想法。发布前,请使用沙盒获取有关挑战的反馈。
El'endia Starman'9

2
优秀的。我仍然建议明确说明这些动作如何构成地牢。
El'endia Starman

1
“显示地图”是什么意思?是否可以从函数返回地图?
Paul Schmitz

3
这看起来很有趣。是否有进行编辑使其重新打开的机会?需要特别注意的事情:从示例中看,您似乎不介意输出周围有多余的空格,但是最好弄清楚。另外,如果您明确描述墙壁的外观并回答牛奶的问题,也应使问题足够清楚。我认为您尚未涵盖的一件事是vvv>>^^^<<将产生什么输出(交叉?管道?)
Dave

Answers:


3

使用Javascript(ES6),261个 254 243字节

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


您可以删除return由替换;,{}()
Cyoce

@Cyoce-那里有一个for无法以这种方式嵌入的循环。
Arnauld

然后替换{eval(",并}")删除return codegolf.stackexchange.com/a/80967/41042
Cyoce

@Cyoce-不幸的是,我认为我需要逃避原义的换行符,'\\n'就像这样做一样。如果我计算正确,那实际上会导致+1个字节。还是有更好的方法将换行符嵌入到评估中?
Arnauld

您只需要\n因为模板字符串支持原义的换行符,但是仍然可以使它保持相同的字节数。很好
Cyoce

3

C,246字节

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

将输入作为单独的字符,例如:

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

或更方便的是,此格式(有意不加引号!):

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

或对于(效率很低)随机输入:

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

最后,awk用来裁剪结果意味着我们可以做得更大:

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

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

输出到标准输出。使用在地图周围允许填充的事实(生成边长为2 * n + 1的地图,将最终位置放在中间)。

分解

这通过反向循环遍历参数并反向移动来实现。它实际上使用了事实,即arg 0是程序名称。它的名称无关紧要,但是它使我们能够访问初始和最后一个单元格(以及中间的所有单元格)而无需特殊处理。

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)
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.