Python 3, 457 316 306 bytes
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')
Hã?
O programa primeiro converte o nó em um diagrama retangular, com as seguintes restrições:
- Não existem dois segmentos verticais ou horizontais na mesma linha.
- Nenhum segmento vertical cruza um segmento horizontal.
Por exemplo, o primeiro caso de teste é convertido no seguinte diagrama retangular:
+-----------+
| |
| | +-------+
| | | |
| +-------+ | | |
| | | | | |
| | +---+ | |
| | | | | |
| | | +---+ |
| | | |
| | | +-------+
| | | | | |
+-----+ | | | |
| | | | | |
| +---+ | | |
| | | | | |
| | +-------------+ | |
| | | | | |
| | | +---+ |
| | | | | |
| | | | +---+
| | | |
+-+ | |
| |
+-+
que representamos exclusivamente pela sequência de coordenadas y dos segmentos verticais, da direita para a esquerda:
(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)
Em seguida, procura simplificações do diagrama retangular, como descrito em Ivan Dynnikov, “Apresentações em arco de links. Simplificação monotônica ”, 2004 . Dynnikov provou que, a partir de qualquer diagrama retangular do nó, existe uma sequência de movimentos simplificadores que termina no diagrama trivial. Resumidamente, os movimentos permitidos incluem:
- Permutando ciclicamente os segmentos verticais (ou horizontais);
- Trocar segmentos verticais (ou horizontais) consecutivos sob certas restrições de configuração.
- Substituindo três vértices adjacentes que ficam no canto do diagrama por um vértice.
Veja o jornal para fotos. Este não é um teorema óbvio; não é válido se, digamos, movimentos de Reidemeister que não aumentam o número de cruzamentos forem usados. Mas para os tipos específicos de simplificações acima, isso é verdade.
(Simplificamos a implementação permitindo apenas segmentos verticais, mas também permitindo que todo o nó seja transposto para trocar horizontal com vertical.)
Demo
$ 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