ตกปลาสำหรับแหอวน Cube


30

คิวบ์สามารถทำหกสี่เหลี่ยมเป็นด้านข้าง แต่คุณสามารถพับสี่เหลี่ยม 2x1 สามอันครึ่งแล้วแปะให้เข้าด้วยกันเพื่อสร้างลูกบาศก์ ตอนนี้ในการท้าทายนี้คุณจะได้ชิ้นส่วนที่ทำจากสี่เหลี่ยมและคุณต้องพิจารณาว่าคุณสามารถเลือกชิ้นส่วนเพื่อสร้างคิวบ์ยูนิตได้หรือไม่ ไม่จำเป็นต้องใช้ชิ้นส่วนทั้งหมดอาจมีบางชิ้นที่เหลือ

รายละเอียด

ชิ้นส่วนจะได้รับเป็นสตริงของอักขระสองตัวที่แตกต่างกันหรือภาพขาวดำหรือรูปแบบแรสเตอร์ 2D ที่สะดวกสบาย ในต่อไปนี้ฉันคิดว่าพิกเซลที่ประกอบกันเป็นสีดำและพื้นหลังเป็นสีขาว

พิกเซลสองอันที่แบ่งด้านจะถือว่าเป็นของชิ้นเดียวกัน ชิ้นส่วนสามารถพับได้ตามแนวกริดซึ่งแยกพิกเซลและไม่สามารถตัดได้ แต่ละด้านของคิวบ์มีขนาดหนึ่งพิกเซลและแต่ละด้านของคิวบ์สามารถสร้างได้เพียงชั้นเดียวเท่านั้น

การส่งออกจะต้องเป็นtruthyหรือfalseyค่า

Testcases

ในต่อไปนี้ช่องว่างคือพื้นหลังและสัญลักษณ์แฮช#แสดงถึงส่วนต่างๆ

(เพิ่มเติมที่จะเพิ่ม)

ถูกต้อง

##  
 ## 
  ##

 #  
####
 #  

# # # # # # #

# ##
## #

โมฆะ

###
###

#  #
####

### ## ####

เรียกใช้ตัวอย่างต่อไปนี้เพื่อทดสอบเพิ่มเติม

PS: นี่คือลักษณะทั่วไปของความท้าทายนี้


เหตุใดโค้ด JS จึงพิมพ์งานทดสอบฮาร์ดโค้ดที่เพิ่มเติม ทำไมไม่ลองใส่ไว้ในโพสต์ฮ่าฮ่า?
Magic Octopus Urn

1
@carusocomputing นั่นเป็นเพียงมาตรการในการป้องกันไม่ให้โพสต์รก
ข้อบกพร่อง

จะมีหกพิกเซลเสมอหรือไม่
ข้าวสาลีตัวช่วยสร้าง

ไม่อาจมีมากหรือน้อย
ข้อบกพร่อง

1
@Blue Ah no การวิเคราะห์อินพุตสำหรับส่วนต่างๆเป็นส่วนหนึ่งของความท้าทาย ข้อมูลนี้จะทำให้ง่ายขึ้นเล็กน้อยดังนั้นฉันจะไม่อนุญาต ขอบคุณสำหรับคำถาม!
ข้อบกพร่อง

คำตอบ:


7

C, 824 803 ไบต์

#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 และโดมิโนสองอันว่าเป็นคิวบ์) ในรหัสไดรเวอร์ TIO มีกรณีทดสอบเพิ่มเติมและตอนนี้มีตัวติดตามผ่าน / ไม่ผ่าน กรณีทดสอบ hexomino ได้รับการอัปเดตพร้อมกับค่า pass / fail ในฉลาก

ลองออนไลน์!

... และก่อนที่จะอธิบายในรายละเอียดมันมีค่าภาพรวมระดับสูง

ภาพรวมพื้นฐาน

อัลกอริทึมนี้ใช้ตัวจับคู่รูปแบบเพื่อจัดประเภทแต่ละโพลีโนที่พบด้วยรูปแบบที่กำหนดเป็นชุดย่อย เนื่องจากการจับคู่แบบโพลีโม่พวกเขาจะถูก "ไม่ทำเครื่องหมาย" ยกเว้นพวกเขาจากการจับคู่รูปแบบอีกครั้ง การจำแนกประเภทเริ่มต้นที่กำหนดโดยผู้จับคู่นั้นเป็นเพียงการนับจำนวนไพ่ในโพลีโนมิน

Matcher จะถูกนำไปใช้ก่อนเพื่อกำจัดโพลีโอโมทั้งหมดที่ไม่สามารถพับลงบนคิวบ์ได้ การจำแนกประเภทของโพลีมิโนเหล่านี้จะถูกยกเลิก การแข่งขันประสบความสำเร็จหากโพลีโอโมเหล่านี้ปรากฏภายในกลุ่มที่สูงกว่า ดังนั้นเราสนใจเฉพาะเซตย่อยที่เล็กที่สุดของ "unfoldable" สำหรับแต่ละชั้นเรียน แสดงให้เห็นที่นี่พร้อมกับการเข้ารหัสเบาะเป็น polyominoes ดังกล่าวทั้งหมด (ไม่รวมการสะท้อนแนวตั้ง) การเข้ารหัสใช้บิต 4-0 ของตัวละครแต่ละตัวเพื่อเป็นตัวแทนของช่องสี่เหลี่ยมในแต่ละแถว:

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

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

เมื่อโพลีโม่เหล่านี้ถูกคัดออกแล้วเราจะจัดหมวดหมู่โพลีโอโมที่เหลือออกเป็นหมวดหมู่ที่เกี่ยวข้อง เป็นที่น่าสังเกตว่าในเกือบทุกกรณีมีเพียงคนเดียวที่สามารถหาโพลีโอโมที่ยังคงอยู่ มีข้อยกเว้นสองประการ:

  • tromino มุมและ line tromino ไม่สามารถสร้างคิวบ์ได้
  • บรรทัด tetromino และ domino ไม่สามารถสร้างคิวบ์ได้

เพื่อให้สามารถรองรับข้อ จำกัด นี้เราได้จัดทำ 8 หมวดหมู่จาก AH: A สำหรับ monominoes (lone tile), B สำหรับแต้ม, C สำหรับ trominoes มุม, D สำหรับ trominoes สาย, E สำหรับ tetrominoes อื่น ๆ , G สำหรับ tetrominoes อื่น ๆ , G สำหรับ pentominoes และ H สำหรับ hexominoes สิ่งใดก็ตามที่ไม่ได้อยู่ในหมวดหมู่เหล่านี้จะถูกเพิกเฉย การนับจำนวนโพลีโม่โนมที่พอเพียงในแต่ละหมวดหมู่

ในตอนท้ายเราแค่คืนความจริงหรือความเท็จตามสมการขนาดยักษ์และตารางเหล่านี้

ไม่พอใจกับความคิดเห็น

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
      ;
}

สิ่งนี้ใช้ไม่ได้ คำถามบอกว่าบางชิ้นอาจไม่ได้ใช้
John Dvorak

@JanDvorak ขอบคุณที่ชี้ให้เห็น!
H Walters

สำหรับฉันดูเหมือนว่าแปลกที่คุณสะกดมันเป็นtrominoแทนที่จะเป็นtriominoแต่ทั้งคู่เป็นคาถาที่ใช้ได้ดูเหมือนว่า
mbomb007
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.