给一张桌子,放在椅子上


41

挑战

将为您提供一个表,以ASCII |和绘制_。您的任务是在椅子周围摆放椅子。

输入:

 ____
|    |
|    |
|    |
|    |
|____|

输出:

 _^_^_
<     >
|     |
<     >
|     |
<_ _ _>
  v v

那些椅子是用<>和制成的v^

另一个例子:

生产线中必须有尽可能多的椅子。

  _____
 |     |_____
 |           |
 |           |
 |           |
 |      _____|
 |_____|


  _^_^_
 <     |_^_^_
 |           >
 <           |
 |           |
 <      _ _ _>
 |_ _ _| v v
   v v

每把椅子之间必须有空间。并且>_^_^_<是无效的,应该是|_^_^_|

  _____       _____
 |     |_____|     |
 |                 |
 |                 |
 |                 |
 |      ___________|
 |_____|


  _^_^_       _^_^_
 <     |_^_^_|     >
 |                 |
 <                 >
 |                 |
 <      _ _ _ _ _ _>
 |_ _ _| v v v v v
   v v

“甜甜圈”内部不得有椅子。

  _________________
 |      _____      |
 |     |     |     |
 |     |     |     |
 |     |_____|     |
 |_________________|


  _^_^_^_^_^_^_^_^_
 <      _____      >
 |     |     |     |
 <     |     |     >
 |     |_____|     |
 <_ _ _ _ _ _ _ _ _>
   v v v v v v v v

^v优先考虑<>。自己没有椅子(必须至少有一个|_成排的)。

  _________________
 |      _____      |
 |     |     |     |
 |     |     |_____|
 |     |_____
 |___________|


  _^_^_^_^_^_^_^_^_
 <      _ _ _      >
 |     | v v |     |
 <     >     <_ _ _>
 |     |_^_^_  v v
 <_ _ _ _ _ _|
   v v v v v

这是代码高尔夫,所以最短的代码获胜。


2
我很困惑,为什么椅子从侧面嵌入桌子?
Optimizer 2015年

如果我没记错的话,您原来的沙箱帖子在垂直桌子线和椅子线之间有一个空格。就像水平桌子线和椅子之间有一点空间一样。
Optimizer

1
看起来椅子彼此之间的距离是1,但是任何输入的周围都不能被2划分。该计划应该如何开始主持。顺时针还是逆时针?从右上角,左上角等等?

1
我也认为第三个示例存在问题-第二个和第三个“顶部”椅子之间有多余的空间-以及在最后一个示例中,右下角

1
第一个测试用例似乎已损坏。输入是只有4宽,其输出是5
小麦向导

Answers:


34

Python 2中,1033 1007 924 879 829 787 713 699 692 691 688 687 672 670 664 659 654 648 643 642 630 625 623 620 570 560 554 545 518 514 513 510 505 492 476 454 451 443个字节

感谢Riley,节省了6个字节

感谢Adnan,节省了6个字节

由于这个问题已有一年多了,但仍然没有答案,我想尝试一下。

n,i,o,u="\nI _";R=lambda x:range(1,x-1)
b=open(i).read()
s=b.split(n)
z=max(map(len,s))+3
a=[list(i+x.ljust(z,i))for x in[i]+s+[i]]
for x in R(len(a))*len(b):
 A=a[x];B=a[x+1];C=a[x-1]
 for y in R(z):
    D=A[y-1:y+2];k=B[y];j=A[y+1]
    if(i in[C[y],k]+D+(k==u)*B[y-1:y+2]or"V"==j)&(A[y]==o):A[y]=i
    if"|"==A[y]==C[y]:A[y]={i:"|",j:">",A[y-1]:"<"}[i]
    if[u]*3==D:A[y],B[y]={i:u+k,C[y]:"^"+k,k:" V"}[i]
print n.join(`y`[2::5]for y in a).replace(i,o)

在线尝试!

程序读取表中名为的文件并将I表及其椅子打印到std::out。我不确定一堆边缘案例,所以我做出了最好的判断(无论花费多少精力),但似乎通过了所有测试案例。一些输出不完全匹配,但是它们都具有相同数量的椅子。

说明

第一行只是简单地设置一些定义,这些定义将来会为我们节省字节:

(为了以后的可读性,我将解压缩这些宏)

n,i,o="\nI ";R=lambda x:range(1,x-1)

然后,我们将打开一个名为的文件,I因为我们已经有了一个简短的变量,因此可以节省一些字节。

b=open("I").read().split("\n")

我们沿换行符分割以创建字符串列表(图像的行)

s=b.split(n)

然后,我找到最长的线的长度,以便可以将所有线填充到该长度。(我也加了3,因为我们需要一些额外的填充)

 z=max(map(len,s))+3

然后,我们执行实际的填充并I在边缘周围创建字符边框。这是因为稍后我们需要告诉形状的内部和外部之间的差异。我们还将数据类型从字符串列表更改为字符列表(长度为1的字符串)。

a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]

下一行只是另一个字节保存定义。

(我还将解开这个包装)

B=R(len(a))

现在,我们希望将I角色传播到形状之外的任何地方。我们可以使用伪细胞自动机来做到这一点。每个都I将传播到任何相邻的字符。我们可以循环直到自动机稳定下来,但是迭代次数不会超过字符数,因此我们只循环遍历b(原始输入)中的每个字符

for _ in b:

对于每次迭代,我们都希望跳过2D列表中的每个字符(不包括最外面的填充)

 for x in range(1,len(a)-1):
    A=a[x]  #<--Another definition I will fill in for clarity
    for y in range(1,z-1):

对于每个职位,我们运行以下代码:

if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "

让我们分解一下。

我们有一个if,其中两个条件之间用&(逐位and)分隔

第一个简单地检查I相邻单元格中是否有一个,第二个简单地检查当前单元格中是否有一个" "。如果通过这些条件,则将当前单元格设置为I


现在我们已经确定了形状的外部和内部,我们可以开始将椅子放在桌子周围了。

我们再次遍历所有单元格(并设置更多速记)

for x in range(1,len(a)-1):
 A=a[x]
 for y in range(1,z-1):
        k=a[x+1][y]

现在,这是我最喜欢的部分。到目前为止,如果您在我无聊的高尔夫运动(主要是基于定义的高尔夫运动)中苦苦挣扎,那么我将以聪明的高尔夫技巧来奖励您(如果我自己也这么说的话)。

python中的一些背景:

在Python中,如果您尝试分配两次字典密钥,则它将分配后者。例如

>>> {1:"a",1:"b"}[1]
'b'

我们将滥用此属性来将当前单元格分配给特定字符。

第一个条件是

if["_"]*3==a[x][y-1:y+2]:a[x][y],a[x+1][y]={"I":"_"+a[x+1][y],a[x-1][y]:"^ ",a[x+1][y]:" V"}["I"]

如果该单元格位于3个_字符的边缘的中间,我们将重新分配当前单元格及其下方的单元格。我们将其分配给通过索引重载字典的结果I。我们首先使用该对设置默认值,"I":"_"+a[x+1][y]这意味着如果没有更改,我们会将两个单元格分配回其原始值。接下来,我们添加一对a[x-1][y]:"^ "。除非当前单元格(a[x-1][y])上方的单元格充满,否则这不会做任何(重要的)操作I。如果其中有一个I,它将覆盖默认值,告诉我们将椅子放在当前单元格上。接下来,如果该单元格是当前单元格,则我们继续移至该单元格,I然后再次覆盖以将一个朝上的椅子放置在当前点下方。

下一个条件要简单一点

if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]   

我们检查当前单元格及其上方的单元格是否均为|。如果是这样,我们建立一个字典。

字典中的第一对"I":"|"设置默认值。因为I如果I没有重新分配密钥,我们将访问它,它将默认返回到|(已经是该字符)并且什么也不做。

我们添加两个键A[y+1]:">",A[y-1]:"<"如果左右两个单元格中的任何一个都位于左侧,I则它将当前单元格重新分配到指向外部的椅子上。


现在我们只需要输出。但是,我们不能只是打印,我们首先要做几件事。我们必须转换回字符串并删除I我们创建的所有。这是一行完成的。

print "\n".join(`y`[2::5]for y in a).replace("I"," ")

您不能为第一级缩进使用空格,对于两个缩进使用制表符,对于三个缩进使用制表符和空格?这样可以节省一些字节。
莱利

3
这可能是最符合要求的答案。
魔术章鱼缸

2
难道i,o="I "不是i="I";o=" "工作?
阿德南

1
@ErikGolferエリックゴルファー制作n成本为4字节并节省了我6。尽管我不经常使用它,但确实可以节省2字节。
小麦巫师

1
@ Pietu1998感谢您指出这一点。我解决了这个问题
麦迪奇巫师
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.