Суммирование вершинных соединений

14

Допустим, у вас есть целое положительное число N . Сначала создайте правильный многоугольник с N вершинами, с расстоянием между соседними вершинами, равным 1. Затем соедините линии из каждой вершины с любой другой вершиной. Наконец, рассчитайте длину всех строк, суммируемых вместе.

пример

Учитывая вход N = 6 , построить шестиугольник с линиями, соединяющими каждую вершину с другими вершинами.

шестиугольник

Как вы можете видеть, есть всего 6 линий границы (длина = 1), 3 линии, которые удваивают длину границы (длина = 2), и 6 других линий, которые мы, используя теорему Пифагора, можем вычислить длину для , который

Если мы сложим длины линий вместе, мы получим (6 * 1) + (3 * 2) + (6 * 1.732) = 22.392 .

Дополнительная информация

Поскольку структуры с 2 или менее вершинами не считаются полигонами, выведите 0 (или NaN, поскольку расстояние между одной вершиной не имеет большого смысла) для N = 1, поскольку одна вершина не может быть связана с другими вершинами, а 1 для N = 2, так как две вершины соединены одной линией.

вход

Целое число N в любом приемлемом формате.

Выход

Длина всех строк, суммируемых вместе, с точностью не менее 3 десятичных знаков, либо в виде функции возврата, либо в виде прямой печати stdout.

правила

  • Стандартные лазейки запрещены.
  • Это , поэтому выигрывает самый короткий код в байтах на любом языке.

Удачи!

Тестовые случаи

(Input) -> (Output)
1 -> 0 or NaN
2 -> 1
3 -> 3
5 -> 13.091
6 -> 22.392
Ян Х.
источник
1
Должны ли мы действительно справиться 1? Моя текущая запись будет возвращаться nan, например, вместо нуля, и для этого потребуется специальный регистр.
Джонатан Аллан
1
@JonathanAllan Я подумал об этом, увидев ваш ответ, nanтоже хорошо, так как расстояние между одной вершиной в любом случае не имеет особого смысла.
Ян Х.
6
Вы, вероятно, должны допустить, чтобы ошибки тоже генерировались, как n=1мне кажется.
Джонатан Аллан
Трудно сказать, что означают 3 десятичных знака точности без верхней границы N, поскольку выходные данные увеличиваются, а значения с плавающей точкой становятся менее точными.
xnor
@xnor До тех пор, пока он будет точным с точностью до 3 знаков после запятой для любого разумного ввода N , хорошо, что результат будет менее точным для больших чисел.
Ян Х.

Ответы:

13

Python 3 SymPy ) ,  61 60 58 54  48 байт

-6 (может быть, даже -10, если нам не нужно обрабатывать n=1) благодаря xnor (дальнейшее тригонометрическое упрощение плюс дальнейшая игра в гольф для обработки крайнего случая 1 и сохранения скобок путем перемещения (теперь ненужного) floatброска).

Надеемся, что можно победить без сторонних библиотек? Да!! но давайте заставим вещи катиться ...

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

Попробуйте онлайн!

При этом используется формула для суммы длин, если многоугольник вписан в единичный круг, n*cot(pi/2/n)/2и корректируется результат на единицу для длины стороны, равной единице, путем деления на грех этой длины шнура sin(pi/n).

Первая формула получается путем рассмотрения n-1длины шнуров всех диагоналей, исходящих из одного угла, которые имеют длину sin(pi/n)(снова) sin(2*pi/n),, ..., sin((n-1)pi/n). Сумма этого в том cot(pi/2/n), что есть nуглы, поэтому мы умножаем на n, но затем мы дважды подсчитали все шнуры, поэтому мы делим на два.

В результате чего n*cot(pi/2/n)/2/sin(pi/n)была затем упрощена путем XNOR , чтобы n/2/(1-cos(pi/n))(выдержка в течение n>1)

... это (при условии, что точность приемлема) теперь больше не требуется по sympyсравнению со встроенным mathмодулем ( math.pi=3.141592653589793).

Джонатан Аллан
источник
2
да! сохранено 11 байт. классная формула!
J42161217
1
Похоже, формула упрощается до n/2/(1-cos(pi/n)).
xnor
Хорошее место @xnor (до тех пор , как мы можем выход 0.25для n=1- но специальный корпус может быть короче , тоже ...)
Джонатан Allan
@JonathanAllan Ха, странный 1/4результат для n=1. Это может быть исправлено 1%n*. Кроме того, паренсы могут быть сохранены путем перемещения floatвнутрь float(1-cos(pi/n)). Я не очень много знаю, но, может быть, есть арифметический способ заставить поплавок.
xnor
@xnor Спасибо! (Я должен был заметить floatдвижение). sympy выводит выражение - например, если n=6приведение не приводит к выражению с представлением 3.0/(-sqrt(3)/2 + 1)- вполне может быть более короткий путь, но я его пока не знаю.
Джонатан Аллан
7

Python , 34 байта

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

Попробуйте онлайн!

Использует формулу, n/2/(1-cos(pi/n))упрощенную от Джонатана Аллана . Нил сэкономил 10 байтов, отметив, что Python может вычислять корни единства как дробные степени 1j.

Python без импорта не имеет встроенных тригонометрических функций pi, или e. Для того, чтобы n=1дать , 0а не 0.25мы предварять 1%n*.

Более длинная версия, использующая только натуральные числа:

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

Попробуйте онлайн!

XNOR
источник
1
Круто как огурец.
Джонатан Аллан
37 байтов:lambda n:1%n*n/(1-(1j**(2/n)).real)/2
Нил
@ Нил Вау, Python может просто вычислить корни единства.
xnor
Ну, это было легко. Я не знаю, что abs()делает, хотя.
Нил
@Neil получает абсолютное значение, отсюда и норму, то есть расстояние от начала координат.
Джонатан Аллан
6

MATL , 16 15 байт

t:=ZF&-|Rst2)/s

Попробуйте онлайн! Или проверьте все тестовые случаи .

При этом используется фиксация, которая представила функцию FFT (быстрое преобразование Фурье) и которая предшествует вызову на 8 дней.

объяснение

Код использует этот трюк (адаптированный к MATL) для генерации корней единства. Они дают позиции вершин в виде комплексных чисел, за исключением того, что расстояние между последовательными вершинами не нормируется на 1. Чтобы решить, что после вычисления всех парных расстояний программа делит их на расстояние между последовательными вершинами.

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
это прекрасно
Иона
@Jonah Комплексные числа FTW :-)
Луис Мендо
5

Кузнечик, 25 примитивов (11 компонентов, 14 проводов)

Я читаю мета-пост о программах в GH и LabVIEW и следую аналогичным инструкциям для измерения визуального языка.

программа кузнечика

Выведите <null>для N = 0, 1, 2, потому что Polygon Primitiveне можете сгенерировать многоугольник с 2 или менее ребрами, и вы получите пустой список линий.

Компоненты слева направо:

  • Side count ползунок: вход
  • Примитив полигонов: нарисуйте многоугольник на холсте
  • Разрывать: Разрывать ломаную линию на сегменты и вершины
  • Перекрестная ссылка: создать целостную перекрестную ссылку между всеми вершинами
  • Линия: провести линию между всеми парами
  • Удалить дубликаты строк
  • Длина кривой
  • (верхняя) сумма
  • (нижнее) деление: поскольку Polygon Primitiveрисует многоугольник на основе радиуса, нам нужно масштабировать форму
  • Multipication
  • Панель: выход

скриншот носорога

Кейу Ган
источник
4

Mathematica, 26 байтов

использует формулу Джонатана Аллана

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

Попробуйте онлайн!

-1 байт Junghwan мин

J42161217
источник
-1 байт: N@Cot[Pi/2/#]/2Csc[Pi/#]#&с1/sin(x) = csc(x)
JungHwan Мин
2
.5Csc[x=Pi/#]Cot[x/2]#&
Миша Лавров,
2

Haskell , 27 байт

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

Попробуйте онлайн!

Я просто нырнул в Haskell, так что это оказалось честным новичком в гольф (то есть, копируя формулу из других ответов).

Я также старался $куда-то положить, но компилятор продолжает на меня кричать, так что это лучшее, что у меня есть. :П

totallyhuman
источник
2

Желе , 13 12 11 байт

Использует формулу Джонатана Аллана (и спасибо ему за сохранение 2 байта)

ØP÷ÆẠCḤɓ’ȧ÷

Попробуйте онлайн!

Я всегда был в восторге от желе, но не использовал его много, так что это, возможно, не самая простая форма.

Jeffmagma
источник
Сохраните байт, используя «разделение аргументов диадической цепочкой», ɓчтобы встроить вашу вспомогательную ссылку следующим образом:ØP÷ÆẠCḤɓn1×÷
Джонатан Аллан
@JonathanAllan о, спасибо, я все еще новичок и знал, что, вероятно, есть лучший способ, чем иметь новую цепь, но не знал, как это сделать
Джеффмагма
О, мы можем спасти другого, используя декремент, и логические-и, :) ȧ:ØP÷ÆẠCḤɓ’ȧ÷
Джонатан Аллан
Ого, спасибо, я не думал об этом
Джеффмагма
1

Javascript (ES6), 36 байт

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

Порт @ JonathanAllan's 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>

Герман Л
источник