Напишите программу для построения двумерной схемы узла на основе структуры узла. Узел - это то, на что он похож: связанная веревка. В математике диаграмма узла показывает, где кусок веревки пересекает или под собой, чтобы сформировать узел. Некоторые примеры диаграмм узлов показаны ниже:
Есть разрыв в линии, где веревка пересекает себя.
Входные данные: входные данные, описывающие узел, являются массивом целых чисел. Узел, где верёвка пересекает себя n раз, может быть представлен как массив из n целых чисел, каждое из которых имеет значение в диапазоне [0, n-1]. Назовем этот массив K .
Чтобы получить массив, описывающий узел, нумеруйте каждый из сегментов от 0 до n-1. Сегмент 0 должен вести к сегменту 1, который должен вести к сегменту 2, который должен вести к сегменту 3 и так далее, пока сегмент n-1 не возвращается назад и не ведет к сегменту 0. Сегмент заканчивается, когда другой сегмент веревки пересекает его ( представлен разрывом в линии на диаграмме). Давайте возьмем самый простой узел - узел трилистника. После нумерации сегментов сегмент 0 заканчивается, когда сегмент 2 пересекает его; сегмент 1 заканчивается, когда сегмент 0 пересекает его; и сегмент 2 заканчивается, когда сегмент 1 пересекает его. Таким образом, массивом, описывающим узел, является [2, 0, 1]. В общем, сегмент x начинается там, где сегмент x-1 mod n остановлен, и заканчивается там, где сегмент K [x] пересекает его.
На рисунке ниже показаны диаграммы узлов с помеченными сегментами и соответствующими массивами, которые описывают узел.
Верхние три диаграммы - это настоящие узлы, в то время как нижние три - это петли веревки, которые пересекают себя, но на самом деле не связаны (но у которых все еще есть соответствующие коды).
Ваша задача - написать функцию, которая принимает массив целых чисел K (вы могли бы назвать его чем-то другим), который описывает узел (или петлю веревки, которая на самом деле не завязана) и который создает соответствующую диаграмму узлов, как описано выше. Примеры. Если вы можете, предоставьте версию вашего кода или объяснение, а также предоставьте примеры выходных данных вашего кода. Один и тот же узел часто может быть представлен несколькими различными способами, но если диаграмма узла, которой удовлетворяет ваша функция, содержит вход в качестве одного из возможных представлений, ваше решение является действительным.
Это код-гольф, поэтому выигрывает самый короткий код в байтах. Линия, представляющая веревку, может иметь толщину 1 пиксель, однако нижние и перемычки должны быть четко различимы (размер разрыва в веревке должен быть больше толщины веревки как минимум на пиксель с любой стороны) ,
Я буду приветствовать ответы, которые полагаются на встроенные возможности теории узлов, но тот, который выбран в конце, не может полагаться на встроенные возможности теории узлов.
Все, что я знаю о своей нотации: я считаю, что есть последовательности значений, которые, кажется, не соответствуют ни одному узлу или узлу. Например, последовательность [2, 3, 4, 0, 1] кажется невозможной для рисования.
Кроме того, предположим, что вы берете пересечение и, начиная с этого пересечения, следуйте по пути веревки в одном направлении и маркируйте каждое непомеченное пересечение, с которым вы сталкиваетесь, последовательно большими интегральными значениями. Для чередующихся узлов существует простой алгоритм преобразования моих обозначений в такую маркировку, а для чередующихся узлов это тривиально преобразовать эту маркировку в код Гаусса:
template<size_t n> array<int, 2*n> LabelAlternatingKnot(array<int, n> end_at)
{
array<int, n> end_of;
for(int i=0;i<n;++i) end_of[end_at[i]] = i;
array<int, 2*n> p;
for(int& i : p) i = -1;
int unique = 0;
for(int i=0;i<n;i++)
{
if(p[2*i] < 0)
{
p[2*i] = unique;
p[2*end_of[i] + 1] = unique;
++unique;
}
if(p[2*i+1] < 0)
{
p[2*i+1] = unique;
p[2*end_at[i]] = unique;
++unique;
}
}
return p;
}
template<size_t n> auto GetGaussCode(array<int, n> end_at)
{
auto crossings = LabelAlternatingKnot(end_at);
for(int& i : crossings) ++i;
for(int i=1;i<2*n;i+=2) crossings[i] = -crossings[i];
return crossings;
}
KnotData
в Mathematica ...: '(
Knot
! Пример использования: << Units`; Convert[Knot, Mile/Hour]
доходность 1.1507794480235425 Mile/Hour
. (Я думаю, что это смешно, независимо от того, правда это или нет, но на самом деле это правда.)