钓鱼立方网


30

立方体可以由六个正方形作为侧面。但是您也可以将三个2x1矩形对折,然后将它们粘合在一起以形成一个立方体。现在,在此挑战中,您将获得一组由正方形组成的零件,并且您必须确定是否可以选择零件来形成单位立方体。并非所有部件都必须使用,可能还剩下一些。

细节

这些片段以两个不同字符的字符串或黑白图像或任何方便的2D栅格格式给出。在下面的示例中,我假设形成碎片的像素为黑色,背景为白色。

共有一侧的两个像素被视为属于同一块。这些片段只能沿着分隔像素的网格线折叠,并且无法剪切。立方体的每一侧都有一个像素的大小,立方体的每一侧只能由一层构成。

输出必须为值。

测试用例

在下面,空格是背景,哈希符号#代表片段。

(还有待添加)

有效

##  
 ## 
  ##

 #  
####
 #  

# # # # # # #

# ##
## #

无效

###
###

#  #
####

### ## ####

运行以下代码片段以获取更多测试用例。

PS:这是对这一挑战的概括


为什么JS代码片段仅打印其他硬编码的测试用例?为什么不把它们放到岗位上哈哈?
魔术章鱼缸

1
@carusocomputing这只是防止帖子混乱的一种措施。
瑕疵的

会永远有六个像素吗?
小麦向导

不,可能会有所不同。
瑕疵的

1
@Blue啊,不,分析碎片的输入是挑战的一部分。此输入将大大简化该操作,因此我不允许这样做。谢谢你的慰问!
瑕疵

Answers:


7

C,824803字节

#define Z return
#define Y char*b
#define N --n
i,j,n,w,h,A,B,C,D,E,F,G,H;char c[9999],*r,*d;x(b)Y;{if(b<c||*b<35)Z;++n;*b^=1;x(b-1);x(b+1);x(b-w);x(b+w);}m(b,p,y)Y,*p;{d=b;if(!y)for(y=-1,--p;1[++p]&31;)d+=w;for(i=0;*p&31?!(*p&16>>i)||b[i]&1:0;++i>4?p+=y,b+=w,i=0:0);Z!(*p&31)?x(d),n:0;}a(b)Y;{for(j=n=0;j<w*h;++j)if(m(c+j,b,1)||m(c+j,b,0))Z n;Z 0;}f(Y){bzero(c,9999);for(h=0,b=strcpy(c,b);r=b,b=strchr(b+1,10);h++,w=b-r);for(A=2,r=1+"@_`^C@|T@^R@XO@XX`|FB@|PP@|DD@PXN@XHX@XPX`PPXL@XHHX@XLDD@XPPX`PPPXH@PXHHH@PPPPP@";*r;r+=A+=r[-1]/96)while(a(r));A=B=C=D=E=F=G=H=0;while(a("PX")||a("XH")) (n-=3)?N?N?N?0:++H:++G:++F:++C;while(a("^")||a("PPPP"))(n-=4)?N?N?0:++H:++G:++E;while(a("P"))N?N?N?N?N?N?0:++H:++G:++F:++D:++B:++A;Z H||(G&&A)||(F&&B+B+A>1)||(E&&A>1)||D>1||C>1||((D||C)*3+B*2+A>5)*(A>1||B>2||A*B);}

注意:包括一个错误修复程序(上一个条目错误地将一个Tromino和两个Domino标识为一个立方体)。 在TIO驱动程序代码中,有更多的测试用例,现在有一个通过/失败跟踪器。hexomino测试用例已用标签中的预期通过/失败值更新。

在线尝试!

...并且在进行详细解释之前,值得一较高层次的概述。

基本概述

该算法应用模式匹配器对以给定模式作为其子集的找到的每个多米诺进行分类。当多氨基酸被匹配时,它们是“未标记的”,从而将它们再次从模式匹配中排除。匹配器给出的初始分类只是对多米诺骨牌中瓷砖数的计数。

首先应用匹配器以剔除所有无法折叠到立方体上的多氨基酸。这些多氨基酸的分类被丢弃。如果这些多氨基酸出现在较高水平的氨基酸中,则匹配成功。因此,我们只关心每个类的“不可折叠”的最小子集。与填充的编码一起显示的是所有这些多米诺骨牌(不包括其垂直反射)。编码使用每个字符的4-0位表示每一行的正方形:

[^C```] [XHX``] [PPPXH] [XHHX`] [PXN``] [|PP``]
 ####.   ##...   #....   ##...   #....   ###..
 ...##   .#...   #....   .#...   ##...   #....
 .....   ##...   #....   .#...   .###.   #....
 .....   .....   ##...   ##...   .....   .....
 .....   .....   .#...   .....   .....   .....
[|FB``] [XPX``] [PPXL`] [XLDD`] [XPPX`] [|DD``]
 ###..   ##...   #....   ##...   ##...   ###..
 ..##.   #....   #....   .##..   #....   ..#..
 ...#.   ##...   ##...   ..#..   #....   ..#..
 .....   .....   .##..   ..#..   ##...   .....
 .....   .....   .....   .....   .....   .....
[|T```] [^R```] [PXHHH] [XO```] [_````] [PPPPP]
 ###..   ####.   #....   ##...   #####   #....
 #.#..   #..#.   ##...   .####   .....   #....
 .....   .....   .#...   .....   .....   #....
 .....   .....   .#...   .....   .....   #....
 .....   .....   .#...   .....   .....   #....

[XX```]
 ##...
 ##...
 .....
 .....
 .....

一旦剔除这些多氨基酸,我们会将其余的多氨基酸分类为相关类别。值得注意的是,几乎在所有情况下,人们都可以找到剩余的多氨基酸(可折叠到立方体上),然后简单地搜索六个总数。有两个例外:

  • 角tromino和线tromino无法形成立方体
  • 线tetromino和多米诺骨牌无法形成立方体

为了适应这一限制,我们从AH分为8个类别:A代表单体(单块瓷砖),B代表多米诺骨牌,C代表角果糖,D代表直线果糖,E代表直线特洛米诺糖,F代表其他特洛米诺糖,G代表戊糖胺,H代表己糖胺。不属于这些类别之一的任何事物都将被忽略。计数属于每个类别的多氨基酸就足够了。

最后,我们只是根据一个巨型方程和这些列表返回真实性或虚假性。

取消评论

i,j,n,w,h,A,B,C,D,E,F,G,H;char c[9999],*r,*d;
x(b)char*b;{      // recursively unmarks polyomino pointed to by b.
   if(b<c||*b<35)return;
   ++n; *b^=1;    // Tabulates tiles in n as it goes.
   x(b-1);x(b+1);x(b-w);x(b+w); // left/up/down/right
}
m(b,p,y)char*b,*p;{ // pattern match area b with pattern p, direction y.
                    //   y=1 scans down; y=0 scans up.
   d=b; // d tracks a tile in the currently matched pattern for unmarking.
        // Note that all patterns are oriented to where "top-left" is a tile.
   if(!y) // ...when scanning up, move p to the end, set y to -1 to count backward,
          //    and advance d to guarantee it points to a tile (now "bottom-left")
      for(y=-1,--p;1[++p]&31;)d+=w;
   // Match the pattern
   for(i=0;*p&31?!(*p&16>>i)||b[i]&1:0;++i>4?p+=y,b+=w,i=0:0);
   return !(*p&31)   // If it matches...
          ? x(d),n   // ...unmark/count total polyomino tiles and return the count
          : 0;
}
a(b)char*b;{ // Scan for an occurrence of the pattern b.
   for(j=n=0;j<w*h;++j)
      if(m(c+j,b,1)||m(c+j,b,0)) // (short circuit) try down then up
         return n;
   return 0;
}
// This is our function.  The parameter is a string containing the entire area,
// delimited by new lines.  The algorithm assumes that this is a rectangular area.
// '#' is used for tiles; ' ' spaces.
f(char*b) {
   bzero(c,9999); // Init categories, c buffer
   for(h=0,b=strcpy(c,b);r=b,b=strchr(b+1,10);h++,w=b-r); // Find width/height
   // Unmark all polyominoes that contain unfoldable subsets.  This was
   // compacted since the last version as follows.  A tracks
   // the current pattern's length; r[-1], usually terminator for the
   // previous pattern, encodes whether the length increases; and o/c
   // the patterns were sorted by length.
   for(A=2,r=1+"@_`^C@|T@^R@XO@XX`|FB@|PP@|DD@PXN@XHX@XPX`PPXL@XHHX@XLDD@XPPX`PPPXH@PXHHH@PPPPP@";*r;r+=A+=r[-1]/96)
      while(a(r));
   A=B=C=D=E=F=G=H=0;
   // Match corner trominoes now to ensure they go into C.
   while(a("PX")||a("XH"))
      (n-=3)
         ?   --n
             ?   --n
                 ?   --n
                    ?   0 // More than 6 tiles?  Ignore it.
                    : ++H // 6 tiles?  It's an H.
                 : ++G // 5 tiles?  It's a G.
             : ++F // 4 tiles?  It's an F.
        : ++C; // only 3 tiles?  It's a C.
   // Now match line tetrominoes to ensure they go into E.
   while(a("^")||a("PPPP"))
      (n-=4)
         ?   --n
             ?   --n
                 ?   0 // More than 6 tiles?  Ignore it.
                 : ++H // 6 tiles?  It's an H.
             : ++G // 5 tiles?  It's a G.
         : ++E; // only 4 tiles?  It's an E.
   // Find all remaining tetrominoes ("P" is a monomino pattern)
   while(a("P"))
      --n
         ?   --n
             ?   --n
                 ?   --n
                     ?   --n
                         ?   --n
                             ?   0 // More than 6 tiles?  Ignore it.
                             : ++H // 6 tiles?  It's an H.
                         : ++G // 5 tiles? It's a G.
                     : ++F // 4 tiles?  It's an F.
                : ++D // 3 tiles?  It's a D.
            : ++B // 2 tiles?  It's a B.
         : ++A; // only 1 tile? It's an A.
   // Figure out if we can form a cube:
   return H               // Yes if we have a foldable hexomino
      ||(G&&A)            // Yes if we have a foldable pentomino
                          // and a monomino
      ||(F&&B+B+A>1)      // Yes if we have a foldable non-line tetromino
                          // and 2 other tiles (dominoes count twice).
                          // Either one domino or two monominoes will do.
      ||(E&&A>1)          // Yes if we have a foldable line tetromino (E)
                          // and two monominoes (A).  Note we can't make a
                          // cube with a line tetromino and a domino (B).
      ||D>1               // Yes if we have two line trominoes
      ||C>1               // Yes if we have two corner trominoes
      ||((D||C)*3+B*2+A>5)
                          // Any combination of trominoes, dominoes, monominoes>6,
                          // where trominoes are used at most once
                          // (via logical or)...
         * (A>1||B>2||A*B)
                          // ...times this includer/excluder fudge factor
                          // that culls out the one non-working case;
                          // see table:
                          //
                          // Trominos Dominos Monomos Cube  A>1 B>2 A*B
                          //    1        0       3+    yes   Y   N   0
                          //    1        1       1+    yes   Y   N   1
                          //    1        2       0     no    N   N   0
                          //    0+       3       0+    yes   Y   Y   1
      ;
}

这行不通。这个问题说,一些碎片可能是未使用的
约翰·德沃夏克

@JanDvorak感谢您指出这一点!
H Walters

对我来说,您将其拼写为tromino而不是triomino似乎很奇怪,但这似乎都是有效的拼写。
mbomb007 '01
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.