Вузлова ситуація


35

Враховуючи позначення Даукера про вузол та його знаки перетину, обчисліть його многочлен дужок.

Хоча існує більше технічних визначень, для цього виклику достатньо думати про вузол як про щось, зроблене фізично, з'єднавши два кінці рядка разом. Оскільки вузли існують у трьох вимірах, коли ми малюємо їх на папері, ми використовуємо діаграми вузлів - двовимірні проекції, в яких перехрестя має рівно дві лінії, одна над і одна під.

введіть тут опис зображення

Тут (b) і (c) - різні діаграми одного вузла.

Як ми представляємо вузольну діаграму на папері? Більшість із нас не є Рембрандтом, тому ми покладаємось на нотацію Даукера , яка працює так:

Виберіть на вузолі довільну вихідну точку. Перемістіть у довільному напрямку уздовж вузла та пронумеруйте перетинання, з яким ви стикаєтесь, починаючи з 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

Для даного вузла діаграми , три правила для полінома представлені в вигляді , є:D DD

введіть тут опис зображення

  1. Петля підошви без будь-яких перетинів має многочлен 1.

  2. Якщо у нас є діаграма, що складається з і петлі, від'єднаної від , многочлен для обох є многочленом для разів .D D ( - A 2 - A - 2 )DDD(A2A2)

  3. Це правило є найскладнішим. У ньому йдеться про те, що якщо у вас є схрещування в , схоже , ви можете використовувати це правило для спрощення вузлів двома різними способами:Dвведіть тут опис зображення

введіть тут опис зображення

На зображенні, викладеному вище, перекреслене на першій схемі, яке має форму введіть тут опис зображення, може бути перетворене введіть тут опис зображенняяк у другій фігурі (також позитивне згладжування ), або введіть тут опис зображенняяк у третій рисунок ( негативне згладжування ).

Отже, дужок многочлен першої діаграми є дужним многочленом другого разу плюс третього разу , тобтоА - 1AA1

введіть тут опис зображення

Плутати ще? Давайте зробимо приклад, намагаючись знайти дужок полінома введіть тут опис зображення(Примітка. Це два вузли, зв'язані між собою. Така діаграма не буде потенційним вкладом у цю задачу, оскільки входи будуть лише окремими вузлами, але можуть виглядати як проміжний результат в алгоритмі.)

Спочатку використовуємо правило 3

введіть тут опис зображення

Ми знову використовуємо правило 3 для обох нових вузлів

введіть тут опис зображення

Ці 4 нові вузли підміняємо в перше рівняння.

введіть тут опис зображення

Застосовуючи правила 1 і 2 до цих 4, повідомте нам

введіть тут опис зображення

Отже, це нам кажуть

введіть тут опис зображення

З повагою до завершення вашого короткого вступу до теорії вузлів!

Вхідні дані

Два списки:

  • Позначення Даукера, наприклад [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]]

Крім того, виведіть список непарної довжини коефіцієнтів, що відповідають показникам для деяких , напр . Центральним елементом є постійний член (коефіцієнт до ). Крайній лівий і правий елементи не повинні бути обома 0.k N A 0kkkN[0,1,0,5,1,0,-1]A0

Правила

Це проблема з . Жодна зі стандартних прорізів не може бути використана, і бібліотеки, які мають інструменти для обчислення або нотацій Даукера, або поліномів дужок, не можуть бути використані. (Мова, яка містить ці бібліотеки, все ще може використовуватися, тільки не бібліотеки / пакети).

Тести

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

Зовнішні ресурси

Не потрібно для виклику, але якщо ви зацікавлені:


пости пісочниці: 1 , 2

дякую @ChasBrown та @ H.Pwiz за те, що помилилися у моєму визначенні позначення Даукера


Коментарі не для розширеного обговорення; ця розмова переміщена до чату .
Mego

1
@ngn: Набагато краще! Я здогадувався, що це малося на увазі, але це тріскання язика, щоб правильно висловитись. :)
Час Браун

Відповіді:



12

Мозг-Флак , 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
  {}({}<>)<>

}<>

Whoaaaaaa. Фантастичний !!!! +1
Дон Тисяча

Я відчуваю, що мені потрібно вручити ще одну щедрість
Дон тисячі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.