俄罗斯方块七巧板


13

介绍

七巧板是经典的难题,涉及将积木排列/装配成各种形状。来自中文七巧板-字面意思是“七个技巧板”。让我们采用这个想法,并使用七个Tetrominos块填充网格。

挑战

编写一个函数或程序,该函数或程序将网格坐标数组作为输入,并输出一个完整的10 x 20的网格,其中填充有俄罗斯方块,但指定坐标除外。

通过尝试保持片段分布均匀来优化您的分数。

标准

使用坐标粘贴框完成任务。有五组坐标。随意修改写入坐标的格式,但不要修改值。

数据集#2无法解决-在这种情况下,只需输出填充了输入像元的网格(即X孔所在的位置)。

输入值

网格坐标表示网格中的“孔”。这些细胞不能包含Tetromino的任何部分。

网格坐标:

(0,0), (1,0), (2,0), ... (9,0)
(0,1), (1,1), (2,1), ... (9,1)
.
.
.
(0,19), (1,19), (2,19), ... (9,19)
  • 使用您的编程语言选择的数组样式输入坐标。

  • X或其他可打印的ASCII表示网格中的孔。

输出量

使用标准Tetris网格大小(宽10单元,高20单元),当且仅当使用Tetromino碎片可以完全完美地填充网格时,才打印解决方案网格。

用字母构造件IOLJTZS如下:

I          
I          L      J
I    OO    L      J     T     ZZ      SS
I    OO    LL    JJ    TTT     ZZ    SS

没有输入坐标的输出解决方案示例:

ZZIIIILLLI
JZZTTTLLLI
JJJSTLOOLI
SZZSSLOOLI
SSZZSLLJJI
TSOOSLLJII
TTOOSSLJII
TZOOSSLZII
ZZOOSSZZII
ZJJJJSZLLI
TTTJJOOILI
ITZJJOOILI
IZZTTTLIII
IZOOTZLIII
IJOOZZLLII
LJJJZSSTII
LLLTSSTTTI
LLLTTSSZJI
OOLTSSZZJI
OOIIIIZJJI

分配如下:

I          
I          L      J
I    OO    L      J     T     ZZ      SS
I    OO    LL    JJ    TTT     ZZ    SS

11   6     8     6      6     7      6

笔记

坐标代表一个XY位于网格上。网格基于0,这意味着坐标(0,0)应该是作者选择的左上角或左下角单元格。

砖可以:

  • 由作者酌情选择。
  • 按照作者认为合适的方式旋转。
  • 由作者自行决定将其放置在网格上的任何位置(又名:无俄罗斯方块引力)

砖块不能:

  • 放置在网格边界之外。
  • 与网格中的现有砖块或孔重叠。
  • 是非标准的俄罗斯方块Tetromino棋子。

计分

您的分数格式为:

(1000-[代码字节])*(M / 10 +1)

其中,M是用于分配解决方案集中的部分的乘数。

最高的三月之分获胜。

要计算M,请为每组添加最低的单个tetromino分布值,然后将平均值四舍五入以计算M。

例如:

Set 1: 5
Set 2: 4
Set 3: 5
Set 4: 6
Set 5: 3

6 + 4 + 5 + 4 + 4 = 21/5 = 4.6

因此,您可以将其4用作M值。

注意:如果一个集合没有解,则不要将该集合作为计算M的因数,因为它不会有Tetromino分布。


4
通常,在问题发布后改进问题通常是困难的,因为如果更改很大,将使已经开始解决问题的人员的工作无效(或更糟的是,甚至发布结果)。我建议在沙盒中发布挑战想法。是在主要发布之前寻求反馈和完善规范的地方。话虽这么说,但快速浏览后,我发现您的挑战没有任何明显的问题。
马丁·恩德

@MartinBüttnerDuly指出,感谢您的反馈。
CzarMatt 2015年

2
3月的Ides = 3月15日。我必须查一下。
级圣河

我做了一些小改动以预先加载任务描述,因为否则无法理解我们在第一次阅读时被要求做的事情。我认为,如果您指出哪些输入案例无法解决,那么这将是一种改进,这样它们就可以在评分数据集中用作测试案例。
彼得·泰勒

@PeterTaylor足够公平,我添加了无法解决的解决方案集。感谢您的反馈。
CzarMatt 2015年

Answers:


2

Python 3,819字节,M = 0,分数= 181

这是蛮力的DFS程序。它构建一个numpy数组,并插入所有输入的孔。然后,将最左边的未填充的图块放在具有该图块的最高行上,然后放置一个tetromino。递归地,我们现在再做一次-当我们找不到解决方案或回溯并在第一个机会尝试另一块时。

这有一个中号的0,因为它试图以确定的顺序使用作品,而且几乎总是没有找到最后一个列表中的一个解决方案。我尝试在每个循环中使用随机排序的列表进行更均匀的分配,但是我得到的M仅为2,这不值得导入random.shuffle所需的字节。

我无法评论以下代码,因为在打高尔夫球时,我早已忘记了它的大部分功能。总体思路:

  • 导入带有1个字母的名称的numpy和itertools产品
  • 将某些内建函数重命名为1个字母的函数,并定义一个lambda以保存字节
  • 将可能的四聚体构建为numpy nd-array,包括所有旋转
  • 在递归函数中:
    • 获取所需的未填充瓷砖的位置,并在零件清单中循环
    • 对于每件作品,循环浏览其译文(上下移动)
    • 如果某事不起作用(一块掉到板子上,碰到另一块,打一个洞等),请尝试下一个翻译或下一个整块
    • 如果可行,那就太好了。尝试一下,然后递归调用该函数。
    • 如果该路径不起作用,它将返回“ a”,因此我们再试一次。如果确实有效,它将返回董事会,然后我们将其通过。
  • 最后是程序。我们将10x20板构建为1的小数数组。
  • 输入的形式为(x1,y1);(x2,y2); ...我们在其中的每个孔上放置一个9,然后得到在其上运行函数的结果。
  • 然后,打印语句将显示成功结果或一行一行空白的原始木板,用适当的字母或符号代替数字。
import numpy as n
from itertools import product as e
m,s=range,len
p=[n.rot90(a,k)for a,r in[([[2,2]]*2,1),([[3]*3,[1,3,1]],4),([[0]*4],2),([[1,1,6],[6]*3],4),([[7,1,1],[7]*3],4),([[4,4,1],[1,4,4]],2),([[1,5,5],[5,5,1]],2)]for k in m(r)]
o=lambda a:e(m(s(a)),m(s(a[0])))
def t(l,d=0):
	g=list(zip(*n.where(l==1)))[0]
	for a in p:
		for u,v in o(a):
			w,x=l.copy(),0
			for r,c in o(a):
				if a[r,c]!=1:
					i,j=g[0]+r-u,g[1]+c-v
					if any([i<0,i>19,j<0,j>9])or l[i,j]!=1:
						x=1
						break
					w[i,j]=a[r,c]
			if x==0:
				if len(w[w==1]):
					f=t(w,d+1)
					if type(f)==str:continue
					return f
				return w
	return'a'
b=n.ones((20,10))
b[list(zip(*[eval(k)[::-1]for k in input().split(';')]))]=9
a=t(b)
for r in(a,b)[type(a)==str]:
	print(''.join(map(dict(zip([0,2,3,4,5,6,7,9,1],'IOTZSLJX-')).get,r)))

在线尝试!

样品测试:

In: (1,1);(8,1);(4,4);(5,8);(4,11);(5,15);(1,18);(8,18)
Out: 
IIIIOOOOLL
TXOOOOOOXL
TTOOOOOOTL
TOOIOOOOTT
TOOIXOOTTI
TTTITOOTTI
TTTITTTTII
OOTTTTTTII
OOTTTXOOII
TTTTOOOOII
TTTTOOOOII
TTTTXTOOII
ITTTTTTTII
ITTTTTTTII
IITTTLLTTI
IITOOXLTTI
IITOOTLTTI
IITTLTTTTI
IXTLLTJTXI
ILLLLLJJJI

1
哦,我的-太神奇了。感谢您的精彩写作和出色的工作!
CzarMatt
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.