Suma las conexiones de vértices

14

Digamos que usted tiene un entero positivo N . Primero, construya un polígono regular , que tenga N vértices, con una distancia entre vértices vecinos de 1. Luego, conecte las líneas de cada vértice a cualquier otro vértice. Por último, calcule la longitud de todas las líneas sumadas juntas.

Ejemplo

Dada la entrada N = 6 , construye un hexágono con líneas que conectan cada vértice con los otros vértices.

Hexágono

Como puede ver, hay un total de 6 líneas de borde (longitud = 1), 3 líneas que tienen el doble de la longitud del borde (longitud = 2) y otras 6 líneas que, utilizando el Teorema de Pitágoras, podemos calcular la longitud para , cual es

Si sumamos las longitudes de las líneas juntas obtenemos (6 * 1) + (3 * 2) + (6 * 1.732) = 22.392 .

Información Adicional

Como las estructuras con 2 o menos vértices no se consideran polígonos, la salida 0 (o NaN, dado que la distancia entre un solo vértice no tiene mucho sentido) para N = 1, ya que un solo vértice no se puede conectar a otros vértices, y 1 para N = 2, ya que dos vértices están conectados por una sola línea.

Entrada

Un entero N, en cualquier formato razonable.

Salida

La longitud de todas las líneas se sumaron juntas, con una precisión de al menos 3 decimales, ya sea como función de retorno o directamente impresas stdout.

Reglas

  • Las lagunas estándar están prohibidas.
  • Este es el , por lo que gana el código más corto en bytes, en cualquier idioma.

¡Buena suerte!

Casos de prueba

(Input) -> (Output)
1 -> 0 or NaN
2 -> 1
3 -> 3
5 -> 13.091
6 -> 22.392
Ian H.
fuente
1
¿Realmente debemos manejarlo 1? Mi entrada actual volvería en nanlugar de cero, por ejemplo, y solo requeriría una carcasa especial para ello.
Jonathan Allan
1
@ JonathanAllan Pensé en ello después de ver tu respuesta, también nanestá bien, ya que la distancia entre un solo vértice no tiene mucho sentido de todos modos.
Ian H.
66
Probablemente también deberías permitir que se arrojen errores n=1, creo.
Jonathan Allan
Es difícil decir qué significan 3 cifras decimales de precisión sin un límite superior N, ya que las salidas se hacen más grandes y los flotantes se vuelven menos precisos.
xnor
@xnor Siempre que sea preciso hasta 3 decimales para cualquier entrada N razonable , su resultado es menos preciso para números grandes.
Ian H.

Respuestas:

13

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

-6 (tal vez incluso -10 si no necesitamos manejarlo n=1) gracias a xnor (mayor simplificación trigonométrica más golf adicional para manejar el caso de borde de 1 y guardar paréntesis moviendo un floatmolde (ahora innecesario) ).

Esperemos que sea vencible sin bibliotecas de terceros ? ¡¡Si!! pero vamos a poner las cosas en marcha ...

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

Pruébalo en línea!

Utiliza una fórmula para la suma de las longitudes si se inscribe un polígono dentro de un círculo unitario, n*cot(pi/2/n)/2 y ajusta el resultado a uno para que la longitud del lado sea uno dividiendo por el pecado de esa longitud del cable sin(pi/n).

La primera fórmula se adquiere considerando las n-1longitudes de cable de todas las diagonales que emanan de una esquina que son de longitudes sin(pi/n)(nuevamente) sin(2*pi/n), ..., sin((n-1)pi/n). La suma de esto escot(pi/2/n) hay nesquinas por lo que multiplicamos por n, pero luego hemos contado dos veces todos los cables, por lo que dividimos por dos.

El resultado n*cot(pi/2/n)/2/sin(pi/n)fue luego simplificado por xnor paran/2/(1-cos(pi/n)) (manteniendo n>1)

... esto (siempre y cuando la precisión sea aceptable) ahora ya no requiere sympymás del mathmódulo incorporado ( math.pi=3.141592653589793).

Jonathan Allan
fuente
2
¡si! guardado 11 bytes. fórmula genial!
J42161217
1
Parece que la fórmula se simplifica n/2/(1-cos(pi/n)).
xnor
@Xnor buen lugar (siempre que nos puede dar salida 0.25a n=1- pero carcasa especial puede ser más corto también ...)
Jonathan Allan
@JonathanAllan Huh, raro, ese 1/4es el resultado n=1. Se puede parchar con 1%n*. Además, los parens se pueden guardar moviendo el floatinterior a float(1-cos(pi/n)). No sé mucho sobre Sympy, pero tal vez haya una forma aritmética de forzar un flotador.
xnor
@xnor Gracias! (Debería haber notado el floatmovimiento). sympy genera una expresión, por ejemplo, para n=6ningún resultado de conversión en una expresión con una representación 3.0/(-sqrt(3)/2 + 1), bien puede haber una forma más corta, pero aún no lo sé.
Jonathan Allan
7

Python , 34 bytes

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

Pruébalo en línea!

Utiliza la fórmula n/2/(1-cos(pi/n))simplificada de Jonathan Allan . Neil ahorró 10 bytes al señalar que Python puede calcular las raíces de la unidad como potencias fraccionarias de 1j.

Python sin importaciones no tiene funciones trigonométricas integradas pi, o e. Hacer n=1dar en 0lugar de dar0.25 , anteponemos 1%n*.

Una versión más larga que usa solo poderes de números naturales:

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

Pruébalo en línea!

xnor
fuente
1
Fresco como una lechuga.
Jonathan Allan
37 bytes:lambda n:1%n*n/(1-(1j**(2/n)).real)/2
Neil
@Neil Wow, Python solo puede calcular las raíces de la unidad.
xnor
Bueno, esa fue la parte fácil. Aunque no sé lo que abs()hace.
Neil
@Neil obtiene el valor absoluto, de ahí la norma, es decir, la distancia desde el origen.
Jonathan Allan
6

MATL , 16 15 bytes

t:=ZF&-|Rst2)/s

Pruébalo en línea! O verificar todos los casos de prueba .

Esto usa un commit que introdujo la función FFT (Transformación rápida de Fourier) y que antecede el desafío en 8 días.

Explicación

El código usa este truco (adaptado a MATL) para generar las raíces de la unidad. Estos dan las posiciones de los vértices como números complejos, excepto que la distancia entre vértices consecutivos no está normalizada a 1. Para resolver eso, después de calcular todas las distancias por pares, el programa las divide por la distancia entre vértices consecutivos.

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
fuente
1
esto es hermoso
Jonás
@Jonah Complex números FTW :-)
Luis Mendo
5

Saltamontes, 25 primitivas (11 componentes, 14 cables)

Leí una meta publicación sobre programas en GH y LabVIEW, y sigo instrucciones similares para medir un lenguaje visual.

programa de saltamontes

Imprimir <null>para N =0, 1, 2 , porque Polygon Primitiveno puede generar un polígono con 2 o menos aristas y obtendrá una lista vacía de líneas.

Componentes de izquierda a derecha:

  • Side count control deslizante: entrada
  • Polígono primitivo: dibuja un polígono sobre lienzo
  • Explotar: Explota una polilínea en segmentos y vértices.
  • Referencia cruzada: crea una referencia cruzada holística entre todos los vértices
  • Línea: dibuja una línea entre todos los pares
  • Eliminar líneas duplicadas
  • Longitud de la curva
  • (superior) Suma
  • División (inferior): debido a que Polygon Primitivedibuja un polígono basado en el radio, necesitamos escalar la forma
  • Multiplicacion
  • Panel: salida

captura de pantalla de rinoceronte

Keyu Gan
fuente
4

Mathematica, 26 bytes

usa la fórmula de @Jonathan Allan

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

Pruébalo en línea!

-1 byte junghwan min

J42161217
fuente
-1 byte: N@Cot[Pi/2/#]/2Csc[Pi/#]#&since1/sin(x) = csc(x)
JungHwan Min
2
.5Csc[x=Pi/#]Cot[x/2]#&
Misha Lavrov
2

Haskell , 27 bytes

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

Pruébalo en línea!

Acabo de sumergirme en Haskell, por lo que resulta ser un buen golf para principiantes (es decir, copiar la fórmula de otras respuestas).

También he intentado ponerlo en $algún lugar, pero el compilador me sigue gritando, así que esto es lo mejor que tengo. :PAG

totalmente humano
fuente
2

Jalea , 13 12 11 bytes

Utiliza la fórmula de Jonathan Allan (y gracias a él por guardar 2 bytes)

ØP÷ÆẠCḤɓ’ȧ÷

Pruébalo en línea!

Siempre he estado bastante fascinado con Jelly, pero no lo he usado mucho, por lo que esta podría no ser la forma más simple.

Jeffmagma
fuente
Guarde un byte usando "separación de cadena diádica de intercambio de argumentos", ɓpara alinear su enlace auxiliar de la siguiente manera:ØP÷ÆẠCḤɓn1×÷
Jonathan Allan
@JonathanAllan oh gracias, todavía soy un principiante y sabía que probablemente había una mejor manera que tener una nueva cadena, pero no sabía cómo hacerlo
Jeffmagma
Oh, podemos salvar a otro usando decremento, y lógico y ȧ: ØP÷ÆẠCḤɓ’ȧ÷:)
Jonathan Allan
oh wow, gracias, no había pensado en eso
Jeffmagma
1

Javascript (ES6), 36 bytes

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

Port of @ JonathanAllan's Python 3 respuesta

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
fuente