Liczba uzwojenia jest liczbą całkowitą obrotów netto przeciwnie do ruchu wskazówek zegara, które obserwator musiał wykonać, aby podążać daną zamkniętą ścieżką. Zwróć uwagę, że wszelkie obroty zgodne z ruchem wskazówek zegara liczą się ujemnie w kierunku liczby uzwojenia. Ścieżka może się przecinać.
Niektóre przykłady (bezwstydnie zaczerpnięte z Wikipedii) podano poniżej:
Twoim celem jest obliczenie liczby uzwojenia dla danej ścieżki.
Wejście
Zakłada się, że obserwator jest u źródła (0,0)
.
Dane wejściowe są skończoną sekwencją punktów (par liczb całkowitych) z dowolnego pożądanego źródła wejściowego, która opisuje kawałkową ścieżkę liniową. W razie potrzeby możesz spłaszczyć tę sekwencję liczb całkowitych 1D, a także zamienić dane wejściowe, aby przyjąć wszystkie współrzędne x przed wszystkimi współrzędnymi y / odwrotnie. Możesz również wziąć dane wejściowe jako liczbę zespolonąa+b i
. Ścieżka może się przecinać i zawierać segmenty o zerowej długości. Pierwszy punkt to początek ścieżki i zakłada się, że leży gdzieś na dodatniej osi x.
Żadna część ścieżki nie przecina początku. Ścieżka zawsze będzie zamknięta (tzn. Pierwszy i utracony punkt są takie same). Twój kod może sugerować ostatni punkt lub wymagać jego uwzględnienia.
Na przykład w zależności od preferencji oba dane wejściowe określają ten sam kwadrat:
domniemany punkt końcowy
1,0
1,1
-1,1
-1,-1
1,-1
wyraźny punkt końcowy
1,0
1,1
-1,1
-1,-1
1,-1
1,0
Wynik
Dane wyjściowe to jedna liczba całkowita dla liczby uzwojenia. Może to być dowolne źródło (zwracana wartość, standardowe wyjście, plik itp.).
Przykłady
Wszystkie przykłady mają wyraźnie zdefiniowany punkt końcowy i są podane jako pary x, y. Nawiasem mówiąc, powinieneś być w stanie bezpośrednio wprowadzić te przykłady do dowolnych kodów, zakładając niejawnie zdefiniowane punkty końcowe, a wyniki powinny być takie same.
1. Test podstawowy
1,0
1,1
-1,1
-1,-1
1,-1
1,0
Wynik
1
2. Test powtarzanego punktu
1,0
1,0
1,1
1,1
-1,1
-1,1
-1,-1
-1,-1
1,-1
1,-1
1,0
Wynik
1
3. Test zgodny z ruchem wskazówek zegara
1,0
1,-1
-1,-1
-1,1
1,1
1,0
Wynik
-1
4. Test zewnętrzny
1,0
1,1
2,1
1,0
Wynik
0
5. Uzwojenie mieszane
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
Wynik
2
Punktacja
To jest kod golfowy; najkrótszy kod wygrywa. Obowiązują standardowe luki. Możesz używać dowolnych wbudowanych funkcji, o ile nie zostały one specjalnie zaprojektowane do obliczania liczby uzwojenia.
"1-i"
lub"1-1i"
?)Odpowiedzi:
ES6, 83 bajty
Bierze jako dane wejściowe tablicę par punktów, które są interpretowane jako liczby zespolone. Zamiast konwertować każdy punkt na kąt, punkty są dzielone przez poprzedni punkt, który Math.atan2 następnie konwertuje na kąt między -π i π, tym samym automatycznie określając, w którą stronę ścieżka jest kręta. Suma kątów jest wtedy 2π razy liczba uzwojenia.
Ponieważ Math.atan2 nie dba o skalę swoich argumentów, tak naprawdę nie wykonuję pełnego podziału
z / w = (z * w*) / (w * w*)
, po prostu mnożę każdy punkt przez złożoną koniugat poprzedniego punktu.Edycja: Zapisano 4 bajty dzięki @ edc65.
źródło
reduce
prawie zawsze jest złym wyborem.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
zamiast tego użyj mapy lub zmniejsz. W każdym razie masz mój głosreduce
ponieważ nie zdawałem sobie sprawy, że Math.atan2 (0,0) wynosi 0. (Cóż, zależy to od tego, czy jedno z twoich 0 to w rzeczywistości -0). Matematyka jest oparta na złożonym podziale, który jest zwykle obliczany jakoz / w = z * w* / |w|²
, ale nie dbam o wielkość, więc to tylko pomnożenie przez złożony koniugat. Również nieco myląco Math.atan2 akceptuje argumenty (y, x).MATL , 11 bajtów
Dane wejściowe to ciąg liczb zespolonych, w tym punkt końcowy.
Wypróbuj online!
Wyjaśnienie
Większość pracy jest wykonywana przez
Z/
funkcję (unwrap
), która rozpakowuje kąty w radianach, zmieniając absolutne skoki większe lub równe pi do ich uzupełnienia 2 * pi.źródło
Galaretka, 11 bajtów
Pobiera to dane wejściowe jako listę współrzędnych y i listę współrzędnych x.
Wypróbuj tutaj .
źródło
Python, 111
Najdłuższa jak dotąd odpowiedź. Moje motywacje to 1) nauczenie się Pythona i 2) prawdopodobnie przeniesienie tego do Pyth'a.
Dane wejściowe podano jako listę liczb zespolonych.
Ideone.
Myślę, że podejście jest podobne do odpowiedzi ES6.
Po pomnożeniu 2 liczb zespolonych argument lub faza iloczynu jest sumą argumentu lub fazy dwóch liczb. Zatem, gdy liczba zespolona jest dzielona przez inną, wówczas faza ilorazu jest różnicą między fazami licznika i mianownika. W ten sposób możemy obliczyć kąt przejścia dla każdego punktu i następnego punktu. Suma tych kątów i podziel przez 2π daje wymaganą liczbę uzwojeń.
źródło