解决网格图


22

七巧板是由七个形状制成的夹层拼图:五种不同大小的三角形,平行四边形和正方形。给定形状,目标是使用所有零件且不重叠来重新创建形状。显然,有无数种方法可以将这组零件排列在平面上。一个有趣的子集是

网格七巧板

我们可以得出“标准”七巧板方成由细分更大的方形网格成16个个小方格。网格七巧板只是由七巧板块组成的形状,因此,这些块的所有顶点都在网格点上。

这些是我们在此挑战中要考虑的七巧板难题,因为它们可能比更一般的难题更容易处理。

附带说明:1942年,中国数学家熊传雄和王付特拉证明了只有13个凸七巧板。他们首先表明,可以将问题简化为网格七巧板,然后使用一些组合和几何参数。这些都是这13个:

挑战

给定可解决的网格七巧板,将网格七巧板的解剖输出为七个七巧板。

IO

七巧板以黑白图像形式给出(形状为黑色,背景为白色),两边的倍数均为50px。网格的宽度正好为50px。网格线平行于图像的侧面。

编辑:图像可以接受为输入,并以任何方便的光栅图像格式(如PNG,TIFF,PBM等)作为输出返回,但是可以将其表示为二进制2d数组或字符串或矩阵。

输出应再次具有相同的大小,并应再次具有相同的形状,但每个部件具有不同的颜色,或者用白线分隔所有部件。值得注意的是,非矩形四边形可以翻转。

块边界上的像素不必完全与形状上的像素匹配,如果存在锯齿效果或其他模糊现象,也可以。

输入和输出示例:

例子:

可能的解决方案:


在这一挑战中,图像处理是完全不必要的障碍。如果您只是将输入指定为小型二进制数组,我会发现它更具吸引力。
Sparr

1
正如我所说,是在沙箱中进行讨论的。但是我怀疑它会增加很多字节,因为任务本身要困难得多。
瑕疵的

3
我是建议输入和输出保持原样的人之一,我之所以提出此建议,是因为我认为这是提出七巧板挑战的最自然,最合适的方法。任何形式的输入/输出都将占用大量字节,因此我认为这并不是真正的问题。
El'endia Starman

1
我同意Elendia。图形I / O的唯一问题是,它可能会限制没有图形功能的语言。就是说,如果人们知道这种格式,那么PBM和PGM非常接近ASCII技术,就没有真正的问题。en.wikipedia.org/wiki/Netpbm_format
Level River St

1
@LevelRiverSt这是一个很好的观点,我认为使用这些格式甚至是零和一的二维数组/字符串都是完全可以接受的。
瑕疵的

Answers:


31

BBC BASIC,570 514 490字节ASCII

http://www.bbcbasic.co.uk/bbcwin/download.html下载口译员

435个字节标记

完整程序L.bmp在屏幕上显示输入,然后对其进行修改以找到解决方案。

*DISPLAY L
t=PI/8q=FNa(1)
DEFFNa(n)IFn=7END
LOCALz,j,p,i,c,s,x,y,m,u,v
F.z=0TO99u=z MOD10*100v=z DIV10*100ORIGINu,v
F.j=0TO12S.4p=0F.i=j+3TOj+9S.2c=9*COS(i*t)s=9*SIN(i*t)p=p*4-(POINT(c,s)<>0)*2-(POINT(9*c,9*s)<>0)N.
m=n:IFn=5A.(43A.p)=0p=0m=7
IF(ASCM."??O|(C",n)-64A.p)=0THEN
F.i=-1TO0GCOL0,-i*n:c=99*COS(j*t)s=99*SIN(j*t)y=402/3^m MOD3-1MOVE-c-s*y,c*y-s:x=n<3MOVEc*x-s*x,s*x+c*x:x=2778/3^m MOD3-1y=5775/3^m MOD3-1PLOT85-32*(n MOD6>3),c*x-s*y,s*x+c*y:IFi q=FNa(n+1)ORIGINu,v
N.
ENDIF
N.N.=0

说明

请注意,在BBC基本中,1像素= 2单位的距离,因此50x50像素网格变为100x100网格。

我们使用递归函数将2个大三角形,中三角形,正方形和平行四边形放置到形状中。在进行下一个递归调用之前,将绘制列表中较早的形状。如果递归调用返回但没有找到解决方案,则将较早的形状覆盖为黑色,并尝试使用较早的形状的新位置。

绘制完这五个形状后,放置两个小三角形仅仅是一种形式。但是,有必要绘制其中之一,以便在它们具有共同优势的情况下使它们消失。我们只给两个小三角形之一上色。另一个留在自然黑色中。

尝试在不同的x,y坐标和4个不同的旋转位置放置每种形状。为了测试是否有自由空间可以绘制形状,我们使用下面的模板(角度为45度)。围绕进行旋转,*测试的8个像素位于半径为9和81单位的2个半圆中,并落在辐射线上,相对于x和y轴的奇数倍为22.5度。

对于大三角形,所有8个空格都必须清除。对于其他形状,只有某些单元格必须是透明的,因此要使用遮罩。

+----+----   Shape             Mask HGFEDCBA Mask decimal 
|\ E/|\G /  
| \/F|H\/    1,2. Large triangle    11111111    -1
|C/\ | /     3. Med triangle        00001111    15
|/ D\|/      4. Square              00111100    60
+----*       5. Parallelogram       11101000   -24
|\ B/        6. Small triangle      00000011     3
|A\/         7. Parallogr reversed  00101011    43
| /          Note: reversed parallelogram is checked/drawn at recursion depth n=5
|/           with a special check, but the coordinates are encoded as m=7.  

一旦确定形状适合,就必须绘制它。如果是三角形,则用绘制PLOT 85,如果是平行四边形,则数字高32(请注意,出于PLOT目的,我们将正方形视为特殊的平行四边形)。无论哪种情况,都必须给出3个连续的顶点。第二个顶点是形状的原点(*在上表中标记),大三角形除外(在旋转之前)是大三角形-1,-1.。其他两个顶点可以具有-1,0 or 1从底数3提取的x和y坐标编码的数字,然后通过99缩放,并通过与转动变换为必要cs

非高尔夫代码

  *DISPLAY L
  t=PI/8                                          :REM Constant 22.5 degrees.
  q=FNa(1)                                        :REM Call function, return dummy value to q
  END                                             :REM End the program gracefully if no solution. Absent in golfed version.

  DEFFNa(n)                                       :REM Recursive function to place shapes.
  IFn=7END                                        :REM If n=7 solution found, end program.
  LOCALk,z,j,p,i,c,s,x,y,m,u,v                    :REM declare local variables for function.
  k=ASCMID$("??O|(C",n)-64                        :REM Bitmasks for big tri, big tri, med tri, sq, normal paralellogram, small tri.
  FORz=0TO99                                      :REM For each point on the grid
    u=z MOD10*100:v=z DIV10*100                   :REM calculate its x and y coordinates relative to bottom left of screen
    ORIGINu,v                                     :REM and set the origin to this point.
    FORj=0TO12STEP4                               :REM For each rotation 0,90,180,270deg
      p=0                                         :REM assume no non-black pixels found
      FORi=j+3TOj+9STEP2                          :REM test angles of 3,5,7,9 times 22.5 deg anticlockwise from right x axis.
        c=9*COS(i*t)                             :REM Coords of test points at radius ll
        s=9*SIN(i*t)
        p*=4                                      :REM Leftshift any existing data in p
        p-=(POINT(c,s)<>0)*2+(POINT(9*c,9*s)<>0)  :REM and check pixels at radius 11 and 99.
      NEXT
      m=n                                         :REM The index of the shape to plot normally corresponds with recursion depth n.
      IF n=5 AND (43ANDp)=0 p=0:m=7               :REM If n=5 check if a reverse parallelogram is possible (mask 43). If so, clear p and change m to 7.
      REM                                         :REM Check p against mask k, if the shape fits then...
      IF (k ANDp)=0 THEN
        FOR i=-1 TO 0                               :REM draw the shape in colour, and if deeper recursions prove unsuccesful, redraw it in black.
          GCOL0,-i*n                                :REM Colour is equal to n.
          c=99*COS(j*t)                             :REM Set parameters c and s for scaling by 99
          s=99*SIN(j*t)                             :REM and rotation by 0,90,180 or 270 as appropriate.
          x=-1                                      :REM For vertex 1, x=-1 always.
          y=402/3^m MOD3-1                          :REM Lookup y value for vertex 1.
          MOVEc*x-s*y,s*x+c*y                       :REM Use c and s to transform the vertex and move to it.
          x=n<3                                     :REM For vertex 2, coords are 0,0 except for large triangle where they are -1,-1
          y=x                                       :REM in BBC BASIC, TRUE=-1
          MOVEc*x-s*y,s*x+c*y                       :REM Use c and s to transform the vertex and move to it.
          x=2778/3^m MOD3-1                         :REM Lookup x and y value for vertex 3.
          y=5775/3^m MOD3-1                         :REM PLOT85 uses last 2 points + specified point to make triangle, PLOT85+32 makes paralelogram (or square.)
          PLOT85-32*(n MOD6>3),c*x-s*y,s*x+c*y      :REM Use c and s to transform the vertex and draw shape.
          IFi q=FNa(n+1):ORIGINu,v                  :REM If i=-1 recurse to next level. If it fails, reset the origin before replotting this level's shape in black.
        NEXT
      ENDIF
    NEXT
  NEXT
  =0                                                :REM Dummy value to return from function

输出量

这是程序为测试用例找到的解决方案的蒙太奇。由于打高尔夫球,使用99而不是100会留下一些小的黑洞。由于在搜索过程中会重新绘制形状,因此在某些情况下可能需要花费几秒钟来运行,并且观看起来非常有趣。

在此处输入图片说明


4
哇,我印象深刻。现在,我很想观看其中的视频!=)
瑕疵的2016年
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.