在正方形中找到对称


14

编写一个包含正整数列表的程序或函数。这些整数均表示2D平面上正方形的边长。每个正方形都可以移动到平面中的任何整数坐标,但不能旋转,也不能与其他正方形重叠。

对于每个正方形(不包括用于空白的空格)使用不同的可打印ASCII字符,您的程序/函数需要打印具有水平或垂直反射对称线的正方形的任何单个排列。如果不存在这样的安排,则不应该打印任何内容。

正方形是不同的字符,因此可以区分它们。只有所有正方形的并集形成的形状才需要对称。您可以假定该列表将包含不超过94个元素(因为有94个字符)。

例如,如果输入为[2, 1, 2, 2, 2],则可能的输出为:

DD--
DD--
Z
FFPP
FFPP

此形状具有一条反射对称的水平线;它的上半部分和下半部分是镜像。还有其他一些可能性:(请注意,不需要触摸正方形,并且只要没有两个正方形由同一字符组成,就可以使用任何字符。)

  55
  55
  %%
  %%
@
  HH
  HH
  ((
  ((
       G

     11 33
     11 33

    22   44
    22   44

对称线也可以是字符之间的边界,例如[2, 4]

!!!!
!!!!  ++
!!!!  ++
!!!!

某些正方形无法对称排列,例如[1, 2, 3]

AAA BB C
AAA BB         (these can't be vertically or horizontally symmetric => no output)
AAA

请记住,即使方形边界不是,整体形状也可能是对称的。例如,有效输出为[2, 1, 1, 1, 1, 4]

AA----
AA----
BC----
DE----

同样,有效输出为[1, 1, 2, 3, 5]

44444
44444
44444
44444
44444
33301
33322
33322

笔记

  • 输入列表将始终包含1到94个元素。
  • 以任何合理的方式进行输入:stdin,命令行,文本文件,函数arg。可以将其略微格式化以适合您的需求,例如{1, 2, 3, 4}[1 2 3 4]
  • 输出到stdout或类似的文件。只要生成的形状具有对称线,任何数量的前导/后跟空格或换行符都可以。
  • 对称的对角线不计算在内(否则这将非常容易)。而且,它必须是反射对称的,而不是旋转或过渡的。
  • 老实说,我不确定该任务在计算上有多困难。您可以发布部分答案来解决问题的某些子集(尤其是如果您想展示一种特别聪明的算法)。这些没有资格获胜。
    • 例如,您可能假设输入始终至少具有一种对称排列(因此[1, 2, 3],永远不会输入类似的列表)。
    • 或者,例如,您可能只考虑正方形边界以及整体形状对称的布置。在这种情况下,[1, 1, 2, 3, 5]将没有输出。
    • 如果您想发疯,可以将其扩展到矩形甚至是多米诺骨牌

计分

您的分数是程序大小(以字节为单位)。最低分获胜。决胜局将首先发布答案。


2
解决方案的要点是[2, 4, 6, 7, 8, 9, 11, 15, 16, 17, 18, 19, 24, 25, 27, 29, 33, 35, 37, 42, 50, 112],尽管由于该问题提供了更多的自由,所以可能还有其他解决方案。
Sp3000

Answers:


4

Python 2中,460个 452 437字节

exec"""def f(L):
 if[]==L:
  X{2}[map(" ".__lt__,q)for q in G]);Z{2}zip(*X));C=Z==Z[::-1]or X==X[::-1]
  if C:print"\\n".join(map("".join,G))
  return C
 x=L[-1];T=S-x+1;R=range(x)
 for n in range(T*T):
  i=n%T;j=n/T
  if all({1}=" "{0}):
{0}:{1}chr(32+len(L))
   r=f(L[:-1])
{0}:{1}" "
   if r:return r""".format("   for a,b in[(a,b)for a in R for b in R]","G[i+a][j+b]=","=filter(sum,")
L=input()
S=sum(L)
G=[S*[" "]for _ in[0]*S]
f(L)

目前只有轻度的打高尔夫球,但这是一些开始的事情。我尝试将其exec用于第10行和第12行,但由于某种原因,它没有让我使用。

L通过STDIN 输入列表,例如[2, 1, 2, 2, 2]。该程序只是尝试将正方形放置在sum(L) x sum(L)网格中的所有可能性。

样本输出(为了紧凑起见,删除了空白行):

[2, 1, 2, 2, 2]

%%       
%%       
$$       
$$       
"        
##       
##       
!!       
!!      

[2, 4]

""""  
""""  
""""  
""""  
 !!   
 !!   

[2, 1, 1, 1]

$!!  
#!!  
 "   

[1, 1, 2, 3, 5]

%%%%%       
%%%%%       
%%%%%       
%%%%%       
%%%%%       
$$$##       
$$$##       
$$$"!       

[1, 4, 1, 8]

$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
# """" !      
  """"        
  """"        
  """"        

[8, 1, 4, 1]

$   !!!!!!!!  
    !!!!!!!!  
####!!!!!!!!  
####!!!!!!!!  
####!!!!!!!!  
####!!!!!!!!  
    !!!!!!!!  
"   !!!!!!!!  

(The algorithm starts placing from the last square first, prioritising left then up)

稍显混乱的版本(452字节):

def f(L):
 if[]==L:
  X=filter(sum,[map(" ".__lt__,q)for q in G]);Z=filter(sum,zip(*X));C=Z==Z[::-1]or X==X[::-1]
  if C:print"\n".join(map("".join,G))
  return C
 x=L[-1];T=S-x+1;R=range(x);V=[(a,b)for a in R for b in R]
 for n in range(T*T):
  i=n%T;j=n/T
  if all(G[i+a][j+b]<"!"for a,b in V):
   for a,b in V:G[i+a][j+b]=chr(32+len(L))
   r=f(L[:-1])
   for a,b in V:G[i+a][j+b]=" "
   if r:return r
L=input()
S=sum(L)
G=[S*[" "]for _ in[0]*S]
f(L)

@ Calvin'sHobbies我刚刚意识到我忘了剥离空的行和列(这意味着配置也必须相对于对称)。[1, 1, 2, 3, 5]现在运行正常。
Sp3000

啊。我以为蛮横的力量将永远消失。
加尔文的爱好2015年

@ Calvin'sHobbies它适用于较大的木板,但施加其他约束只会使情况更糟:P
Sp3000 2015年

我认为您可以使用缩进技巧节省一些字符。
加尔文的爱好2015年
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.