節のある状況


35

結び目のダウカー表記法とその交差記号を与え、そのブラケット多項式を計算します。

より多くの技術的な定義がありますが、この課題に対しては、結び目を、文字列の両端を結び付けて物理的に作られたものと考えるだけで十分です。ノットは3次元で存在するため、紙にノットダイアグラムを描画するときは、ノットダイアグラムを使用します。2次元投影では、交差が正確に2本の線で構成されます。

ここに画像の説明を入力してください

ここで(b)と(c)は同じ結び目の異なる図です。

紙に結び目図をどのように表現しますか?私たちのほとんどはレンブラントではないので、次のように機能するDowker表記法に依存しています。

結び目の任意の開始点を選択します。結び目に沿って任意の方向に移動し、遭遇した交差点に番号を付けます。1から始まり、次の変更を加えます。偶数で、現在交差点を超えている場合は、その偶数を無効にします。最後に、1、3、5などに対応する偶数を選択します。

例を試してみましょう:

ここに画像の説明を入力してください

この結び目で、開始点として「1」を選択し、右上に移動しました。ロープの別の部分のまたはを通るたびに、交差点に次の自然数を割り当てます。たとえば[3,-12]図のように、交差を越える鎖に対応する偶数を無効にします。したがって、この図はで表され[[1,6],[2,5],[3,-12],[-4,9],[7,8],[-10,11]]ます。1、3、5、7などの仲間をリストすると、が得られ[6,-12,2,8,-4,-10]ます。

ここで注意すべきことがいくつかあります。まず、Dowker表記は、任意の開始点と方向を選択できるため、特定のノットに対して一意ではありません。しかし、表記法を考えると、結び目の構造を完全に決定することができます(技術的には、その主要な結び目コンポーネントの反映まで)。すべてのダウカー表記法がノットを形成できるわけではありませんが、この問題では、入力が実際のノットを表すと仮定できます。

結び目の反射のあいまいさを回避し、課題を解決しやすくするために、交差記号のリストも入力として提供されます。

ここに画像の説明を入力してください

正の交差では、下の線は上の線の視点から左に進みます。負の交差点では、右に進みます。(つまり、両方の逆転結び目の周りに行くの向きを反転させることに注意のラインとのラインは)交差記号を変更しません。この例では、交差記号は[-1,-1,-1,1,-1,1]です。それらは、ダウカー記法と同じ順序で、つまり1、3、5、7などの番号が付けられた交差点で与えられます。

A

DD

ここに画像の説明を入力してください

  1. 交差のない唯一のループの多項式は1です。

  2. 構成される図がある場合DDDA2A2

  3. Dここに画像の説明を入力してください

ここに画像の説明を入力してください

上記の画像では、最初の図のアウトラインの交差はの形式であり、2番目の図(正の平滑化)または3番目の図(負の平滑化)のここに画像の説明を入力してくださいように変換できます。ここに画像の説明を入力してくださいここに画像の説明を入力してください

AA1

ここに画像の説明を入力してください

まだ混乱していますか?のブラケット多項式を見つけようとする例を見てみましょうここに画像の説明を入力してください(注:これは相互にリンクされた2つのノットです。この種の図は、入力が単一のノットのみであるため、このチャレンジの潜在的な入力ではありませんが、アルゴリズムの中間結果。)

最初にルール3を使用します

ここに画像の説明を入力してください

新しいノットの両方で再びルール3を使用します

ここに画像の説明を入力してください

これらの4つの新しいノットを最初の方程式に代入します。

ここに画像の説明を入力してください

これら4にルール1と2を適用すると、

ここに画像の説明を入力してください

だから、これは私たちに教えて

ここに画像の説明を入力してください

結び目理論の簡単な紹介を完了しました!

入力

2つのリスト:

  • ダッカー記法、例えば[6,-12,2,8,-4,-10]。交差点の番号は1から開始する必要があります。対応する奇数[1,3,5,7,...]は暗黙的であり、入力として提供しないでください。

  • ダウカー記法に対応する交差点の標識(1/ -1または0/ 1またはfalse/ trueまたは'+'/ を好む場合'-'[-1,-1,-1,1,-1,1]

リストのペアの代わりに、ペアのリストを持つことができます。例えば [[6,-1],[-12,-1],...

出力

A2+5+AA3[[1,-2],[5,0],[1,1],[-1,3]]

あるいは、指数対応する係数の奇数長リストを出力しますkkkN[0,1,0,5,1,0,-1]A0

ルール

これは挑戦です。標準の抜け穴は使用できず、Dowker表記またはブラケット多項式を計算するツールを備えたライブラリは使用できません。(ライブラリ/パッケージではなく、これらのライブラリを含む言語を引き続き使用できます)。

テスト

// 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"]
]

外部リソース

チャレンジには必要ありませんが、興味がある場合:


サンドボックスの投稿: 12

Dowker表記法の定義の間違いを見つけてくれて、@ ChasBrownと@ H.Pwizに感謝します。


コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
メゴ

1
@ngn:はるかに良い!私はそれが何を意味するのかと推測していましたが、適切に表現するのはちょっと難しいです。:)
チャスブラウン

回答:



12

Brain-Flak、1316バイト

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

オンラインでお試しください!

私は何も後悔していない。入力は、フラット化されたペアのリストです。

# 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
  {}({}<>)<>

}<>

おっと。素晴らしい!!!! +1
ドンサウザンド

別の報奨金を渡す必要があるように感じます
ドンサウザンド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.