Scrivi un programma per disegnare un diagramma 2D di un nodo basato sulla struttura del nodo. Un nodo è esattamente quello che sembra: un anello di corda che è legato. In matematica, un diagramma di nodo mostra dove un pezzo di corda attraversa sopra o sotto se stesso per formare il nodo. Di seguito sono riportati alcuni schemi di nodi di esempio:
C'è una rottura nella linea in cui la corda attraversa se stessa.
Input: l'input che descrive il nodo è un array di numeri interi. Un nodo in cui la corda incrocia su se stessa n volte può essere rappresentato come una matrice di n numeri interi, ciascuno con un valore compreso nell'intervallo [0, n-1]. Chiamiamo questo array K .
Per ottenere l'array che descrive un nodo, numerare ciascuno dei segmenti da 0 a n-1. Il segmento 0 dovrebbe condurre al segmento 1, che dovrebbe portare al segmento 2, che dovrebbe portare al segmento 3, e così via fino a quando il segmento n-1 si sposta indietro e conduce al segmento 0. Un segmento termina quando un altro segmento di fune lo attraversa ( rappresentato da un'interruzione nella linea nel diagramma). Facciamo il nodo più semplice: il nodo del trifoglio. Dopo aver numerato i segmnenti, il segmento 0 termina quando il segmento 2 lo attraversa; il segmento 1 termina quando il segmento 0 lo attraversa; e il segmento 2 termina quando il segmento 1 lo attraversa. Pertanto, l'array che descrive il nodo è [2, 0, 1]. In generale, il segmento x inizia da dove il segmento x-1 mod n è stato interrotto e termina dove il segmento K [x] lo attraversa.
L'immagine seguente mostra i diagrammi dei nodi, con segmenti etichettati e le matrici corrispondenti che descrivono il nodo.
I tre diagrammi superiori sono veri nodi, mentre i tre inferiori sono anelli di corda che si incrociano su se stessi ma che in realtà non sono annodati (ma che hanno ancora codici corrispondenti).
Il tuo compito è scrivere una funzione che accetta una matrice di numeri interi K (potresti chiamarla in modo diverso) che descriva un nodo (o un anello di corda che non è effettivamente annodato) e che produce il diagramma del nodo corrispondente, come descritto sopra esempi. Se è possibile, fornire una versione non modificata del codice o una spiegazione e fornire anche output di esempio del codice. Lo stesso nodo può spesso essere rappresentato in più modi diversi, ma se il diagramma dei nodi che la tua funzione soddisfa ha l'input come una delle sue possibili rappresentazioni, la tua soluzione è valida.
Questo è code-golf, quindi vince il codice più breve in byte. La linea che rappresenta la corda può avere uno spessore di 1 pixel, tuttavia gli incroci sotto e gli incroci devono essere chiaramente distinguibili (la dimensione della rottura della corda dovrebbe essere maggiore dello spessore della corda di almeno un pixel su entrambi i lati) .
Valuterò le risposte che si basano sulle capacità integrate della teoria dei nodi, ma quella selezionata alla fine non può fare affidamento sulle capacità integrate della teoria dei nodi.
Tutto quello che so della mia notazione: credo che ci siano sequenze di valori che non sembrano corrispondere a nessun nodo o sregolato. Ad esempio, la sequenza [2, 3, 4, 0, 1] sembra impossibile da disegnare.
A parte ciò, supponi di prendere un incrocio e, partendo da quell'incrocio, segui il percorso della corda in una direzione ed etichetta ogni incrocio senza etichetta che incontri con valori integrali sempre più grandi. Per i nodi alternati, esiste un semplice algoritmo per convertire la mia notazione in tale etichettatura e per i nodi alternati è banale convertire questa etichettatura in un codice di 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
in Mathematica ...: '(
Knot
! Esempio di utilizzo: << Units`; Convert[Knot, Mile/Hour]
rese 1.1507794480235425 Mile/Hour
. (Penso che questo sia divertente indipendentemente dal fatto che sia vero o falso; ma in realtà è vero.)