我可以用砖块,楼板和楼梯做成这种形状吗?


13

考虑一个矩形二维网格,其中每个单元格可以为空(.)或完整(0)。

例如

..00....
0000....
.00000..
000...00
..000000
000.00..

网格被认为是无限的,所描绘区域之外的所有像元都是空的。

目标是使用一组7个形状各异的砖块覆盖填充的空间并使空白空间保持开放,每个砖块占用4个网格(2×2)。

这些是7块砖:

  • 方块-1个变体

    11
    11
    
  • 平板-2个款式

    ..
    22
    33
    ..
  • 楼梯-4个款式

    .4
    44
    5.
    55
    66
    .6
    77
    7.

这些积木必须始终与其单元格是输入网格的单元格的宽度和高度的两倍的网格对齐。每块积木只能占据该较大网格的一个单元,但是较小网格可以在较大网格下方平移(上移,下移,左移,右移),以提供更多用于查找封面的选项。网格和单个砖块均不得旋转。

因此,覆盖(又称求解)上面示例的一种方法是这样的:

..11....
2211....
.47733..
447...22
..771133
227.11..

(相同的相邻砖块仍然可能引起歧义,但是仔细识别较大的网格可以解决这一问题。)

一个无效的解决方案

000000
000000

566774
556744

因为砖块并不都与较大的网格对齐,也不是仅占据其中一个单元。

一个有效的解决方案是连续3个块:

111111
111111

另一个有效的解决方案涉及6个平板:

......
222222
333333
......

因此请注意,某些输入网格具有多种解决方案

一个无效的解决方案

00.00
00...

11.33
11...

因为砖块不与较大的网格对齐。平板需要向左或向右移动一个,但是当然盖板将是不完整的。此输入网格没有解决方案

挑战

编写一个程序(通过标准输入/命令行),将一个矩形的.“”和0“” 文本块放入,该矩形块代表要覆盖的网格。

如果有有效的覆盖解决方案,则以与上述相同的方式(通过stdout)打印任何一种解决方案,并0用适当的1穿7墙砖替换所有。

如果没有解决方案,则您的程序不应输出任何内容,只需安静地正常结束即可。

笔记

  • 输入和输出不必具有相同的矩形尺寸。您的输出可以包含所有的多余行和/或列.(只要它们不会使解决方案无效)。

  • .如果不影响填充的空格,也可以修剪所有的行和列。例如

    222222
    333333
    

    是一个有效的解决方案

    000000
    000000
    

    相反,00..00无法删除其中的两个空列,因为这将使填充的空间混乱。

  • 您可以选择假定输入具有单个尾随换行符。即使没有解决方案,输出中的尾随换行符也很好。

  • 完全空(所有.)的网格和琐碎的0×0网格不是您需要担心的输入情况。但是1×1 0网格与包含至少一个的所有其他网格一样0。(您可能无法假定输入网格的宽度或高度是均匀的!)

  • 代替程序,您可以编写一个将输入作为字符串参数并正常打印输出或将其返回为字符串的函数。如果没有解决方案,则可以返回任何伪造的值

  • 您可以使用9个不同的可打印ASCII字符代替. 0 1 2 3 4 5 6 7。请务必说出您的替代者是什么!换行符必须保持原样。

计分

以字节为单位的最短代码获胜。Tiebreaker是票数最高的职位。

这种挑战的灵感来自于楼梯我的世界,它遵循此处介绍的同样的规则。如果您喜欢PPCG和Minecraft,则可能需要查看PPCG Minecraft服务器


3
看来Minecraft服务器未在Golf脚本中实现-无聊:-)
Thomas Weller 2015年

5
@ThomasWeller它在CJam中重新实现以节省一些字节。
Alex A.

Answers:


6

蟒蛇- 525个 491 478 430字节

r=range
def t(s):
 m=s.find("\n")+1
 for q in r(4):
  try:
   for i in r(-q%2,m-1,2):
    for j in r(-q/2,len(s)/m,2):
     k,g=j*m+i,""
     b=[k,k+1,k+m,k+m+1]
     for z in b:g+=a(s,z)
     for z in b:
      if a(s,z)!="d":s=s[:z]+`dict(dddd=0,zzdd=3,ddzz=2,zzzd=7,zzdz=6,zdzz=5,dzzz=4,zzzz=1)[g]`+s[z+1:]
   return s
  except:d
def a(v,i):
 try:
  if v[i]!="\n":return v[i]
  return "d"
 except:return "d"

说明:这是我的第一个代码高尔夫,所以它可能不是最佳选择,但是它是这样工作的。函数t(s)提供传入的字符串的结果。首先,它找到列数,然后将四种可能的不同翻译数乘以1(无,左,上,左上),然后尝试解决它为每一个。它查看每个2x2块,并将其映射到由字典指定的有效块号,并将零更改为该数字。

如果它在词典中找不到一个,它将放弃该特定的偏移量并从下一个偏移量开始。如果它经过所有4个偏移而没有找到有效的解决方案,则结束而不输出任何东西。a(v,i)允许在字符串外使用默认值,并忽略换行符。尽管在运行期间可能会得到部分解决方案,但如果存在,它将始终使用最终正确的解决方案覆盖它们。

编辑:使用不同的字符映射:。-> d,0-> z,其他所有数字都归自己所有。这适用于输入和输出。


1
欢迎来到PPCG!我们有一些用Python打高尔夫球的技巧; 我认为您可以节省一些字节。
lirtosiast
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.