แยกตารางออกเป็นกริด


22

บทนำ

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

งาน

การป้อนข้อมูลของคุณคืออาร์เรย์ 2D บิตของบิต 1 หมายถึงบ้านและ 0 ช่องว่าง ขนาดจะมีอย่างน้อย1 × 1และจะมีอย่างน้อยหนึ่ง 1 คุณสามารถใช้อินพุตในรูปแบบที่เหมาะสม (รายการซ้อนจำนวนเต็มรายการของสตริงสตริงหลายบรรทัด ฯลฯ )

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

ตัวอย่างเช่นต่อไปนี้เป็นส่วนที่ถูกต้องของอาร์เรย์:

00|0010|01|1
01|0000|00|0
--+----+--+-
00|0000|00|1
01|0010|01|0
--+----+--+-
01|1000|10|1

ในขณะที่การแบ่งต่อไปนี้ไม่ถูกต้องเนื่องจากมีกริดเซลล์ที่ไม่มี 1s หรือมากกว่าหนึ่ง 1:

00|0010|01|1
--+----+--+-
01|0000|00|0
00|0000|00|1
01|0010|01|0
--+----+--+-
00|1000|10|1

หากมีการแบ่งที่ถูกต้องคุณจะต้องส่งออกค่าความจริงและมิฉะนั้นเป็นค่าเท็จ

กฎและการให้คะแนน

คุณสามารถเขียนโปรแกรมเต็มรูปแบบหรือฟังก์ชั่น จำนวนไบต์ต่ำสุดชนะ

กรณีทดสอบ

[[1]] -> True
[[0,1],[1,0]] -> True
[[1,1],[1,0]] -> False
[[1,0,1],[0,1,0]] -> True
[[1,0],[0,1],[0,1]] -> True
[[1,0,0],[0,0,1],[0,1,1]] -> True
[[1,1,1],[1,1,1],[1,1,1]] -> True
[[1,0,1],[0,1,0],[1,0,0]] -> True
[[1,0,0],[1,0,0],[0,1,1]] -> False
[[0,0,0,0,1],[1,0,0,1,0],[0,0,0,1,0]] -> False
[[0,0,1,0,1],[0,0,0,1,0],[0,0,0,0,0]] -> True
[[1,1,0,0,0],[0,0,0,0,0],[1,0,1,0,0]] -> True
[[1,1,0,1,1],[0,1,0,1,1],[1,0,0,0,0]] -> True
[[0,0,0,0,0,0,0],[0,1,1,1,0,1,0],[0,1,0,0,1,0,0],[0,0,0,0,0,0,1],[0,0,1,0,0,0,1],[1,1,0,1,1,0,0]] -> False
[[1,1,0,0,0,0,0],[1,0,1,1,0,1,0],[0,0,0,0,1,0,0],[0,1,0,1,1,0,0],[1,0,0,0,1,1,0],[0,0,0,0,0,1,0]] -> False
[[0,1,0,1,1,1,0],[0,0,0,0,1,0,0],[0,0,0,0,0,0,0],[1,0,0,1,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,1]] -> True
[[0,1,0,0,1,0,1],[1,0,0,0,1,0,1],[0,0,1,0,1,0,1],[1,0,0,0,1,1,0],[0,0,0,1,1,1,0],[0,1,0,0,1,0,1]] -> True
[[0,1,0,0,1,0,0,1,0],[0,0,0,0,1,1,0,1,0],[1,1,0,0,1,0,0,0,0],[0,0,1,0,1,0,1,0,0],[0,0,1,0,1,0,1,0,0],[0,1,0,0,0,1,0,0,1],[0,1,0,0,0,0,1,0,0]] -> False
[[1,0,1,0,0,1,1,0,1],[0,1,1,0,0,1,1,0,1],[1,0,0,0,0,1,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,1,1],[0,1,1,0,1,0,1,0,1],[1,0,1,0,0,1,1,0,1]] -> True

สามารถ [[0,0,1,0,1], [1,0,0,1,0], [0,0,0,1,0]] แบ่งออกเป็น: 3X1, 2X1, 3X2, 2X1, รูปสี่เหลี่ยม 2X1 ในลักษณะนี้หรือไม่? 001 | 01 --- + - 100 | 10 + - 000 | 10
ประกาศอย่างเป็นทางการ

4
@officialaimm ไม่นั่นไม่ถูกต้อง เส้นกริดต้องวิ่งจากด้านหนึ่งของอาเรย์จนถึงด้านอื่น
Zgarb

กรณีทดสอบที่เสนอ: [[1, 0, 1], [0, 1, 0], [1, 0, 0]]นั่นเป็นเมทริกซ์ 3x3 เดียวที่แนวทางใหม่ของฉันล้มเหลว
Dennis

@Dennis ขอบคุณเพิ่ม
Zgarb

คำตอบ:


7

Pyth, 30 29 26 24 23 ไบต์

sm.Asmmq1ssbCkds./MC./M

ลองออนไลน์

ฉันแน่ใจว่านี่จะสั้นลง นี่คือO (2 mn )โดยที่mและnเป็นความกว้างและความสูงของอาร์เรย์ แต่เสร็จสิ้นการทดสอบสองกรณีสุดท้ายใน 45 วินาทีบนแล็ปท็อปของฉันบนแบตเตอรี่ (i5-5200U ที่มีประสิทธิภาพ จำกัด )

เอาต์พุตจำนวนโซลูชัน

คำอธิบาย

อาร์เรย์ห้ามิติสนุกกับการใช้งานจริง ๆ </sarcasm>คุณไม่ควรที่จะเข้าใจว่ามันใช้งานได้ดีแม้จะมีคำอธิบาย

                    ./M    Find all partitions of each row. Now we have a list of rows,
                           each containing the ways to split the row, each containing
                           the parts of the split (3D).
                   C       Transpose. Now we have a list of ways to split the columns,
                           each containing the rows, each containing the parts of the
                           row (3D).
                ./M        Find all partitions of each row list. Now we have a list of
                           ways to split the columns, each containing the ways to split
                           the rows, each containing the bunch of rows, each containing 
                           the rows in the bunch, each containing the parts of the row
                           (6D).
               s           Combine the ways to split rows & columns into one array (5D).
 m            d            Do the following for each way to split rows & columns (4D):
     m       k                 Do the following for each bunch of rows (3D):
            C                      Transpose the array. We now have a list of column
                                   groups, each containing the row parts (3D).
      m    b                       Do the following for each column group (2D):
          s                            Combine the row parts in the column group. We now
                                       have the list of cells in this row/column group
                                       (1D).
         s                             Sum the cells.
       q1                              Check if the sum is one.
                                   We now have the list of booleans that tell if each
                                   row/column group is valid (1D).
                               We now have the 2D list of booleans that tell if each
                               row/column group in each bunch of rows is valid. (2D)
    s                          Combine the 2D list of booleans to 1D.
  .A                           Check if all values are truthy; if the split is valid.
                           We now have the validity of each split.
s                          Sum the list to get the number of valid solutions.


2

Haskell , 116 ไบต์

import Data.List
m(a:b)=[a:e|e<-m b]++[zipWith(+)a d:e|d:e<-m b];m e=[e]
d=(any$any$all$all(==1)).map(m.transpose).m

ลองออนไลน์!


1
สิ่งนี้ไม่ได้รวบรวม โปรดลบคำตอบของคุณจนกว่าจะได้รับการแก้ไข นอกจากนี้ยังมีศักยภาพในการเล่นกอล์ฟอีกมากมายเช่น การเปลี่ยนชื่อไปmergerows m
Laikoni

ฉันวางแผนที่จะวิ่งออกจากการแข่งขันเนื่องจาก Pythity ที่ยากต่อการเอาชนะและขอบคุณ @Laikoni ที่เห็นว่าฉันอาจทำใจจัดฟันเยื้องของฉัน
Roman Czyborra

2
[[1,0],[0,1],[1,0]]นี้ไม่ถูกต้องจะช่วยให้ในการเท็จ ปัญหาคือการล่มสลายโลภสามารถไปในทางที่ดีขึ้นในภายหลังการล่มสลาย
xnor

ที่จริงการ[[1,1],[1,0]]ล่มสลายของฉัน ขัดขวางการ[[1],[1],[1]]แก้ปัญหาอย่างไม่ถูกต้อง ให้ฉันนอนเหนือสิ่งนี้หรือฉันควรลบ
Roman Czyborra


1

เยลลี่ , 20 ไบต์

ŒṖS€€ỊȦ$ÐfZ€µ⁺€Ȧ€€FS

นี่ยังคงเป็นวิธีการแก้ปัญหาที่ดุร้าย แต่ก็เร็วกว่าคำตอบอื่น ๆ ของฉันเล็กน้อยซึ่งไม่สามารถรับมือกับสองกรณีทดสอบล่าสุดใน TIO และจัดการกับกรณีทดสอบทั้งหมดใน ~ 4 วินาที

ลองออนไลน์!

มันทำงานอย่างไร

ŒṖS€€ỊȦ$ÐfZ€µ⁺€Ȧ€€FS  Main link. Argument: M (matrix, array of rows)

ŒṖ                    Compute all partitions, i.e., all groupings of M's rows.
  S€€                 Map sum over all individual groupings, collapsing the grouped
                      rows into a single row.
        Ðf            Filter; keep only those partially collapsed matrices for
                      which the link to the left returns a truthy value.
       $                Group the two links to the left into a monadic chain.
     Ị                    Insignificant; map 0 and 1 to 1, greater integers to 0.
      Ȧ                   All; return 1 iff the matrix contains no zeroes.
          Z€          Zip/transpose all kept matrices,
            µ         Combine all links to the left into a monadic chain.
             ⁺€       Duplicate the chain and map it over the individual results
                      from the first call. We now have all possible combinations
                      of row and column groupings (represented by the corresponding
                      matrices of collapsed rows and columns) that do not have a
                      2 anywhere. However, they still may contain zeroes.
               Ȧ€€    Map the all atom over the matrices, returning 1 only for
                      matrices that consist entirely of ones.
                  FS  Flatten and sum, counting the number of valid divisions.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.