Écrivez un programme pour dessiner un diagramme 2D d'un nœud basé sur la structure du nœud. Un nœud est exactement ce à quoi il ressemble: une boucle de corde qui est attachée. En mathématiques, un diagramme de nœuds montre où un morceau de corde se croise sur ou sous lui-même pour former le nœud. Voici quelques exemples de diagrammes de nœuds:
Il y a une rupture dans la ligne où la corde se croise.
Entrée: l'entrée décrivant le nœud est un tableau d'entiers. Un nœud où la corde se croise sur elle-même n fois peut être représenté comme un tableau de n entiers, chacun avec une valeur dans la plage [0, n-1]. Appelons ce tableau K .
Pour obtenir le tableau décrivant un nœud, numérotez chacun des segments de 0 à n-1. Le segment 0 doit conduire au segment 1, qui doit conduire au segment 2, qui doit conduire au segment 3, et ainsi de suite jusqu'à ce que le segment n-1 boucle en arrière et mène au segment 0. Un segment se termine lorsqu'un autre segment de corde le traverse ( représenté par une coupure dans la ligne du diagramme). Prenons le nœud le plus simple - le nœud trèfle. Après avoir numéroté les segments, le segment 0 se termine lorsque le segment 2 le traverse; le segment 1 se termine lorsque le segment 0 le traverse; et le segment 2 se termine lorsque le segment 1 le traverse. Ainsi, le tableau décrivant le nœud est [2, 0, 1]. En général, le segment x commence là où le segment x-1 mod n s'est arrêté et se termine là où le segment K [x] le traverse.
L'image ci-dessous montre des diagrammes de nœuds, avec des segments étiquetés et les tableaux correspondants qui décrivent le nœud.
Les trois diagrammes supérieurs sont de vrais nœuds, tandis que les trois derniers sont des boucles de corde qui se croisent mais qui ne sont pas réellement nouées (mais qui ont toujours des codes correspondants).
Votre tâche consiste à écrire une fonction qui prend un tableau d'entiers K (vous pourriez l'appeler quelque chose de différent) qui décrit un nœud (ou une boucle de corde qui n'est pas réellement nouée), et qui produit le diagramme de nœud correspondant, comme décrit ci-dessus exemples. Si vous le pouvez, fournissez une version non golfée de votre code ou une explication, ainsi que des exemples de sorties de votre code. Le même nœud peut souvent être représenté de plusieurs façons différentes, mais si le diagramme de nœuds que votre sortie de fonction satisfait a l'entrée comme l'une de ses représentations possibles, votre solution est valide.
C'est le code-golf, donc le code le plus court en octets gagne. La ligne représentant la corde peut avoir une épaisseur de 1 pixel, mais les traversées et les franchissements doivent être clairement distinguables (la taille de la rupture de la corde doit être supérieure à l'épaisseur de la corde d'au moins un pixel de chaque côté) .
Je vais voter pour des réponses qui reposent sur des capacités de théorie des nœuds intégrées, mais celle qui est finalement sélectionnée ne peut pas s'appuyer sur des capacités de théorie des nœuds intégrées.
Tout ce que je sais de ma notation: je crois qu'il y a des séquences de valeurs qui ne semblent correspondre à aucun nœud ou à un nœud. Par exemple, la séquence [2, 3, 4, 0, 1] semble impossible à tracer.
En dehors de cela, supposez que vous prenez un croisement et, à partir de ce croisement, suivez le chemin de la corde dans une direction et étiquetez chaque croisement sans étiquette que vous rencontrez avec des valeurs intégrales successivement plus grandes. Pour les nœuds alternés, il existe un algorithme simple pour convertir ma notation en un tel étiquetage, et pour les nœuds alternés, il est trivial de convertir cet étiquetage en un code Gauss:
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
dans Mathematica ...: '(
Knot
intégré! Exemple d'utilisation: << Units`; Convert[Knot, Mile/Hour]
rendements 1.1507794480235425 Mile/Hour
. (Je pense que c'est drôle, que ce soit vrai ou faux; mais c'est en fait vrai.)