Write a program to draw a 2-D diagram of a knot based on the knot's structure. A knot is exactly what it sounds like: a loop of rope that's tied up. In mathematics, a knot diagram shows where a piece of rope crosses over or under itself to form the knot. Some example knot diagrams are shown below:
There's a break in the line where the rope crosses over itself.
Input: the input describing the knot is an array of integers. A knot where the rope crosses over itself n times can be represented as an array of n integers, each with a value in the range [0, n-1]. Let's call this array K.
To get the array describing a knot, number each of the segments 0 through n-1. Segment 0 should lead to segment 1, which should lead to segment 2, which should lead to segment 3, and so on until segment n-1 loops back and leads to segment 0. A segment ends when another segment of rope crosses over it (represented by a break in the line in the diagram). Let's take the simplest knot - the trefoil knot. After we've numbered the segmnents, segment 0 ends when segment 2 crosses over it; segment 1 ends when segment 0 crosses over it; and segment 2 ends when segment 1 crosses over it. Thus, the array describing the knot is [2, 0, 1]. In general, segment x starts where segment x-1 mod n left off, and ends where segment K[x] crosses over it.
The below image show knot diagrams, with labeled segments and the corresponding arrays that describe the knot.
The top three diagrams are true knots, while the bottom three are loops of rope that cross over themself but aren't actually knotted (but which still have corresponding codes).
Your task is to write a function which takes an array of integers K (you could call it something different) that describes a knot (or loop of rope that's not actually knotted), and which produces the corresponding knot diagram, as described in the above examples. If you can, provide an ungolfed version of your code or an explanation, and also provide sample outputs of your code. The same knot can often be represented in multiple different ways, but if the knot diagram your function outputs satisfies has the input as one of it's possible representations, your solution is valid.
This is code-golf, so shortest code in bytes wins. The line representing the rope can have a thickness of 1 pixel, however under and over-crossings must be clearly distinguishable (the size of the break in the rope should be greater than the thickness of the rope by at least a pixel on either side).
I will upvote answers that rely on built-in knot theory capabilities, but the one that's selected in the end can't rely on built-in knot theory capabilities.
Everything I know about my notation: I believe that there are sequences of values that don't seem to correspond to any knot or unknot. For example, the sequence [2, 3, 4, 0, 1] seems to be impossible to draw.
Aside from that, suppose that you take a crossing and, starting from that crossing, follow the path of the rope in one direction and label every unlabeled crossing that you come across with succesively greater integral values. For alternating knots, there is a simple algorithm to convert my notation into such a labeling, and for alternating knots it's trivial to convert this labeling into a Gauss Code:
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
in Mathematica... :'( \$\endgroup\$Knot
builtin! Example usage:<< Units`; Convert[Knot, Mile/Hour]
yields1.1507794480235425 Mile/Hour
. (I think this is funny regardless of whether it's true or false; but it's actually true.) \$\endgroup\$