“ KNOT” หรือ“ ไม่”?


144

เขียนโปรแกรมที่ประมวลผลการแทนค่า ASCII art ของสตริงที่มีการพันกันและตัดสินใจว่าจะไม่ถูกรวมเข้าไปในลูปแบบง่ายได้หรือไม่ ยุ่งเหยิงจะถูกแสดงโดยใช้ตัวอักษร-และ|เพื่อเป็นตัวแทนของส่วนแนวนอนและแนวตั้งและ+เพื่อเป็นตัวแทนมุม สถานที่ที่สตริงผ่านตัวเองจะถูกแสดงดังนี้:

            |                           |   
         -------                     ---|---
            |                           |   
(Horizontal segment on top)   (Vertical segment on top)

ปลายของสายเชื่อมต่อกัน ไม่มีจุดจบหลวม

KNOTถ้าโปรแกรมของคุณตัดสินใจว่าสตริงไม่สามารถแกะเป็นห่วงง่ายๆก็ควรเอาท์พุทคำว่า มิฉะนั้นควรส่งคำNOTออก

นี่เป็นความท้าทายของดังนั้นคำตอบที่สั้นที่สุดที่ถูกต้อง (วัดเป็นไบต์ของซอร์สโค้ด) จะเป็นผู้ชนะ

ขีด จำกัด

อินพุต ASCII จะประกอบด้วยความยาวสูงสุด 80 บรรทัดซึ่งประกอบด้วยอักขระ 80 ตัว คุณอาจสันนิษฐานว่าเส้นทุกเส้นมีช่องว่างที่มีความยาวเท่ากัน

ตัวอย่าง

การป้อนข้อมูล:

+-------+    +-------+    
|       |    |       |    
|   +---|----+   +-------+
|   |   |        |   |   |
+-------|------------|---+
    |   |        |   |    
    +---+        +---+    

เอาท์พุท:

KNOT

การป้อนข้อมูล:

+----------+         
|          |         
|    +--------------+
|    |     |        |
|    |   +-|----+   |
|    |   | |    |   |
|    +-----+    |   |
|        |      |   |
|        +------|---+
|               |    
+---------------+    

เอาท์พุท:

NOT

อ้างอิง


36
+1 คำถามที่ยอดเยี่ยม ล่อลวงให้รับรางวัลนี้เพื่อส่งเสริมให้ผู้คนกระโดดเข้าสู่ทฤษฎีปมนั้น
บาดเจ็บทางดิจิตอล

2
เราคิดว่ามันเป็นปม (อาจจะเป็น unknot) หรือเป็นลิงค์ของส่วนประกอบที่เชื่อมต่อ> 1 ได้หรือไม่?
msh210

@ msh210 ใช่คุณสามารถสันนิษฐานได้ว่ามันเป็นปม :-) เดียว
ossifrage คลื่นไส้

คำตอบ:


94

Python 3, 457 316 306 ไบต์

E=enumerate
V={'+'}
Q=[[(-j,i,k)for i,u in E(open(0))for j,v in E(u)for k in[{v}&V,'join'][u[j:j+2]=='|-']]]
while Q:
 a,b,c,d,*e=A=tuple(x//2for y,x in sorted((y,x)for x,y in E(Q.pop())));e or exit('NOT')
 if{A}-V:V|={A};Q+=[[c,d,a,b]+e,A,A[2:]+A[:2]][a<c<b<d:][c<a<d<b:]
 if b==d:Q=[[a,c]+e]
exit('KNOT')

ฮะ?

โปรแกรมจะแปลงปมเป็นไดอะแกรมสี่เหลี่ยมก่อนซึ่งมีข้อ จำกัด ดังต่อไปนี้:

  1. ไม่มีเซ็กเมนต์แนวตั้งหรือแนวนอนสองอันวางอยู่บนบรรทัดเดียวกัน
  2. ไม่มีส่วนแนวตั้งข้ามข้ามส่วนแนวนอน

ตัวอย่างเช่นกรณีทดสอบครั้งแรกจะถูกแปลงเป็นแผนภาพสี่เหลี่ยมต่อไปนี้:

+-----------+            
|           |            
|           | +-------+  
|           | |       |  
| +-------+ | |       |  
| |       | | |       |  
| |     +---+ |       |  
| |     | |   |       |  
| |     | +---+       |  
| |     |             |  
| |     |       +-------+
| |     |       |     | |
+-----+ |       |     | |
  |   | |       |     | |
  | +---+       |     | |
  | | |         |     | |
  | | +-------------+ | |
  | |           |   | | |
  | |           | +---+ |
  | |           | | |   |
  | |           | | +---+
  | |           | |      
  +-+           | |      
                | |      
                +-+      

ซึ่งเรานำเสนอโดยไม่ซ้ำกันโดยลำดับของพิกัด y ของส่วนแนวตั้งจากขวาไปซ้าย:

(5,10, 1,9, 8,10, 9,12, 5,12, 1,4, 0,3, 2,4, 3,7, 6,8, 7,11, 2,11, 0,6)

จากนั้นค้นหาความเรียบง่ายของแผนภาพสี่เหลี่ยมตามที่อธิบายไว้ในIvan Dynnikov“ การนำเสนอส่วนโค้งของลิงก์ ทำให้เข้าใจง่ายต่อเนื่อง” 2004 Dynnikov พิสูจน์ว่าจากแผนภาพสี่เหลี่ยมใด ๆ ของ unknot มีลำดับของการลดความซับซ้อนของการเคลื่อนไหวที่สิ้นสุดที่แผนภาพเล็กน้อย สั้น ๆ การเคลื่อนไหวที่อนุญาตรวมถึง:

  1. อนุญาตให้เซกเมนต์ตามแนวตั้ง (หรือแนวนอน) เป็นวงกลม
  2. การสลับกลุ่มในแนวตั้ง (หรือแนวนอน) ติดต่อกันภายใต้ข้อ จำกัด การกำหนดค่าบางอย่าง
  3. แทนที่จุดยอดที่อยู่ติดกันสามจุดที่อยู่ในมุมของแผนภาพด้วยจุดสุดยอดเดียว

ดูกระดาษสำหรับรูปภาพ นี่ไม่ใช่ทฤษฎีบทที่ชัดเจน มันไม่ถือถ้าพูดว่า Reidemeister ย้ายที่ไม่เพิ่มจำนวนของการข้ามถูกนำมาใช้แทน แต่สำหรับการทำให้เข้าใจง่ายบางประเภทด้านบนมันกลายเป็นจริง

(เราลดความซับซ้อนของการใช้งานโดยอนุญาตให้เฉพาะส่วนแนวตั้งเท่านั้น

การสาธิต

$ python3 knot.py <<EOF
+-------+    +-------+    
|       |    |       |    
|   +---|----+   +-------+
|   |   |        |   |   |
+-------|------------|---+
    |   |        |   |    
    +---+        +---+    
EOF
KNOT
$ python3 knot.py <<EOF
+----------+         
|          |         
|    +--------------+
|    |     |        |
|    |   +-|----+   |
|    |   | |    |   |
|    +-----+    |   |
|        |      |   |
|        +------|---+
|               |    
+---------------+    
EOF
NOT
$ python3 knot.py <<EOF  # the Culprit
        +-----+  
        |     |  
+-----------+ |  
|       |   | |  
|   +-+ | +---|-+
|   | | | | | | |
| +-|-------+ | |
| | | | | |   | |
+-|-+ | | +---+ |
  |   | |       |
  +---|---------+
      | |        
      +-+        
EOF
NOT
$ python3 knot.py <<EOF  # Ochiai unknot
    +-----+    
    |     |    
  +-|---------+
  | |     |   |
  | | +-+ |   |
  | | | | |   |
+-|-|---|-|-+ |
| | | | | | | |
| | | +---|---+
| | |   | | |  
+-------+ | |  
  | |     | |  
  | +-------+  
  |       |    
  +-------+    
EOF
NOT
$ python3 knot.py <<EOF  # Ochiai unknot plus trefoil
    +-----+ +-----+
    |     | |     |
  +-|---------+   |
  | |     | | |   |
  | | +-+ | +---+ |
  | | | | |   | | |
+-|-|---|-|-+ +---+
| | | | | | |   |  
| | | +---|-----+  
| | |   | | |      
+-------+ | |      
  | |     | |      
  | +-------+      
  |       |        
  +-------+        
EOF
KNOT
$ python3 knot.py <<EOF  # Thistlethwaite unknot
      +---------+        
      |         |        
    +---+ +---------+    
    | | | |     |   |    
    | +-------+ |   |    
    |   | |   | |   |    
    |   | | +---+   |    
    |   | | | |     |    
    |   | +-------+ |    
    |   |   | |   | |    
    |   +-------+ | |    
    |       | | | | |    
+-----------+ | | | |    
|   |         | | | |    
| +-----------+ | | |    
| | |           | | |    
| | +-------------+ |    
| |             |   |    
| |             +-----+  
| |                 | |  
| |                 +---+
| |                   | |
+---------------------+ |
  |                     |
  +---------------------+
EOF
NOT
$ python3 knot.py <<EOF  # (−3,5,7)-pretzel knot
      +-------------+
      |             |
    +-|-----+       |
    | |     |       |
  +-|-+   +-------+ |
  | |     | |     | |
+-|-+   +---+   +---+
| |     | |     | |  
| |   +---+   +---+  
| |   | |     | |    
| | +---+   +---+    
| | | |     | |      
| +---+   +---+      
|   |     | |        
|   |   +---+        
|   |   | |          
|   | +---+          
|   | | |            
|   +---+            
|     |              
+-----+              
EOF
KNOT
$ python3 knot.py <<EOF  # Gordian unknot
+-------------+                 +-------------+
|             |                 |             |
| +---------+ |                 | +---------+ |
| |         | |                 | |         | |
| | +-------------+         +-------------+ | |
| | |       | |   |         |   | |       | | |
| | | +---------+ |         | +---------+ | | |
| | | |     | | | |         | | | |     | | | |
| +-------+ | +-------+ +-------+ | +-------+ |
|   | |   | |   | |   | |   | |   | |   | |   |
+-------+ | +-------+ | | +-------+ | +-------+
    | | | |     | | | | | | | |     | | | |    
    | +-------+ | | | | | | | | +-------+ |    
    |   | |   | | | | | | | | | |   | |   |    
    +-------+ | | | | | | | | | | +-------+    
        | | | | | | | | | | | | | | | |        
        | +-----+ | | | | | | +-----+ |        
        |   | |   | | | | | |   | |   |        
        +---------+ | | | | +---------+        
            | |     | | | |     | |            
          +---------+ | | +---------+          
          | | |       | |       | | |          
          | | +-----------------+ | |          
          | |         | |         | |          
          | +---------------------+ |          
          |           | |           |          
          +-----------+ +-----------+          
EOF
NOT

ว้าวนี่ยอดเยี่ยมมาก
ossifrage คลื่นไส้

3
คุณช่วยโพสต์โค้ดที่ไม่มีเวอร์ชันของคุณได้ไหม?
J. Antonio Perez

นอกจากนี้ความซับซ้อนของเวลาในโปรแกรมของคุณคืออะไร?
J. Antonio Perez

3
@ JorgePerez ฉันไม่มีเวอร์ชั่นที่แยกกันไม่ได้ วิธีที่ดีที่สุดในการทำความเข้าใจโปรแกรมคือการอ่านกระดาษของ Dynnikov ที่ฉันเชื่อมโยง ความซับซ้อนเป็นสิ่งที่อธิบายอย่างน่ากลัว; เท่าที่ฉันรู้ไม่ว่าอัลกอริทึมเวลาพหุนามมีอยู่ยังคงเป็นปัญหาที่เปิดอยู่หรือไม่
Anders Kaseorg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.