Le nombre d'enroulement est le nombre entier de révolutions nettes dans le sens antihoraire qu'un observateur doit avoir effectuées pour suivre un chemin fermé donné. Notez que toute rotation dans le sens des aiguilles d'une montre compte négative pour le nombre de bobinage. Le chemin est autorisé à s'entrecroiser.
Quelques exemples (pris sans vergogne de Wikipedia) sont donnés ci-dessous:
Votre objectif est de calculer le nombre d'enroulement pour un chemin donné.
Contribution
L'observateur est supposé être à l'origine (0,0)
.
L'entrée est une séquence finie de points (paire de nombres entiers) provenant de n'importe quelle source d'entrée souhaitée qui décrit le chemin linéaire par morceaux. Vous pouvez aplatir cela en une séquence 1D de nombres entiers si vous le souhaitez, et vous pouvez également étaler l'entrée pour prendre toutes les coordonnées x avant toutes les coordonnées y / vice-versa. Vous pouvez également prendre l'entrée comme un nombre complexe a+b i
. Le chemin peut se recouper et peut contenir des segments de longueur nulle. Le premier point est le début du chemin et est supposé se situer quelque part sur l'axe x positif.
Aucune partie du chemin ne coupera l'origine. Le chemin sera toujours fermé (c'est-à-dire que le premier et le point perdu sont les mêmes). Votre code peut impliquer le dernier point ou exiger qu'il soit inclus.
Par exemple, selon votre préférence, les deux entrées spécifient le même carré:
point final implicite
1,0
1,1
-1,1
-1,-1
1,-1
point final explicite
1,0
1,1
-1,1
-1,-1
1,-1
1,0
Production
La sortie est un entier unique pour le nombre d'enroulement. Il peut s'agir de n'importe quelle source (valeur de retour, sortie standard, fichier, etc.).
Exemples
Tous les exemples ont le point final explicitement défini et sont donnés sous forme de paires x, y. Soit dit en passant, vous devriez également pouvoir directement alimenter ces exemples dans n'importe quel code en supposant des points d'extrémité définis implicitement et les sorties devraient être les mêmes.
1. Test de base
1,0
1,1
-1,1
-1,-1
1,-1
1,0
Production
1
2. Test ponctuel répété
1,0
1,0
1,1
1,1
-1,1
-1,1
-1,-1
-1,-1
1,-1
1,-1
1,0
Production
1
3. Test dans le sens horaire
1,0
1,-1
-1,-1
-1,1
1,1
1,0
Production
-1
4. Test extérieur
1,0
1,1
2,1
1,0
Production
0
5. Enroulement mixte
1,0
1,1
-1,1
-1,-1
1,-1
1,0
1,-1
-1,-1
-1,1
1,1
1,0
1,1
-1,1
-1,-1
1,-1
1,0
1,1
-1,1
-1,-1
1,-1
1,0
Production
2
Notation
C'est le golf de code; le code le plus court gagne. Des échappatoires standard s'appliquent. Vous pouvez utiliser toutes les fonctions intégrées tant qu'elles n'ont pas été spécifiquement conçues pour calculer le nombre d'enroulement.
"1-i"
ou"1-1i"
?)Réponses:
ES6, 83 octets
Prend en entrée un tableau de paires de points qui sont interprétés comme des nombres complexes. Plutôt que de convertir chaque point en un angle, les points sont divisés par le point précédent, que Math.atan2 convertit ensuite en un angle entre -π et π, déterminant ainsi automatiquement la direction dans laquelle le chemin s'enroule. La somme des angles est alors 2π fois le nombre d'enroulement.
Puisque Math.atan2 ne se soucie pas de l'échelle de ses arguments, je n'effectue pas réellement la division complète
z / w = (z * w*) / (w * w*)
au lieu de cela, je multiplie simplement chaque point par le conjugué complexe du point précédent.Edit: 4 octets enregistrés grâce à @ edc65.
la source
reduce
c'est presque toujours un mauvais choix.a=>a.map(([x,y])=>r+=Math.atan2(y*b-x*c,y*c+x*b,b=x,c=y),b=c=r=0)&&r/Math.PI/2
utilisez plutôt la carte ou réduisez. Vous avez quand même mon votereduce
parce que je ne savais pas que Math.atan2 (0,0) est égal à 0. (Eh bien, cela dépend si l'un de vos 0 est réellement -0.) Les mathématiques sont basées sur une division complexe, qui est normalement calculée commez / w = z * w* / |w|²
, mais je ne me soucie pas de l'ampleur, donc c'est juste une multiplication par le conjugué complexe. Math.atan2 accepte également de manière légèrement confuse les arguments (y, x).MATL , 11 octets
L'entrée est une séquence de nombres complexes comprenant le point final.
Essayez-le en ligne!
Explication
La plupart du travail est effectué par la
Z/
fonction (unwrap
), qui déroule les angles en radians en modifiant les sauts absolus supérieurs ou égaux à pi à leur complément 2 * pi.la source
Gelée, 11 octets
Cela prend l'entrée comme une liste de coordonnées y et une liste de coordonnées x.
Essayez-le ici .
la source
Python, 111
Réponse la plus longue jusqu'à présent. Mes motivations sont 1) d'apprendre python et 2) éventuellement de porter cela en pyth.
L'entrée est donnée sous la forme d'une liste de nombres complexes.
Ideone.
Je pense que l'approche est similaire à la réponse ES6.
Lorsque 2 nombres complexes sont multipliés, l'argument ou la phase du produit est la somme de l'argument ou de la phase des deux nombres. Ainsi, lorsqu'un nombre complexe est divisé par un autre, la phase du quotient est la différence entre les phases du numérateur et du dénominateur. Ainsi, nous pouvons calculer l'angle traversé pour chaque point et le point suivant. Additionner ces angles et diviser par 2π donne le nombre d'enroulement requis.
la source