Zsumuj połączenia wierzchołków

14

Powiedzmy, że masz dodatnią liczbę całkowitą N . Najpierw zbuduj regularny wielokąt, który ma N wierzchołków, przy czym odległość między sąsiednimi wierzchołkami wynosi 1. Następnie połącz linie z każdego wierzchołka do każdego innego wierzchołka. Na koniec obliczyć długość wszystkich linii zsumowanych razem.

Przykład

Biorąc pod uwagę wartość wejściową N = 6 , zbuduj sześciokąt z liniami łączącymi każdy wierzchołek z innymi wierzchołkami.

Sześciokąt

Jak widać, istnieje w sumie 6 linii brzegowych (długość = 1), 3 linie, które mają podwójną długość granicy (długość = 2) i 6 innych linii, które za pomocą twierdzenia Pitagorasa możemy obliczyć długość dla , który jest

Jeśli dodamy razem długości linii, otrzymamy (6 * 1) + (3 * 2) + (6 * 1,732) = 22,392 .

Dodatkowe informacje

Ponieważ struktury z 2 lub mniejszymi wierzchołkami nie są uważane za wielokąty, wyjmij 0 (lub NaN, ponieważ odległość między pojedynczym wierzchołkiem nie ma większego sensu) dla N = 1, ponieważ pojedynczego wierzchołka nie można połączyć z innymi wierzchołkami, a 1 dla N = 2, ponieważ dwa wierzchołki są połączone jedną linią.

Wejście

Liczba całkowita N, w dowolnym rozsądnym formacie.

Wynik

Długość wszystkich linii zsumowanych razem, z dokładnością do co najmniej 3 miejsc po przecinku, albo jako funkcja powrotu, albo bezpośrednio do wydruku stdout.

Zasady

  • Standardowe luki są zabronione.
  • To jest , więc wygrywa najkrótszy kod w bajtach, w dowolnym języku.

Powodzenia!

Przypadki testowe

(Input) -> (Output)
1 -> 0 or NaN
2 -> 1
3 -> 3
5 -> 13.091
6 -> 22.392
Ian H.
źródło
1
Czy naprawdę musimy sobie poradzić 1? Mój obecny wpis powróciłby nanna przykład zamiast zera i wymagałby po prostu specjalnej obudowy.
Jonathan Allan
1
@JonathanAllan Pomyślałem o tym po tym, jak zobaczyłem twoją odpowiedź, nanjest też w porządku, ponieważ odległość między jednym wierzchołkiem i tak nie ma większego sensu.
Ian H.
6
n=1Myślę, że powinieneś chyba pozwolić na zgłaszanie błędów .
Jonathan Allan
Trudno powiedzieć, co oznaczają 3 miejsca dziesiętne dokładności bez górnej granicy N, ponieważ wyniki stają się większe, a zmiennoprzecinkowe mniej precyzyjne.
xnor
@ xnor Dopóki jest dokładny do 3 miejsc po przecinku dla każdego rozsądnego wejścia N , jego kara jest mniejsza w przypadku dużych liczb.
Ian H.

Odpowiedzi:

13

Python 3 (z sympią ) ,  61 60 58 54  48 bajtów

-6 (może nawet -10, jeśli nie musimy sobie poradzić n=1) dzięki xnor (dalsze uproszczenie trygonometryczne plus dalsze gry w golfa, aby obsłużyć skrzynkę 1 i oszczędzić nawiasy, przesuwając (teraz niepotrzebne) floatrzut).

Mam nadzieję, że do pokonania bez bibliotek stron trzecich ? Tak!! ale Sprawmy, żeby wszystko kręciło się ...

lambda n:1%n*n/2/(1-cos(pi/n))
from math import*

Wypróbuj online!

Wykorzystuje to wzór na sumę długości, jeśli wielokąt jest wpisany w koło jednostkowe, n*cot(pi/2/n)/2i dopasowuje wynik do jednego dla długości boku równej jeden, dzieląc przez grzech tej długości sznurka sin(pi/n).

Pierwszą formułę uzyskuje się, biorąc pod uwagę n-1długości sznurka wszystkich przekątnych wychodzących z jednego rogu, które mają długości sin(pi/n)(ponownie) sin(2*pi/n), ..., sin((n-1)pi/n). Suma tego jest taka cot(pi/2/n), że są nrogi, więc mnożymy przez n, ale potem policzyliśmy dwukrotnie wszystkie sznury, więc dzielimy przez dwa.

Wynik n*cot(pi/2/n)/2/sin(pi/n)został następnie uproszczony przez xnor do n/2/(1-cos(pi/n))(przytrzymanie n>1)

... to (o ile dokładność jest akceptowalna) nie wymaga już sympywbudowanego mathmodułu ( math.pi=3.141592653589793).

Jonathan Allan
źródło
2
tak! zapisane 11 bajtów. fajna formuła!
J42161217,
1
Wygląda na to, że formuła upraszcza n/2/(1-cos(pi/n)).
xnor
@Xnor dobre miejsce (tak długo, jak możemy wyjście 0.25dla n=1- ale specjalny obudowa może być krótszy zbyt ...)
Jonathan Allan
@JonathanAllan Huh, dziwne, że taki 1/4jest wynik n=1. Można go załatać 1%n*. Pareny można również zapisać, przesuwając floatwnętrze do float(1-cos(pi/n)). Nie wiem zbyt dobrze, ale może istnieje arytmetyczny sposób na wymuszenie pływaka.
xnor
@xnor Thanks! (Powinienem był zauważyć floatruch). sympy wyprowadza wyrażenie - np. n=6brak rzutowania powoduje wyrażenie z reprezentacją 3.0/(-sqrt(3)/2 + 1)- może być krótszy sposób, ale jeszcze go nie znam.
Jonathan Allan
7

Python , 34 bajty

lambda n:1%n*n/abs(1-1j**(2/n))**2

Wypróbuj online!

Używa formuły n/2/(1-cos(pi/n))uproszczonej od Jonathana Allana . Neil zaoszczędził 10 bajtów, zauważając, że Python może obliczyć pierwiastki jedności jako ułamkowe moce 1j.

Python bez importu nie ma wbudowanych funkcji trygonometrycznych pi, lub e. Aby n=1dać 0zamiast 0.25, możemy poprzedzić 1%n*.

Dłuższa wersja wykorzystująca tylko moce liczb naturalnych:

lambda n:1%n*n/abs(1-(1+1e-8j/n)**314159265)**2

Wypróbuj online!

xnor
źródło
1
Fajny jak ogórek.
Jonathan Allan
37 bajtów:lambda n:1%n*n/(1-(1j**(2/n)).real)/2
Neil
@ Neil Wow, Python może po prostu obliczyć korzenie jedności.
xnor
Cóż, to było łatwe. Nie wiem jednak, co to abs()robi.
Neil,
@ Neil otrzymuje wartość bezwzględną, stąd normę, tj. Odległość od początku.
Jonathan Allan
6

MATL , 16 15 bajtów

t:=ZF&-|Rst2)/s

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wykorzystuje zatwierdzenie, które wprowadziło funkcję FFT (szybka transformata Fouriera) i które poprzedza wyzwanie o 8 dni.

Wyjaśnienie

Kod wykorzystuje tę sztuczkę (dostosowaną do MATL) do generowania korzeni jedności. Dają one pozycje wierzchołków jako liczby zespolone, z tym wyjątkiem, że odległość między kolejnymi wierzchołkami nie jest znormalizowana do 1. Aby rozwiązać ten problem, po obliczeniu wszystkich odległości parami, program dzieli je przez odległość między kolejnymi wierzchołkami.

t       % Implicit input, n. Duplicate
:       % Range: [1 2 ... n-1 n]
=       % Isequal, element-wise. Gives [0 0 ... 0 1]
ZF      % FFT. Gives the n complex n-th roots of unity
&-|     % Matrix of pairwise absolute differences
R       % Upper triangular matrix. This avoids counting each line twice.
s       % Sum of each column. The second entry gives the distance between
        % consecutive vertices
t2)/    % Divide all entries by the second entry
s       % Sum. Implicit display
Luis Mendo
źródło
1
to jest piękne
Jonasz
@Jonah Liczba zespolona FTW :-)
Luis Mendo
5

Konik polny, 25 prymitywów (11 elementów, 14 drutów)

Czytam meta post na temat programów w GH i LabVIEW i postępuję zgodnie z podobnymi instrukcjami, aby zmierzyć język wizualny.

program konik polny

Drukuj <null>dla N = 0, 1, 2, ponieważ Polygon Primitivenie można wygenerować wielokąta o 2 lub mniejszej liczbie krawędzi, a otrzymasz pustą listę linii.

Komponenty od lewej do prawej:

  • Side count suwak: wprowadzanie
  • Wielokąt Prymityw: narysuj wielokąt na płótnie
  • Rozbij: Rozbij polilinię na segmenty i wierzchołki
  • Odsyłacz: buduj holistyczne odniesienie między wszystkimi wierzchołkami
  • Linia: narysuj linię między wszystkimi parami
  • Usuń zduplikowane linie
  • Długość łuku
  • (górna) suma
  • (dolny) Podział: ponieważ Polygon Primitiverysuje wielokąt na podstawie promienia, musimy przeskalować kształt
  • Mnożenie
  • Panel: wyjście

zrzut ekranu nosorożca

Keyu Gan
źródło
4

Mathematica, 26 bajtów

używa formuły @Jathanathan Allan

N@Cot[Pi/2/#]/2Csc[Pi/#]#&   

Wypróbuj online!

-1 bajt Junghwan min

J42161217
źródło
-1 bajt: N@Cot[Pi/2/#]/2Csc[Pi/#]#&od1/sin(x) = csc(x)
JungHwan Min
2
.5Csc[x=Pi/#]Cot[x/2]#&
Misha Lavrov
2

Haskell , 27 bajtów

f 1=0
f n=n/2/(1-cos(pi/n))

Wypróbuj online!

Właśnie zagłębiłem się w Haskell, więc okazało się, że jest to dobry golf dla początkujących (czyli kopiowanie formuły z innych odpowiedzi).

Starałem się też $gdzieś umieścić, ale kompilator wciąż na mnie krzyczy, więc to najlepsze, co mam. : P

całkowicie ludzki
źródło
2

Galaretka , 13 12 11 bajtów

Korzysta ze wzoru Jonathana Allana (i dziękuje mu za uratowanie 2 bajtów)

ØP÷ÆẠCḤɓ’ȧ÷

Wypróbuj online!

Zawsze fascynowała mnie Jelly, ale nie używałem jej zbyt wiele, więc może to nie być najprostsza forma.

Jeffmagma
źródło
Oszczędź bajt, używając „wymiany argumentów dyadic separacji łańcucha”, ɓaby wstawić link pomocnika w ten sposób:ØP÷ÆẠCḤɓn1×÷
Jonathan Allan
@JonathanAllan, dziękuję, wciąż jestem początkujący i wiedziałem, że prawdopodobnie jest lepszy sposób niż nowy łańcuch, ale nie wiedziałem, jak to zrobić
Jeffmagma
Och, możemy uratować innego, używając dekrementacji, i logicznie, i ȧ: ØP÷ÆẠCḤɓ’ȧ÷:)
Jonathan Allan
o wow dzięki, nie myślałem o tym
Jeffmagma
1

JavaScript (ES6), 36 bajtów

n=>1%n*n/2/(1-Math.cos(Math.PI/n))

Port odpowiedzi @ JonathanAllan na Python 3

f=n=>1%n*n/2/(1-Math.cos(Math.PI/n))
<input id=i type=number oninput="o.innerText=f(i.value)" /><pre id=o>

Herman L.
źródło