Schreiben Sie ein Programm, um ein 2-D-Diagramm eines Knotens auf der Grundlage der Knotenstruktur zu zeichnen. Ein Knoten ist genau das, wonach es sich anhört: eine Seilschleife, die festgebunden ist. In der Mathematik zeigt ein Knotendiagramm, wo sich ein Stück Seil über oder unter sich kreuzt, um den Knoten zu bilden. Einige beispielhafte Knotendiagramme sind unten dargestellt:
Es gibt einen Bruch in der Linie, in der sich das Seil kreuzt.
Eingabe: Die Eingabe, die den Knoten beschreibt, ist ein Array von ganzen Zahlen. Ein Knoten, bei dem sich das Seil n- mal kreuzt, kann als Array von n ganzen Zahlen mit einem Wert im Bereich [0, n-1] dargestellt werden. Lassen Sie uns dieses Array nennen K .
Um das Array zu erhalten, das einen Knoten beschreibt, nummerieren Sie jedes der Segmente 0 bis n-1. Segment 0 sollte zu Segment 1 führen, was zu Segment 2 führen sollte, was zu Segment 3 führen sollte, und so weiter, bis sich Segment n-1 zurückzieht und zu Segment 0 führt. Ein Segment endet, wenn ein anderes Seilsegment darüber läuft ( durch einen Zeilenumbruch im Diagramm dargestellt). Nehmen wir den einfachsten Knoten - den Kleeblattknoten. Nachdem wir die Segmente nummeriert haben, endet Segment 0, wenn Segment 2 darüber läuft. Segment 1 endet, wenn Segment 0 darüber läuft. und Segment 2 endet, wenn Segment 1 es überquert. Somit ist das Array, das den Knoten beschreibt, [2, 0, 1]. Im allgemeinen Segment x beginnt , wo Segment x-1 mod n aufhörte und endet in dem Segment K [x] kreuzt es.
Das folgende Bild zeigt Knotendiagramme mit beschrifteten Segmenten und den entsprechenden Arrays, die den Knoten beschreiben.
Die oberen drei Diagramme sind echte Knoten, während die unteren drei Seilschlaufen sind, die sich selbst kreuzen, aber nicht wirklich geknüpft sind (aber immer noch entsprechende Codes haben).
Ihre Aufgabe ist es, eine Funktion zu schreiben, die ein Array von ganzen Zahlen K (man könnte es auch anders nennen) verwendet, die einen Knoten (oder eine Seilschleife, die nicht wirklich geknüpft ist) beschreibt und das entsprechende Knotendiagramm wie oben beschrieben erzeugt Beispiele. Wenn Sie können, geben Sie eine unbenutzte Version Ihres Codes oder eine Erklärung an und stellen Sie auch Beispielausgaben Ihres Codes bereit. Derselbe Knoten kann häufig auf mehrere verschiedene Arten dargestellt werden. Wenn jedoch das Knotendiagramm, das Ihre Funktionsausgaben erfüllen, die Eingabe als eine der möglichen Darstellungen enthält, ist Ihre Lösung gültig.
Das ist Code-Golf, also gewinnt der kürzeste Code in Bytes. Die Linie, die das Seil darstellt, kann eine Dicke von 1 Pixel haben, Unter- und Überkreuzungen müssen jedoch deutlich unterscheidbar sein (die Größe des Seilbruchs sollte um mindestens ein Pixel auf beiden Seiten größer sein als die Dicke des Seils). .
Ich werde Antworten positiv bewerten, die auf den Fähigkeiten der eingebauten Knotentheorie beruhen, aber die, die am Ende ausgewählt wurden, können sich nicht auf die Fähigkeiten der eingebauten Knotentheorie stützen.
Alles, was ich über meine Notation weiß: Ich glaube, dass es Wertesequenzen gibt, die keinem Knoten oder Knoten entsprechen. Zum Beispiel scheint es unmöglich zu sein, die Sequenz [2, 3, 4, 0, 1] zu zeichnen.
Angenommen, Sie nehmen eine Kreuzung und folgen ab dieser Kreuzung dem Pfad des Seils in eine Richtung und kennzeichnen jede nicht gekennzeichnete Kreuzung, auf die Sie stoßen, mit immer größeren Integralwerten. Für alternierende Knoten gibt es einen einfachen Algorithmus, um meine Notation in eine solche Kennzeichnung umzuwandeln, und für alternierende Knoten ist es trivial, diese Kennzeichnung in einen Gauß-Code umzuwandeln:
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 verwenden ...: '(
Knot
eingebautes! Anwendungsbeispiel: << Units`; Convert[Knot, Mile/Hour]
Erträge 1.1507794480235425 Mile/Hour
. (Ich denke, das ist lustig, egal ob es wahr oder falsch ist; aber es ist tatsächlich wahr.)