Soma as conexões de vértice

14

Vamos dizer que você tem um número inteiro positivo N . Primeiro, construa um polígono regular , com N vértices, com a distância entre os vértices vizinhos sendo 1. Em seguida, conecte linhas de todos os vértices a todos os outros vértices. Por fim, calcule o comprimento de todas as linhas somadas.

Exemplo

Dada a entrada N = 6 , construa um hexágono com linhas conectando todos os vértices aos outros vértices.

Hexágono

Como você pode ver, há um total de 6 linhas de borda (comprimento = 1), 3 linhas com o dobro do comprimento da borda (comprimento = 2) e 6 outras linhas que nós, usando o Teorema de Pitágoras, podemos calcular o comprimento para , qual é

Se somarmos os comprimentos das linhas, obtemos (6 * 1) + (3 * 2) + (6 * 1,732) = 22,392 .

informação adicional

Como estruturas com 2 ou menos vértices não estão sendo consideradas polígonos, a saída 0 (ou NaN, como a distância entre um único vértice não faz muito sentido) para N = 1, pois um único vértice não pode ser conectado a outros vértices e 1 para N = 2, pois dois vértices são conectados por uma única linha.

Entrada

Um número inteiro N, em qualquer formato razoável.

Resultado

O comprimento de todas as linhas somadas, com precisão de pelo menos três casas decimais, como retorno de função ou impresso diretamente em stdout.

Regras

  • As brechas padrão são proibidas.
  • Isso é , então o código mais curto em bytes, em qualquer idioma, vence.

Boa sorte!

Casos de teste

(Input) -> (Output)
1 -> 0 or NaN
2 -> 1
3 -> 3
5 -> 13.091
6 -> 22.392
Ian H.
fonte
1
Devemos realmente lidar com isso 1? Minha entrada atual retornaria em nanvez de zero, por exemplo, e exigiria apenas um revestimento especial para ela.
Jonathan Allan
1
@ JonathanAllan Eu pensei sobre isso depois de ver sua resposta, também nané bom, já que a distância entre um único vértice não faz muito sentido.
23717 Ian Ian H.
6
Você provavelmente deve permitir que erros sejam gerados também, n=1eu acho.
Jonathan Allan
É difícil dizer o que significa três casas decimais de precisão sem um limite superior N, pois as saídas aumentam e os flutuadores ficam menos precisos.
Xnor
@xnor Contanto que seja preciso até 3 casas decimais para qualquer entrada N razoável , o resultado é menos preciso para números grandes.
23717 Ian Ian H.

Respostas:

13

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

-6 (talvez até -10 se não precisarmos lidar com isso n=1) graças ao xnor (simplificação trigonométrica adicional e golfe adicional para lidar com o caso de borda 1 e salvar parênteses movendo um floatelenco (agora desnecessário) ).

Esperançosamente superável sem bibliotecas de terceiros ? Sim!! mas vamos fazer as coisas rolar ...

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

Experimente online!

Isso usa uma fórmula para a soma dos comprimentos se um polígono estiver inscrito dentro de um círculo unitário n*cot(pi/2/n)/2e ajusta o resultado a um para o comprimento lateral sendo um dividindo pelo pecado do comprimento do cordão sin(pi/n).

A primeira fórmula é adquirida considerando os n-1comprimentos das cordas de todas as diagonais que emanam de um canto e que são de comprimentos sin(pi/n)(novamente) ,, sin(2*pi/n)..., sin((n-1)pi/n). A soma disso é cot(pi/2/n)que existem ncantos, então multiplicamos por n, mas depois contamos duas vezes todos os cabos, então dividimos por dois.

O resultado n*cot(pi/2/n)/2/sin(pi/n)foi então simplificado pelo xnor para n/2/(1-cos(pi/n))(mantendo pressionado n>1)

... isso (contanto que a precisão seja aceitável) agora não requer sympymais o mathmódulo embutido ( math.pi=3.141592653589793).

Jonathan Allan
fonte
2
sim! salvou 11 bytes. fórmula legal!
J42161217
1
Parece que a fórmula simplifica para n/2/(1-cos(pi/n)).
Xnor
@Xnor Bom local (contanto que pode saída 0.25para n=1- mas embalagem especial pode ser menor também ...)
Jonathan Allan
@ JonathanAllan Huh, estranho esse 1/4é o resultado n=1. Pode ser corrigido com 1%n*. Além disso, é possível salvar parênteses movendo o floatinterior para float(1-cos(pi/n)). Não sei muito sobre o sympy, mas talvez exista uma maneira aritmética de forçar um carro alegórico.
Xnor
@xnor Obrigado! (Eu deveria ter notado a floatmudança). O sympy gera uma expressão - por exemplo, para n=6nenhum resultado de conversão em uma expressão com uma representação 3.0/(-sqrt(3)/2 + 1)- pode haver uma maneira mais curta, mas ainda não a conheço.
Jonathan Allan
7

Python , 34 bytes

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

Experimente online!

Usa a fórmula n/2/(1-cos(pi/n))simplificada de Jonathan Allan . Neil economizou 10 bytes observando que o Python pode calcular raízes da unidade como potências fracionárias de 1j.

Python sem importações não possui funções trigonométricas embutidas pi, ou e. Para n=1dar, em 0vez de 0.25, acrescentamos 1%n*.

Uma versão mais longa usando apenas poderes de número natural:

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

Experimente online!

xnor
fonte
1
Legal como um pepino.
Jonathan Allan
37 bytes:lambda n:1%n*n/(1-(1j**(2/n)).real)/2
Neil
@ Neil Wow, o Python pode apenas calcular as raízes da unidade.
Xnor
Bem, essa foi a parte fácil. Eu não sei o que abs()faz embora.
Neil
@ Neil obtém o valor absoluto, daí a norma, ou seja, a distância da origem.
Jonathan Allan
6

MATL , 16 15 bytes

t:=ZF&-|Rst2)/s

Experimente online! Ou verifique todos os casos de teste .

Isso usa um commit que introduziu a função FFT (Fast Fourier Transform) e que antecede o desafio em 8 dias.

Explicação

O código usa esse truque (adaptado ao MATL) para gerar as raízes da unidade. Eles fornecem as posições dos vértices como números complexos, exceto que a distância entre vértices consecutivos não é normalizada para 1. Para resolver que, depois de calcular todas as distâncias em pares, o programa as divide pela distância 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
fonte
1
isso é lindo #
1128 Jonah
@Jonah números complexos FTW :-)
Luis Mendo
5

Gafanhoto, 25 primitivas (11 componentes, 14 fios)

Li um meta post sobre programas no GH e no LabVIEW e sigo instruções semelhantes para medir uma linguagem visual.

programa gafanhoto

Imprima <null>para N = 0, 1, 2, porque Polygon Primitivenão é possível gerar um polígono com 2 ou menos arestas e você obterá uma lista vazia de linhas.

Componentes da esquerda para a direita:

  • Side count controle deslizante: entrada
  • Primitivo de polígono: desenha um polígono na tela
  • Explodir: explodir uma polilinha em segmentos e vértices
  • Referência cruzada: crie referência cruzada holística entre todos os vértices
  • Linha: desenha uma linha entre todos os pares
  • Excluir linhas duplicadas
  • Comprimento da curva
  • Soma (superior)
  • Divisão (inferior): como Polygon Primitivedesenha um polígono com base no raio, precisamos escalar a forma
  • Multipicação
  • Painel: saída

captura de tela rinoceronte

Keyu Gan
fonte
4

Mathematica, 26 bytes

usa a fórmula de Jonathan Allan

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

Experimente online!

-1 byte junghwan min

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

Haskell , 27 bytes

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

Experimente online!

Acabei de mergulhar em Haskell, então isso acaba sendo um golfe para iniciantes (ou seja, copiar a fórmula de outras respostas).

Eu também tentei muito colocar em $algum lugar, mas o compilador continua gritando comigo, então esse é o melhor que eu tenho. : P

totalmente humano
fonte
2

Geléia , 13 12 11 bytes

Usa a fórmula de Jonathan Allan (e obrigado por salvar 2 bytes)

ØP÷ÆẠCḤɓ’ȧ÷

Experimente online!

Eu sempre fui muito fascinado por Jelly, mas não o usei muito, então essa pode não ser a forma mais simples.

Jeffmagma
fonte
Salvar um byte usando "argumento trocando separação cadeia dyadic", ɓ, para inline seu link ajudante assim:ØP÷ÆẠCḤɓn1×÷
Jonathan Allan
@JonathanAllan oh obrigado, eu ainda sou iniciante e sabia que provavelmente havia uma maneira melhor do que ter uma nova cadeia, mas não sabia como fazê-lo
Jeffmagma
Oh, podemos salvar outro usando decréscimo, e lógico-e, ȧ: ØP÷ÆẠCḤɓ’ȧ÷:)
Jonathan Allan
oh uau, obrigado, eu não tinha pensado nisso #
910 Jeffmagma
1

Javascript (ES6), 36 bytes

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

Port of @ JonathanAllan's Python 3 resposta

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
fonte