Somma le connessioni vertici


14

Diciamo che si dispone di un intero positivo N . Innanzitutto, costruisci un poligono regolare , che ha N vertici, con la distanza tra i vertici vicini pari a 1. Quindi collega le linee da ogni vertice a ogni altro vertice. Infine, calcola la lunghezza di tutte le righe riassunte insieme.

Esempio

Dato l'ingresso N = 6 , costruisci un esagono con linee che collegano ogni vertice con gli altri vertici.

Esagono

Come puoi vedere, ci sono un totale di 6 linee di confine (lunghezza = 1), 3 linee che hanno il doppio della lunghezza del bordo (lunghezza = 2) e 6 altre linee che, usando il Teorema di Pitagora, possiamo calcolare la lunghezza per , che è

Se sommiamo le lunghezze delle linee otteniamo (6 * 1) + (3 * 2) + (6 * 1.732) = 22.392 .

Informazioni aggiuntive

Poiché le strutture con 2 o meno vertici non vengono considerate poligoni, l'uscita 0 (o NaN, poiché la distanza tra un singolo vertice non ha molto senso) per N = 1, poiché un singolo vertice non può essere collegato ad altri vertici e 1 per N = 2, poiché due vertici sono collegati da un'unica linea.

Ingresso

Un numero intero N, in qualsiasi formato ragionevole.

Produzione

La lunghezza di tutte le linee sommate insieme, accurate con almeno 3 cifre decimali, come ritorno di una funzione o direttamente stampate stdout.

Regole

  • Sono vietate le scappatoie standard.
  • Questo è , quindi vince il codice più breve in byte, in qualsiasi lingua.

In bocca al lupo!

Casi test

(Input) -> (Output)
1 -> 0 or NaN
2 -> 1
3 -> 3
5 -> 13.091
6 -> 22.392

1
Dobbiamo davvero gestire 1? La mia voce corrente ritornerebbe nanpiuttosto che zero per esempio, e richiederebbe solo un involucro speciale per questo.
Jonathan Allan,

1
@JonathanAllan Ci ho pensato dopo aver visto la tua risposta, nanva bene anche perché la distanza tra un singolo vertice non ha comunque molto senso.
Ian H.

6
Probabilmente dovresti permettere che anche gli errori vengano lanciati, n=1credo.
Jonathan Allan,

È difficile dire cosa significhino 3 cifre decimali di precisione senza un limite superiore N, poiché le uscite diventano più grandi e i float diventano meno precisi.
xnor

@xnor Finché è preciso fino a 3 cifre decimali per qualsiasi input ragionevole N , la sua multa è il risultato è meno preciso per numeri enormi.
Ian H.,

Risposte:


13

Python 3 (con sympy ) ,  61 60 58 54  48 byte

-6 (forse anche -10 se non abbiamo bisogno di gestirlo n=1) grazie a xnor (ulteriore semplificazione trigonometrica più ulteriore golfing per gestire il caso limite di 1 e salvare le parentesi spostando un floatcast (ora non necessario) ).

Spero che sia battibile senza librerie di terze parti ? Sì!! ma facciamo girare le cose ...

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

Provalo online!

Questo utilizza una formula per la somma delle lunghezze se un poligono è inscritto all'interno di un cerchio unitario n*cot(pi/2/n)/2e regola il risultato su uno per la lunghezza del lato che è uno dividendo per il peccato di quella lunghezza del cavo sin(pi/n).

La prima formula viene acquisita considerando le n-1lunghezze del cavo di tutte le diagonali emanate da un angolo che sono di lunghezza sin(pi/n)(di nuovo),, sin(2*pi/n)..., sin((n-1)pi/n). La somma è che cot(pi/2/n)ci sono nangoli per cui moltipliciamo per n, ma poi abbiamo contato due volte tutti i cavi, quindi dividiamo per due.

Il risultato è n*cot(pi/2/n)/2/sin(pi/n)stato quindi semplificato da xnor in n/2/(1-cos(pi/n))(tenendo premuto per n>1)

... questo (purché l'accuratezza sia accettabile) ora non richiede più sympysul mathmodulo integrato ( math.pi=3.141592653589793).


2
sì! salvato 11 byte. formula fantastica!
J42161217

1
Sembra che la formula semplifichi n/2/(1-cos(pi/n)).
xnor

Good spot @xnor (a condizione che possiamo uscire 0.25per n=1- ma un involucro speciale potrebbe anche essere più corto ...)
Jonathan Allan,

@JonathanAllan Huh, strano che 1/4è il risultato per n=1. Può essere patchato con 1%n*. Inoltre, le parentesi possono essere salvate spostando l' floatinterno in float(1-cos(pi/n)). Non conosco molto Sympy, ma forse esiste un modo aritmetico per forzare un galleggiante.
xnor

@xnor Grazie! (Avrei dovuto notare la floatmossa). sympy genera un'espressione - ad es. per il n=6cast non risulta un'espressione con una rappresentazione 3.0/(-sqrt(3)/2 + 1)- potrebbe esserci un modo più breve ma non lo so ancora.
Jonathan Allan,

7

Python , 34 byte

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

Provalo online!

Utilizza la formula n/2/(1-cos(pi/n))semplificata da Jonathan Allan . Neil ha salvato 10 byte notando che Python può calcolare le radici dell'unità come poteri frazionari di 1j.

Python senza importazioni non ha funzioni trigonometriche incorporate pi, o e. Per n=1dare, 0piuttosto che 0.25, anteponiamo 1%n*.

Una versione più lunga che utilizza solo poteri con numeri naturali:

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

Provalo online!


1
Fresco come un cetriolo.
Jonathan Allan,

37 byte:lambda n:1%n*n/(1-(1j**(2/n)).real)/2
Neil,

@Neil Wow, Python può semplicemente calcolare le radici dell'unità.
xnor

Bene, è stato un po 'facile. Non so cosa abs()significhi però.
Neil,

@Neil ottiene il valore assoluto, quindi la norma, cioè la distanza dall'origine.
Jonathan Allan,

6

MATL , 16 15 byte

t:=ZF&-|Rst2)/s

Provalo online! Oppure verifica tutti i casi di test .

Questo utilizza un commit che ha introdotto la funzione FFT (Fast Fourier Transform) e che precede la sfida di 8 giorni.

Spiegazione

Il codice usa questo trucco (adattato a MATL) per generare le radici dell'unità. Questi forniscono le posizioni dei vertici come numeri complessi, tranne per il fatto che la distanza tra vertici consecutivi non è normalizzata a 1. Per risolvere il problema, dopo aver calcolato tutte le distanze a coppie, il programma li divide per la distanza tra vertici consecutivi.

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

1
è bellissimo
Giona il

@Jonah Numeri complessi FTW :-)
Luis Mendo il

5

Cavalletta, 25 primitivi (11 componenti, 14 fili)

Ho letto un meta post sui programmi in GH e LabVIEW e seguo istruzioni simili per misurare un linguaggio visivo.

programma di cavallette

Stampa <null>per N = 0, 1, 2, perché Polygon Primitivenon puoi generare un poligono con 2 o meno spigoli e otterrai un elenco vuoto di linee.

Componenti da sinistra a destra:

  • Side count cursore: input
  • Poligono Primitivo: disegna un poligono su tela
  • Esplodi: esplode una polilinea in segmenti e vertici
  • Riferimento incrociato: crea un riferimento incrociato olistico tra tutti i vertici
  • Linea: traccia una linea tra tutte le coppie
  • Elimina linee duplicate
  • Lunghezza della curva
  • (superiore) Somma
  • (inferiore) Divisione: poiché Polygon Primitivedisegna il poligono in base al raggio, dobbiamo ridimensionare la forma
  • multipication
  • Pannello: uscita

screenshot di rinoceronte



2

Haskell , 27 byte

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

Provalo online!

Mi sono appena tuffato in Haskell, quindi questo risulta essere un discreto golf per principianti (cioè copiare la formula da altre risposte).

Ho anche cercato di mettere $da qualche parte, ma il compilatore continua a urlare contro di me, quindi questo è il migliore che ho. : P


2

Gelatina , 13 12 11 byte

Utilizza la formula di Jonathan Allan (e grazie a lui per aver salvato 2 byte)

ØP÷ÆẠCḤɓ’ȧ÷

Provalo online!

Sono sempre stato piuttosto affascinato da Jelly, ma non l'ho usato molto, quindi questa potrebbe non essere la forma più semplice.


Salvare un byte usando "Argomento scambiando la separazione della catena diadica", ɓper incorporare il collegamento di aiuto in questo modo:ØP÷ÆẠCḤɓn1×÷
Jonathan Allan

@JonathanAllan oh grazie, sono ancora un principiante e sapevo che probabilmente c'era un modo migliore di avere una nuova catena ma non sapevo come farlo
Jeffmagma

Oh, possiamo salvarne un altro usando decremento, e logico, e ȧ: ØP÷ÆẠCḤɓ’ȧ÷:)
Jonathan Allan

oh caspita grazie non ci avevo pensato
Jeffmagma,

1

Javascript (ES6), 36 byte

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

Porta della risposta Python 3 di JonathanAllan

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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.