Additionnez les connexions Vertex

14

Disons que vous avez un effet positif entier N . Construisez d'abord un polygone régulier , qui a N sommets, avec la distance entre les sommets voisins étant 1. Ensuite, connectez les lignes de chaque sommet à tous les autres sommets. Enfin, calculez la longueur de toutes les lignes résumées ensemble.

Exemple

Étant donné l'entrée N = 6 , construisez un hexagone avec des lignes reliant chaque sommet aux autres sommets.

Hexagone

Comme vous pouvez le voir, il y a un total de 6 lignes de bordure (longueur = 1), 3 lignes qui ont le double de la longueur de bordure (longueur = 2) et 6 autres lignes que nous, en utilisant le théorème de Pythagore, pouvons calculer la longueur pour , lequel est

Si nous additionnons les longueurs des lignes, nous obtenons (6 * 1) + (3 * 2) + (6 * 1,732) = 22,392 .

Information additionnelle

Comme les structures avec 2 sommets ou moins ne sont pas considérées comme des polygones, affichez 0 (ou NaN, puisque la distance entre un seul sommet n'a pas beaucoup de sens) pour N = 1, car un seul sommet ne peut pas être connecté à d'autres sommets, et 1 pour N = 2, car deux sommets sont reliés par une seule ligne.

Contribution

Un entier N, dans n'importe quel format raisonnable.

Production

La longueur de toutes les lignes résumées ensemble, précise à au moins 3 décimales, soit sous forme de retour de fonction, soit directement imprimée dans stdout.

Règles

  • Les failles standard sont interdites.
  • C'est le , donc le code le plus court en octets, dans n'importe quelle langue, gagne.

Bonne chance!

Cas de test

(Input) -> (Output)
1 -> 0 or NaN
2 -> 1
3 -> 3
5 -> 13.091
6 -> 22.392
Ian H.
la source
1
Faut-il vraiment gérer 1? Mon entrée actuelle retournerait nanplutôt que zéro par exemple, et nécessiterait juste un boîtier spécial pour cela.
Jonathan Allan
1
@JonathanAllan J'y ai pensé après avoir vu votre réponse, ça nanva aussi, car la distance entre un seul sommet n'a pas beaucoup de sens de toute façon.
Ian H.
6
Vous devriez probablement permettre que des erreurs soient lancées aussi, n=1je pense.
Jonathan Allan
Il est difficile de dire ce que signifie 3 décimales de précision sans limite supérieure N, car les sorties deviennent plus grandes et les flottants moins précis.
xnor
@xnor Tant qu'il est précis jusqu'à 3 décimales pour toute entrée raisonnable N , son amende est que le résultat est moins précis pour les nombres énormes.
Ian H.

Réponses:

13

Python 3 (avec sympy ) ,  61 60 58 54  48 octets

-6 (peut-être même -10 si nous n'avons pas besoin de gérer n=1) grâce à xnor (simplification trigonométrique supplémentaire et golf supplémentaire pour gérer le cas de bord de 1 et enregistrer les parenthèses en déplaçant une floatdistribution (désormais inutile) ).

J'espère battable sans bibliothèques tierces ? Oui!! mais permet de faire avancer les choses ...

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

Essayez-le en ligne!

Cela utilise une formule pour la somme des longueurs si un polygone est inscrit à l'intérieur d'un cercle unité, n*cot(pi/2/n)/2et ajuste le résultat à un pour la longueur du côté étant un en divisant par le péché de cette longueur de cordon sin(pi/n).

La première formule s'acquiert en considérant les n-1longueurs de cordons de toutes les diagonales émanant d'un coin qui sont de longueurs sin(pi/n)(encore),, sin(2*pi/n)..., sin((n-1)pi/n). La somme de ceci est cot(pi/2/n)qu'il y a des ncoins donc nous multiplions par n, mais ensuite nous avons compté deux fois tous les cordons, donc nous divisons par deux.

Le résultat n*cot(pi/2/n)/2/sin(pi/n)a ensuite été simplifié par xnor to n/2/(1-cos(pi/n))(holding for n>1)

... cela (tant que la précision est acceptable) ne nécessite plus sympysur le intégrémath module intégré ( math.pi=3.141592653589793).

Jonathan Allan
la source
2
Oui! enregistré 11 octets. formule cool!
J42161217
1
Il semble que la formule se simplifie n/2/(1-cos(pi/n)).
xnor
Bon endroit @xnor (tant que nous pouvons produire 0.25pour n=1- mais le boîtier spécial peut également être plus court ...)
Jonathan Allan
@JonathanAllan Huh, bizarre c'est 1/4le résultat pour n=1. Il peut être corrigé avec 1%n*. En outre, les parens peuvent être enregistrés en déplaçant l' floatintérieur vers float(1-cos(pi/n)). Je ne connais pas beaucoup sympy, mais peut-être y a-t-il un moyen arithmétique de forcer un flotteur.
xnor
@xnor Merci! (J'aurais dû remarquer le floatmouvement). sympy génère une expression - par exemple, si n=6aucun cast ne donne une expression avec une représentation 3.0/(-sqrt(3)/2 + 1)- il peut y avoir un moyen plus court mais je ne le sais pas encore.
Jonathan Allan
7

Python , 34 octets

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

Essayez-le en ligne!

Utilise la formule n/2/(1-cos(pi/n))simplifiée de Jonathan Allan . Neil a économisé 10 octets en notant que Python peut calculer les racines de l'unité en tant que puissances fractionnaires de 1j.

Python sans importations n'a pas de fonctions trigonométriques intégrées,, piou e. Pour faire n=1donner 0plutôt que 0.25, on préfère1%n* .

Une version plus longue utilisant uniquement des pouvoirs de nombre naturel:

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

Essayez-le en ligne!

xnor
la source
1
Froid comme un concombre.
Jonathan Allan
37 octets:lambda n:1%n*n/(1-(1j**(2/n)).real)/2
Neil
@Neil Wow, Python peut simplement calculer les racines de l'unité.
xnor
Eh bien, c'était le plus simple. Je ne sais pas ce qui se abs()passe cependant.
Neil
@Neil obtient la valeur absolue, donc la norme, c'est-à-dire la distance par rapport à l'origine.
Jonathan Allan
6

MATL , 16 15 octets

t:=ZF&-|Rst2)/s

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Cela utilise un commit qui a introduit la fonction FFT (Fast Fourier Transform), et qui est antérieur au défi de 8 jours.

Explication

Le code utilise cette astuce (adaptée à MATL) pour générer les racines de l'unité. Ceux-ci donnent les positions des sommets sous forme de nombres complexes, sauf que la distance entre les sommets consécutifs n'est pas normalisée à 1. Pour résoudre ce problème, après avoir calculé toutes les distances par paires, le programme les divise par la distance entre les sommets consécutifs.

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
la source
1
c'est beau
Jonah
@Jonah Complex numéros FTW :-)
Luis Mendo
5

Sauterelle, 25 primitives (11 composants, 14 fils)

J'ai lu un meta post sur les programmes dans GH et LabVIEW, et je suis des instructions similaires pour mesurer un langage visuel.

programme sauterelle

Imprimez <null>pour N = 0, 1, 2, car Polygon Primitivevous ne pouvez pas générer un polygone avec 2 bords ou moins et vous obtiendrez une liste de lignes vide.

Composants de gauche à droite:

  • Side count curseur: entrée
  • Polygon Primitive: dessine un polygone sur toile
  • Décomposer: décomposer une polyligne en segments et sommets
  • Référence croisée: créer une référence croisée holistique entre tous les sommets
  • Ligne: tracez une ligne entre toutes les paires
  • Supprimer les lignes en double
  • Longueur de courbe
  • (supérieur) Sum
  • (inférieur) Division: parce que Polygon Primitivedessine un polygone en fonction du rayon, nous devons mettre la forme à l'échelle
  • Multipication
  • Panneau: sortie

capture d'écran de rhinocéros

Keyu Gan
la source
4

Mathematica, 26 octets

utilise la formule de @Jonathan Allan

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

Essayez-le en ligne!

-1 octet junghwan min

J42161217
la source
-1 octet: N@Cot[Pi/2/#]/2Csc[Pi/#]#&depuis1/sin(x) = csc(x)
JungHwan Min
2
.5Csc[x=Pi/#]Cot[x/2]#&
Misha Lavrov
2

Haskell , 27 octets

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

Essayez-le en ligne!

Je viens de plonger dans Haskell, donc cela s'avère être un bon golf pour débutant (c'est-à-dire copier la formule à partir d'autres réponses).

J'ai également essayé de mettre $quelque part, mais le compilateur continue de me crier dessus, c'est donc le meilleur que j'ai. : P

totalement humain
la source
2

Gelée , 13 12 11 octets

Utilise la formule de Jonathan Allan (et merci à lui d'avoir économisé 2 octets)

ØP÷ÆẠCḤɓ’ȧ÷

Essayez-le en ligne!

J'ai toujours été assez fasciné par Jelly, mais je ne l'ai pas beaucoup utilisé, donc ce n'est peut-être pas la forme la plus simple.

Jeffmagma
la source
Économisez un octet en utilisant la «séparation de chaîne dyadique par permutation d'arguments», ɓpour aligner votre lien d'aide comme ceci:ØP÷ÆẠCḤɓn1×÷
Jonathan Allan
@JonathanAllan oh merci, je suis toujours un débutant et je savais qu'il y avait probablement un meilleur moyen que d'avoir une nouvelle chaîne mais je ne savais pas comment le faire
Jeffmagma
Oh, nous pouvons sauver une autre en utilisant décrément, et-logique et ȧ: ØP÷ÆẠCḤɓ’ȧ÷:)
Allan Jonathan
oh wow merci je n'y avais pas pensé
Jeffmagma
1

Javascript (ES6), 36 octets

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

Port de @ JonathanAllan's Python 3 answer

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
la source