El número de devanado es el número entero de revoluciones netas en sentido antihorario que un observador debe haber hecho para seguir un camino cerrado dado. Tenga en cuenta que cualquier revolución en el sentido de las agujas del reloj cuenta negativamente hacia el número de devanado. Se permite que el camino se cruce.
A continuación se dan algunos ejemplos (descaradamente tomados de Wikipedia):
Su objetivo es calcular el número de bobinado para una ruta determinada.
Entrada
Se supone que el observador está en el origen (0,0)
.
La entrada es una secuencia finita de puntos (pares de números enteros) de cualquier fuente de entrada deseada que describe la ruta lineal por partes. Puede aplanar esto en una secuencia 1D de números enteros si lo desea, y también puede mezclar la entrada para tomar todas las coordenadas x antes de todas las coordenadas y / viceversa. También puede tomar la entrada como un número complejo a+b i
. La ruta puede auto intersectarse y puede contener segmentos de longitud cero. El primer punto es el inicio de la ruta y se supone que se encuentra en algún lugar del eje x positivo.
Ninguna parte del camino se cruzará con el origen. La ruta siempre estará cerrada (es decir, el primer punto y el punto perdido son los mismos). Su código puede implicar el último punto o requerir que se incluya.
Por ejemplo, dependiendo de su preferencia, ambas entradas especifican el mismo cuadrado:
punto final implícito
1,0
1,1
-1,1
-1,-1
1,-1
punto final explícito
1,0
1,1
-1,1
-1,-1
1,-1
1,0
Salida
La salida es un número entero único para el número de devanado. Esto puede ser a cualquier fuente (valor de retorno, stdout, archivo, etc.).
Ejemplos
Todos los ejemplos tienen el punto final explícitamente definido y se dan como pares x, y. Por cierto, también debería poder alimentar directamente estos ejemplos en cualquier código suponiendo puntos finales definidos implícitamente y las salidas deberían ser las mismas.
1. Prueba básica
1,0
1,1
-1,1
-1,-1
1,-1
1,0
Salida
1
2. Prueba repetida de puntos
1,0
1,0
1,1
1,1
-1,1
-1,1
-1,-1
-1,-1
1,-1
1,-1
1,0
Salida
1
3. Prueba en sentido horario
1,0
1,-1
-1,-1
-1,1
1,1
1,0
Salida
-1
4. Prueba exterior
1,0
1,1
2,1
1,0
Salida
0
5. Bobinado mixto
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
Salida
2
Puntuación
Este es el código de golf; el código más corto gana. Se aplican lagunas estándar. Puede usar cualquier función incorporada siempre que no estén específicamente diseñadas para calcular el número de devanado.
"1-i"
o"1-1i"
?)Respuestas:
ES6, 83 bytes
Toma como entrada una matriz de pares de puntos que se interpretan como números complejos. En lugar de convertir cada punto en un ángulo, los puntos se dividen por el punto anterior, que Math.atan2 luego convierte en un ángulo entre -π y π, lo que determina automáticamente en qué dirección se está enrollando el camino. La suma de los ángulos es entonces 2π veces el número de devanado.
Como Math.atan2 no se preocupa por la escala de sus argumentos, en realidad no realizo la división completa,
z / w = (z * w*) / (w * w*)
sino que simplemente multiplico cada punto por el complejo conjugado del punto anterior.Editar: Guardado 4 bytes gracias a @ edc65.
fuente
reduce
casi siempre es una mala elección.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
usando el mapa en su lugar o reducir. Tienes mi voto de todos modosreduce
porque no me di cuenta de que Math.atan2 (0,0) es 0. (Bueno, depende de si uno de tus 0 es realmente -0.) Las matemáticas se basan en una división compleja, que normalmente se calcula comoz / w = z * w* / |w|²
, pero no me importa la magnitud, así que es solo la multiplicación por el conjugado complejo. También un poco confusamente Math.atan2 acepta argumentos (y, x).MATL , 11 bytes
La entrada es una secuencia de números complejos que incluye el punto final.
Pruébalo en línea!
Explicación
La mayor parte del trabajo se realiza mediante la
Z/
función (unwrap
), que desenvuelve los ángulos en radianes cambiando los saltos absolutos mayores o iguales que pi a su complemento 2 * pi.fuente
Jalea, 11 bytes
Esto toma la entrada como una lista de coordenadas y y una lista de coordenadas x.
Pruébalo aquí .
fuente
Python, 111
La respuesta más larga hasta ahora. Mis motivaciones son 1) aprender python y 2) posiblemente portar esto a pyth.
La entrada se da como una lista de números complejos.
Ideona
Creo que el enfoque es similar a la respuesta ES6.
Cuando se multiplican 2 números complejos, el argumento o la fase del producto es la suma del argumento o la fase de los dos números. Así, cuando un número complejo se divide por otro, la fase del cociente es la diferencia entre las fases del numerador y el denominador. Por lo tanto, podemos calcular el ángulo atravesado para cada punto y el siguiente punto. Sumar estos ángulos y dividir por 2π da el número de devanado requerido.
fuente