Escriba un programa para dibujar un diagrama 2D de un nudo basado en la estructura del nudo. Un nudo es exactamente lo que parece: un lazo de cuerda que está atado. En matemáticas, un diagrama de nudos muestra dónde un trozo de cuerda se cruza sobre o debajo de sí mismo para formar el nudo. A continuación se muestran algunos diagramas de nudos de ejemplo:
Hay una ruptura en la línea donde la cuerda se cruza sobre sí misma.
Entrada: la entrada que describe el nudo es una matriz de enteros. Un nudo donde la cuerda se cruza sobre sí misma n veces puede representarse como una matriz de n enteros, cada uno con un valor en el rango [0, n-1]. Vamos a llamar a esta matriz K .
Para obtener la matriz que describe un nudo, numere cada uno de los segmentos del 0 al n-1. El segmento 0 debería conducir al segmento 1, que debería conducir al segmento 2, que debería conducir al segmento 3, y así sucesivamente hasta que el segmento n-1 regrese y conduzca al segmento 0. Un segmento termina cuando otro segmento de cuerda lo cruza ( representado por un salto en la línea del diagrama). Tomemos el nudo más simple: el nudo trébol. Después de haber numerado los segmentos, el segmento 0 termina cuando el segmento 2 lo cruza; el segmento 1 termina cuando el segmento 0 lo cruza; y el segmento 2 termina cuando el segmento 1 cruza sobre él. Por lo tanto, la matriz que describe el nudo es [2, 0, 1]. En general, el segmento x comienza donde quedó el segmento x-1 mod n , y termina donde el segmento K [x] lo cruza.
La siguiente imagen muestra diagramas de nudos, con segmentos etiquetados y las matrices correspondientes que describen el nudo.
Los tres diagramas superiores son nudos verdaderos, mientras que los tres inferiores son bucles de cuerda que se cruzan sobre sí mismos pero que en realidad no están anudados (pero que todavía tienen los códigos correspondientes).
Su tarea es escribir una función que tome una matriz de enteros K (podría llamarse algo diferente) que describa un nudo (o lazo de cuerda que en realidad no está anudado), y que produzca el diagrama de nudos correspondiente, como se describe en el anterior ejemplos Si puede, proporcione una versión no codificada de su código o una explicación, y también proporcione resultados de muestra de su código. El mismo nudo a menudo se puede representar de múltiples maneras diferentes, pero si el diagrama de nudos que satisface su salida tiene la entrada como una de sus posibles representaciones, su solución es válida.
Este es el código de golf, por lo que gana el código más corto en bytes. La línea que representa la cuerda puede tener un grosor de 1 píxel, sin embargo, los cruces inferiores y superiores deben ser claramente distinguibles (el tamaño de la rotura de la cuerda debe ser mayor que el grosor de la cuerda en al menos un píxel a cada lado) .
Votaré las respuestas que se basan en las capacidades de la teoría de nudos incorporadas, pero la que se selecciona al final no puede confiar en las capacidades de la teoría de nudos incorporadas.
Todo lo que sé sobre mi notación: creo que hay secuencias de valores que no parecen corresponder a ningún nudo o nudo. Por ejemplo, la secuencia [2, 3, 4, 0, 1] parece ser imposible de dibujar.
Aparte de eso, suponga que toma un cruce y, a partir de ese cruce, siga el camino de la cuerda en una dirección y etiquete cada cruce sin etiquetar que encuentre con valores integrales sucesivamente mayores. Para nudos alternos, hay un algoritmo simple para convertir mi notación en tal etiquetado, y para nudos alternos es trivial convertir este etiquetado en un Código 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
en Mathematica ...: '(
Knot
incorporado! Ejemplo de uso: << Units`; Convert[Knot, Mile/Hour]
rendimientos 1.1507794480235425 Mile/Hour
. (Creo que esto es divertido independientemente de si es verdadero o falso; pero en realidad es cierto.)