“KNOT”또는“NOT”?


144

얽힌 문자열의 ASCII 아트 표현을 처리하고 간단한 루프로 풀 수 있는지 여부를 결정하는 프로그램을 작성하십시오. 엉킴이 문자를 사용하여 표현 -하고 |, 수평 및 수직 세그먼트를 나타 내기 위해 한 +모서리를 나타내는. 현이 지나가는 장소는 다음과 같이 표현됩니다.

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

줄의 끝은 서로 연결되어 있습니다. 느슨한 끝이 없습니다.

프로그램이 문자열을 간단한 루프로 풀 수 없다고 결정하면 단어를 출력해야합니다 KNOT. 그렇지 않으면 단어를 출력해야합니다 NOT.

이것은 도전이므로 소스 코드의 바이트 단위로 측정 된 가장 짧은 유효한 답변이 이길 것입니다.

제한

ASCII 입력은 최대 25 줄의 80 자로 구성됩니다. 모든 줄이 같은 길이의 공백으로 채워져 있다고 가정 할 수 있습니다.

입력:

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

산출:

KNOT

입력:

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

산출:

NOT

참고 문헌


36
+1 좋은 질문입니다. 사람들이 그 매듭 이론에 뛰어 들도록 격려하기 위해 이것에 현상금을 주려고 유혹했습니다.
디지털 외상

2
우리는 그것이 매듭 (아마도 멍청이)이거나 또는> 1 연결된 컴포넌트의 링크 일 수 있다고 가정 할 수 있습니까?
msh210

@ msh210 예, 당신은 그것이 하나의 매듭이라고 가정 할 수 있습니다 :-)
squeamish ossifrage

답변:


94

파이썬 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


3
ungolfed 코드를 게시 할 수 있습니까?
J. Antonio Perez

또한 프로그램의 시간 복잡성은 무엇입니까?
J. Antonio Perez

3
@JorgePerez 별도의 ungolfed 버전이 없습니다. 프로그램을 이해하는 가장 좋은 방법은 내가 연결 한 Dynnikov의 논문을 읽는 것입니다. 복잡성은 엄청나게 지수입니다. 내가 아는 한, 다항식 시간 알고리즘이 존재하는지 여부는 여전히 미해결 문제입니다.
Anders Kaseorg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.