Una situazione intricata


34

Data la notazione di Dowker di un nodo e i suoi segni di incrocio, calcola il suo polinomio di parentesi.

Sebbene ci siano più definizioni tecniche, per questa sfida è sufficiente pensare a un nodo come qualcosa fatto fisicamente attaccando le due estremità di una corda. Poiché i nodi esistono in tre dimensioni, quando li disegniamo su carta, usiamo diagrammi a nodo : proiezioni bidimensionali in cui gli incroci sono esattamente di due linee, una sopra e una sotto.

inserisci qui la descrizione dell'immagine

Qui (b) e (c) sono diversi diagrammi dello stesso nodo.

Come possiamo rappresentare un diagramma dei nodi su carta? Molti di noi non sono Rembrandt, quindi facciamo affidamento sulla notazione di Dowker , che funziona come segue:

Scegli un punto di partenza arbitrario sul nodo. Muoversi in una direzione arbitraria lungo il nodo e il numero degli incroci che si incontrano, a partire dal 1, con la seguente modifica: se si tratta di un numero ancora e si sta attualmente in corso sopra l'incrocio, annulla quel numero pari. Infine, scegli i numeri pari corrispondenti a 1, 3, 5, ecc.

Facciamo un esempio:

inserisci qui la descrizione dell'immagine

Su questo nodo, abbiamo scelto "1" come punto di partenza e abbiamo proceduto a spostarci verso l'alto e verso destra. Ogni volta che passiamo sopra o sotto un altro pezzo di corda, assegniamo al punto di incrocio il prossimo numero naturale. Annulliamo i numeri pari corrispondenti ai fili che attraversano un incrocio, ad esempio [3,-12]nel diagramma. Quindi, questo diagramma sarebbe rappresentato da [[1,6],[2,5],[3,-12],[-4,9],[7,8],[-10,11]]. Elencare gli amici di 1, 3, 5, 7, ecc [6,-12,2,8,-4,-10]. Ci dà .

Ci sono alcune cose da notare qui. Innanzitutto, la notazione di Dowker non è unica per un dato nodo, poiché possiamo scegliere un punto di partenza e una direzione arbitrari. Ma, data la notazione, si può determinare completamente la struttura del nodo (tecnicamente, fino alla riflessione dei suoi componenti del nodo principale). Sebbene non tutte le notazioni di Dowker possano formare possibili nodi, in questo problema si può presumere che l'input rappresenti un nodo reale.

Per evitare l'ambiguità tra le riflessioni di un nodo e per facilitare la risoluzione della sfida, ti verrà anche fornito un elenco di segni di attraversamento come input.

inserisci qui la descrizione dell'immagine

In un incrocio positivo la linea inferiore va a sinistra dal punto di vista della linea superiore. In un incrocio negativo va a destra. Si noti che invertire la direzione di andare attorno al nodo (ovvero invertire sia la linea sopra che la linea sotto ) non cambia i segni dell'incrocio. Nel nostro esempio i segni dell'incrocio sono [-1,-1,-1,1,-1,1]. Sono dati nello stesso ordine della notazione Dowker, ovvero per incroci numerati 1, 3, 5, 7, ecc.

In questa sfida calcoleremo il polinomio di parentesi di un nodo. È un oggetto invariante rispetto alla maggior parte delle trasformazioni del diagramma dei nodi, un concetto che lo rende estremamente utile nell'analisi della teoria dei nodi. (Ancora una volta, la maggior parte dei teorici del nodo calcolano il polinomio di parentesi come un prodotto intermedio nel loro cammino verso il calcolo del polinomio di Jones, che è invariante in tutte le trasformazioni, ma non lo faremo.) Come funziona? Il polinomio di parentesi è un polinomio di Laurent - uno in cui la variabile (tradizionalmente chiamata ) può essere elevata a poteri negativi, oltre che positivi.A

Per un dato diagramma dei nodi , le tre regole per il polinomio, rappresentate come , sono:D DD

inserisci qui la descrizione dell'immagine

  1. Un loop unico senza incroci ha il polinomio 1.

  2. Se abbiamo un diagramma costituito da e un loop disconnesso da , il polinomio per entrambi è il polinomio per volte .D D ( - A 2 - A - 2 )DDD(A2A2)

  3. Questa regola è la più complicata. Dice che se hai un incrocio in simile , puoi usare questa regola per semplificare i nodi in due modi diversi:Dinserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Nell'immagine sopra, l'attraversamento delineato nel primo diagramma, che è della forma inserisci qui la descrizione dell'immagine, può essere trasformato in inserisci qui la descrizione dell'immaginecome nella seconda figura (alias livellamento positivo ) o inserisci qui la descrizione dell'immaginecome nella terza figura ( livellamento negativo ).

Quindi, il polinomio di parentesi del primo diagramma è il polinomio di parentesi delle seconde volte più le terze volte , ovveroA - 1AA1

inserisci qui la descrizione dell'immagine

Ancora confuso? Facciamo un esempio, cercando di trovare il polinomio di parentesi di inserisci qui la descrizione dell'immagine(Nota: si tratta di due nodi collegati insieme. Questo tipo di diagramma non sarà un potenziale input in questa sfida poiché gli input saranno solo nodi singoli, ma potrebbe apparire come un nodo risultato intermedio nell'algoritmo.)

Per prima cosa usiamo la regola 3

inserisci qui la descrizione dell'immagine

Usiamo di nuovo la regola 3 su entrambi i nuovi nodi

inserisci qui la descrizione dell'immagine

Sostituiamo questi 4 nuovi nodi nella prima equazione.

inserisci qui la descrizione dell'immagine

L'applicazione delle regole 1 e 2 a questi 4 ci dice

inserisci qui la descrizione dell'immagine

Quindi, questo ci dice

inserisci qui la descrizione dell'immagine

Complimenti per aver completato la tua breve introduzione alla teoria dei nodi!

Ingresso

Due elenchi:

  • Notazione Dowker, ad es [6,-12,2,8,-4,-10]. La numerazione degli incroci deve iniziare da 1. I numeri dispari corrispondenti [1,3,5,7,...]sono impliciti e non devono essere forniti come input.

  • Segni ( 1/ -1o se si preferisce 0/ 1o false/ trueo '+'/ '-') per gli incroci corrispondenti alla notazione di Dowker, ad es [-1,-1,-1,1,-1,1].

Invece di una coppia di liste, potresti avere una lista di coppie, ad es [[6,-1],[-12,-1],...

Produzione

Stampa o restituisce il polinomio, ad esempio , come un elenco di coppie coefficiente-esponente (o coppia esponente-coefficiente) in ordine crescente degli esponenti e senza coefficienti zero, ad es .A2+5+AA3[[1,-2],[5,0],[1,1],[-1,3]]

In alternativa, genera un elenco di coefficienti di lunghezza dispari corrispondente agli esponenti per alcuni , ad es . L'elemento centrale è il termine costante (coefficiente prima di ). Gli elementi più a sinistra e più a destra non devono essere entrambi 0.k N A 0kkkN[0,1,0,5,1,0,-1]A0

Regole

Questa è una sfida di . Nessuna delle scappatoie standard può essere utilizzata e le librerie che dispongono di strumenti per calcolare le notazioni di Dowker o i polinomi di parentesi non possono essere utilizzate. (È ancora possibile utilizzare un linguaggio che contiene queste librerie, non solo le librerie / i pacchetti).

test

// 4-tuples of [dowker_notation, crossing_signs, expected_result, description]
[
 [[],[],[[1,0]],"unknot"],
 [[2],[1],[[-1,3]],"unknot with a half-twist (positive crossing)"],
 [[2],[-1],[[-1,-3]],"unknot with a half-twist (negative crossing)"],
 [[2,4],[1,1],[[1,6]],"unknot with two half-twists (positive crossings)"],
 [[4,6,2],[1,1,1],[[1,-7],[-1,-3],[-1,5]],"right-handed trefoil knot, 3_1"],
 [[4,6,2,8],[-1,1,-1,1],[[1,-8],[-1,-4],[1,0],[-1,4],[1,8]],"figure-eight knot, 4_1"],
 [[6,8,10,2,4],[-1,-1,-1,-1,-1],[[-1,-7],[-1,1],[1,5],[-1,9],[1,13]],"pentafoil knot, 5_1"],
 [[6,8,10,4,2],[-1,-1,-1,-1,-1],[[-1,-11],[1,-7],[-2,-3],[1,1],[-1,5],[1,9]],"three-twist knot, 5_2"],
 [[4,8,10,2,12,6],[1,1,-1,1,-1,-1],[[-1,-12],[2,-8],[-2,-4],[3,0],[-2,4],[2,8],[-1,12]],"6_3"],
 [[4,6,2,10,12,8],[-1,-1,-1,-1,-1,-1],[[1,-10],[2,-2],[-2,2],[1,6],[-2,10],[1,14]],"granny knot (sum of two identical trefoils)"],
 [[4,6,2,-10,-12,-8],[1,1,1,1,1,1],[[1,-14],[-2,-10],[1,-6],[-2,-2],[2,2],[1,10]],"square knot (sum of two mirrored trefoils)"],
 [[6,-12,2,8,-4,-10],[-1,-1,-1,1,-1,1],[[1,-2],[1,6],[-1,10]],"example knot"]
]

Risorse esterne

Non necessario per la sfida, ma se sei interessato:


messaggi sandbox: 1 , 2

grazie @ChasBrown e @ H.Pwiz per aver colto un errore nella mia definizione di notazione Dowker


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Mego

1
@ngn: molto meglio! Immaginavo che fosse quello che intendevo dire, ma è un po 'sciocco parlare in modo corretto. :)
Chas Brown,

Risposte:


10

K (ngn / k) , 196 193 byte

{!N::2*n:#x;{+/d,'x,'d:&:'-2!(|/n)-n:#:'x}(+/1-2*s){j::+,/y;,/(&0|2*x;(-1+#?{x[j]&:x@|j;x}/!N){-(d,x)+x,d:&4}/,1;&0|-2*x)}'(N!{(x,'|1+x;x+/:!2)}'((2*!n),'-1+x|-x)@'0 1=/:x>0)@'/:+~(y<0)=s:!n#2}

Provalo online!


12

Brain-Flak , 1316 byte

(({})<({()<(({}<>))><>}){(({})[()()]<{([{}]({})<>({}<>))}{}(([({}<>)]<<>({}<>)<>((({})<<>{({}<>)<>}<>>))>)){({}<>)<>}<>{}(({}<{}(({}<{({}<>)<>}>))>))<>{({}<>)<>}>)}<>>){(({}){}()<({}<>)>)<>{}(({}){}<>)<>}<>{}{}(()){(<({}<({}<>)>)>)<>((){[()](<(({})<>){({}[({})]<>({}<>))}{}({}<>({}<{}<>{({}<>)<>}>)[()])<>({}({})[()])(([()]{()(<({}[({})]())>)}{})<{(<{}{}>)}{}><>{()((<({}()[({}<>)])<>>))}{}<{}{}>)((){[()]<({}()<({}<({}<<>({()<({}<>)<>>}<>){({}[()]<(({})<({()<({}<>)<>>})<>>)<>{({}[()]<<>({}<>)>)}{}>)}<>>)<>>)>)((){[()](<{}(({})<<>(({})<(<<>({}<<>({}<(()()){({}[()]<([{}]()<>)<>({}<<>{({}({})<>[({}<>)])}{}{}>){({}<>)<>}<>>)}{}>{})>)>)<>{}{({}<>)<>}<>([({}<>)]<((()))>)(())<>({}<>)<>{}({}[()]){<>({}<<>(()()){({}[()]<({}<<>{({}<>)<>}>){({}[({})]<>({}<>))}{}(({})<<>({}<>)<>([{}])>)>)}{}{}>)<>({}<(({})())>[()]<>)}{}({}<<>{}([{}]()<{({}<>)<>}>){({}({})<>[({}<>)])}{}{}>){({}<>)<>}<>{}{}{}>{})>)>)}{}){(<{}(({})<<>(({}{})<<>(<({}<>)>)<>{}{({}<>)<>}<>>(({}){}){})>)>)}>}{}){(<{}([{}]<({}<<>([{}]()<>)<>({}<<>{({}({})<>[({}<>)])}{}{}>){({}<>)<>}<>>({})({}){})>)>)}{}>)}{}){{}(([{}]){}<>{}{}<<>({}<>{}){([{}]({}()()<{}({}<>)(())<>>))}{}{}{}>{})(())<>{{}({}<>)(())<>}(<>)<>}{}}{}{}<>{}{}({}<{{}({}<>)(())<>}<>{{}{((<(())>))}{}}{}{{}({}<>)(())<>}>)<>{{}({}<(<()>)<>([]){{}({}<>)(())<>([])}{}>)<>{{}({}<>)<>}{}{}({}<>)<>}<>

Provalo online!

Non mi pento di nulla. L'input è un elenco appiattito di coppie.

# Part 1: extract edges
(({})<

({()<(({}<>))><>}){

(({})[()()]<

{([{}]({})<>({}<>))}{}(([({}<>)]<<>({}<>)<>((({})<<>{({}<>)<>}<>>))>)){({}<>)<>}

<>{}(({}<{}(({}<{({}<>)<>}>))>))<>{({}<>)<>}

>)}

<>>){(({}){}()<({}<>)>)<>{}(({}){}<>)<>}<>

{}{}(())

# Part 2: Compute bracket polynomial
{

  # Move degree/sign to other stack
  (<({}<({}<>)>)>)<>

  # If current shape has crossings:
  ((){[()](<

    # Consider first currently listed edge in set
    # Find the other edge leaving same crossing
    (({})<>){({}[({})]<>({}<>))}{}

    # Move to top of other stack
    # Also check for twist
    ({}<>({}<{}<>{({}<>)<>}>)[()])

    # Check for twist in current edge
    <>({}({})[()])

    (

      # Remove current edge if twist
      ([()]{()(<({}[({})]())>)}{})<{(<{}{}>)}{}>

      # Remove matching edge if twist
      <>{()((<({}()[({}<>)])<>>))}{}<{}{}>

    # Push 1 minus number of twists from current vertex.
    )

    # If number of twists is not 1:
    ((){[()]<

      # While testing whether number of twists is 2:
      ({}()<

        # Keep sign/degree on third stack:
        ({}<({}<

          # Duplicate current configuration
          <>({()<({}<>)<>>}<>){({}[()]<(({})<({()<({}<>)<>>})<>>)<>{({}[()]<<>({}<>)>)}{}>)}

        # Push sign and degree on separate stacks
        <>>)<>>)

      # If number of twists is not 2: (i.e., no twists)
      >)((){[()](<{}

        # Make first copy of sign/degree
        (({})<<>(({})<

          # Make second copy of sign/degree
          (<<>({}<<>({}<

            # Do twice:
            (()()){({}[()]<

              # Prepare search for vertex leading into crossing on other side
              ([{}]()<>)

              # While keeping destination on third stack:
              <>({}<

                # Search for matching edge
                <>{({}({})<>[({}<>)])}{}

              # Replace old destination
              {}>)

              # Move back to original stack
              {({}<>)<>}<>

            >)}{}

          # Add orientation to degree
          >{})>)>)

          # Move duplicate to left stack
          <>{}{({}<>)<>}<>

          # Create "fake" edges from current crossing as termination conditions
          ([({}<>)]<((()))>)(())<>

          # Create representation of "top" new edge
          ({}<>)<>{}({}[()])

          # While didn't reach initial crossing again:
          {

            # Keep destination of new edge on third stack
            <>({}<<>

              # Do twice:
              (()()){({}[()]<

                # Search for crossing
                ({}<<>{({}<>)<>}>){({}[({})]<>({}<>))}{}

                # Reverse orientation of crossing
                (({})<<>({}<>)<>([{}])>)

              >)}{}

              # Remove extraneous search term
              {}

            # Push new destination for edge
            >)

            # Set up next edge
            <>({}<(({})())>[()]<>)

          }

          # Get destination of last edge to link up
          {}({}<

            # Find edge headed toward original crossing
            <>{}([{}]()<{({}<>)<>}>){({}({})<>[({}<>)])}

          # Replace destination
          {}{}>)

          # Move everything to left stack
          {({}<>)<>}

          # Clean up temporary data
          <>{}{}{}

        # Push new sign/degree of negatively smoothed knot
        >{})>)

      # Else (two twists)
      # i.e., crossing is the twist in unknot with one half-twist
      >)}{}){(<{}

        # Copy sign and degree+orientation
        (({})<<>(({}{})<

          # Move sign to left stack
          <>(<({}<>)>)

          # Move copy of configuration to left stack
          <>{}{({}<>)<>}

        # Add an additional 4*orientation to degree
        <>>(({}){}){})>)

      >)}

    # Else (one twist)
    >}{}){(<

      # Invert sign and get degree
      {}([{}]<({}<

        # Search term for other edge leading to this crossing
        <>([{}]()<>)

        # With destination on third stack:
        <>({}<

          # Find matching edge
          <>{({}({})<>[({}<>)])}{}

        # Replace destination
        {}>)

        # Move stuff back to left stack
        {({}<>)<>}<>

      # Add 3*orientation to degree
      >({})({}){})>)

    >)}{}

  # Else (no crossings)
  >)}{}){{}

    # If this came from the 2-twist case, undo splitting.
    # If this came from an initial empty input, use implicit zeros to not join anything
    # New sign = sign - 2 * next entry sign
    (([{}]){}<>{}{}<

      # New degree = average of both degrees
      <>({}<>{})

      # Find coefficient corresponding to degree
      {([{}]({}()()<{}({}<>)(())<>>))}{}{}

    # Add sign to coefficient
    {}>{})

    # Move rest of polynomial back to right stack
    (())<>{{}({}<>)(())<>}

    # Set up next configuration
    (<>)<>

  }{}

}{}{}<>{}

# Step 3: Put polynomial in correct form

# Keeping constant term:
{}({}<

  # Move to other stack to get access to terms of highest absolute degree
  {{}({}<>)(())<>}<>

  # Remove outer zeros
  {{}{((<(())>))}{}}

  # Move back to right stack to get access to lower order terms
  {}{{}({}<>)(())<>}

>)<>

# While terms remain:
{

  # Move term with positive coefficient
  {}({}<(<()>)<>([]){{}({}<>)(())<>([])}{}>)<>{{}({}<>)<>}{}

  # Move term with negative coefficient
  {}({}<>)<>

}<>

Whoaaaaaa. Fantastico!!!! +1
Don Migliaia

Mi sento come se avessi bisogno di distribuire un'altra taglia
Don Thousand
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.