Фон (пропустите к определениям)
Эйлер доказал красивую теорему о комплексных числах: e ix = cos (x) + i sin (x).
Это позволяет легко доказать теорему де Мойвра:
(e ix ) n = e i (nx)
(cos (x) + i sin (x)) n = cos (nx) + i sin (nx)
Мы можем построить комплексные числа, используя двумерную евклидову плоскость, где горизонтальная ось представляет действительную часть, а вертикальная ось представляет мнимую часть. Таким образом, (3,4) будет соответствовать комплексному числу 3 + 4i.
Если вы знакомы с полярными координатами, (3,4) будет (5, arctan (4/3)) в полярных координатах. Первое число r - это расстояние точки от начала координат; второе число θ - это угол, измеренный от положительной оси x к точке против часовой стрелки. В результате 3 = r cosθ и 4 = r sinθ. Поэтому мы можем записать 3 + 4i как r cosθ + ri sinθ = r (cosθ + i sinθ) = re iθ .
Решим комплексное уравнение z n = 1, где n - натуральное число.
Пусть z = re iθ . Тогда z n = r n e inθ . Расстояние z n от начала координат равно r n , а угол равен nθ. Однако мы знаем, что расстояние 1 от начала координат равно 1, а угол равен 0. Следовательно, r n = 1 и nθ = 0. Однако, если вы повернете на 2π больше, вы все равно окажетесь в той же точке, потому что 2π - это просто полный круг. Следовательно, r = 1 и nθ = 2kπ, что дает нам z = e 2ikπ / n .
Мы повторяем наше открытие: решения для z n = 1 являются z = e 2ikπ / n .
Многочлен можно выразить через его корни. Например, корни x 2 -3x + 2 равны 1 и 2, поэтому x 2 -3x + 2 = (x-1) (x-2). Точно так же из нашего открытия выше:
Однако этот продукт, безусловно, содержал корни других русских. Например, возьмите n = 8. Корни z 4 = 1 также будут включены в корни z 8 = 1, поскольку z 4 = 1 подразумевает z 8 = (z 4 ) 2 = 1 2 = 1. Возьмем n = 6 в качестве примера. Если z 2 = 1, то мы также имели бы z 6 = 1. Аналогично, если z 3 = 1, то z 6 = 1.
Если мы хотим извлечь корни, уникальные для z n = 1, нам нужно, чтобы k и n не разделяли общий делитель, кроме 1. Или же, если они разделяют общий делитель d, где d> 1, то z будет (k / г) -ый корень из z n / d = 1. Используя вышеописанную технику, чтобы написать многочлен в терминах его корней, мы получим многочлен:
Обратите внимание, что этот многочлен выполняется путем удаления корней из z n / d = 1, где d является делителем n. Мы утверждаем, что полином выше имеет целочисленные коэффициенты. Рассмотрим LCM многочленов в виде z n / d -1, где d> 1 и d делит n. Корни LCM - это именно те корни, которые мы хотим удалить. Поскольку каждый компонент имеет целочисленные коэффициенты, LCM также имеет целочисленные коэффициенты. Поскольку LCM делит z n -1, частное должно быть многочленом с целочисленным коэффициентом, а частное является многочленом выше.
Корни z n = 1 имеют радиус 1, поэтому они образуют круг. Полином представляет точки окружности, уникальные для n, поэтому в некотором смысле полиномы образуют разбиение окружности. Следовательно, приведенный выше многочлен является n-м циклическим многочленом. (Цикло- = круг; том- = разрезать)
Определение 1
Обозначенный n-й циклотомический многочлен является единственным многочленом с целочисленными коэффициентами, которые делят x n -1, но не x k -1 при k <n.
Определение 2
Циклотомные полиномы - это набор полиномов, по одному на каждое положительное целое число, такой что:
где к | n означает, что k делит n.
Определение 3
N-й циклотомический полином - это полином x n -1, деленный на LCM полиномов в виде x k -1, где k делит n и k <n.
Примеры
- Φ 1 (x) = x - 1
- Ф 2 (х) = х + 1
- Ф 3 (х) = х 2 + х + 1
- Φ 30 (x) = x 8 + x 7 - x 5 - x 4 - x 3 + x + 1
- Φ 105 (x) = x 48 + x 47 + x 46 - x 43 - x 42 - 2x 41 - x 40 - x 39 + x 36 + x 35 + x 34 + x 33 + x 32 + x 31 - x 28 - x 26 - x 24 - x 22 - x 20 + x 17 + x 16 + x 15 + x 14 + x 13 + x 12 - x9 - х 8 - 2х 7 - х 6 - х 5 + х 2 + х + 1
задача
Если задано положительное целое число n
, верните-й n
циклотомический полином, как определено выше, в приемлемом формате (например, допустим список коэффициентов).
правила
Вы можете возвращать числа с плавающей запятой / комплексные числа, пока они округляются до правильного значения.
счет
Это код-гольф . Кратчайший ответ в байтах побеждает.
Ссылки
источник
Ответы:
Haskell , 120 байт
Попробуйте онлайн!
Предоставляет список сложных чисел с плавающей точкой, например,
1.0000000000000078 :+ 3.314015728506092e-14
из-за неточности. Прямой метод умножения для восстановления полинома из его корней.Это
fromInteger
большая уступка системе типов Хаскелла. Должен быть лучший способ. Предложения приветствуются. Работа с корнями единства символически может также сработать.Haskell , 127 байт
Попробуйте онлайн!
Нет импорта.
Использует формулу
Вычисляет Φ_n (x) путем деления LHS на каждое из других слагаемых в RHS.
Оператор
%
выполняет деление на полиномы, полагаясь на то, что остаток равен нулю. Делитель считается моническим и задается без начального 1, а также с бесконечными конечными нулями, чтобы избежать усечения при выполненииzipWith
.источник
[0,0..]
на байт корочеrepeat 0
.Mathematica,
4341 байтКонечно, мы всегда можем использовать встроенную функцию, но если нет, это делит x n -1 на Φ k ( x ) (вычисляется рекурсивно) для каждого правильного делителя k числа n .
Мы используем,
Factor
чтобы получить полином в конце. Я думаю, что причина этой работы заключается в том, чтоx^#-1
факторы во все циклотомические полиномы делителей делятся n , а затем мы делим те, которые нам не нужны.-2 байта благодаря Jenny_mathy, переписав его так, чтобы он относился
Factor
только к числителю.источник
Factor@
Factor[x^#-1]/Times@@...
вместо; если бы у нас не было скобок, мы бы хотели скобки.Factor[x^#-1]/Times@@...
, и это также означает, что я понятия не имею, как он работает.MATL ,
32312725 байтовВывод может быть нецелым из-за неточностей с плавающей точкой (что разрешено). Нижний колонтитул делает округление для ясности.
Попробуйте онлайн!
источник
Haskell ,
250 236 233 218216 байтЭто подробная версия, (@xnor может сделать это почти вдвое меньше ), но она гарантированно для любого
n
условии, что у вас достаточно памяти, но она не использует встроенную функцию для генерации n-го циклотомического полинома. Входные данные представляют собой целые числа произвольного размера, а выходные данные представляют собой полиномиальный тип с (точными) рациональными коэффициентами.Грубая идея здесь состоит в том, чтобы вычислить многочлены рекурсивно. Для
n=1
илиn
премьер это тривиально. Для всех остальных чисел этот подход в основном использует формулу из определения 2решено для . Спасибо @ H.PWiz за кучу байтов!
Для
n=105
этого получим следующий полином (я убрал все%1
знаменатели):Полином для
n=15015
можно найти здесь (самый большой коэффициент 23).Попробуйте онлайн!
источник
+1
за то, что не был встроенным.Rationals
? Кажется, что они работают без нихquotRemPoly
, позвольте мне попробовать еще раз!Double
коэффициенты, если вы не используетеRatio Integer
вместо этого, что может вызвать проблемы для очень (очень) большихn
.Желе , 23 байта
Попробуйте онлайн!
Выходы в виде списка коэффициентов.
Имеет плавающую точку и сложные неточности. Нижний колонтитул делает округление, чтобы сделать вывод более красивым.
источник
J , 36 байт
Попробуйте онлайн!
Использует формулу
Есть некоторые неточности с плавающей точкой, но это разрешено.
источник
Mathematica, 81 байт
источник
R ,
176171139112 байтПопробуйте онлайн!
Значительно более простая версия; использует
for
цикл, а неReduce
.источник
Пари / ГП , 8 байт
Встроенный.
Попробуйте онлайн!
Pari / GP , 39 байт, без встроенного
Используя формулу:
Попробуйте онлайн!
источник
CJam (
5251 байт)Демо онлайн . Это анонимный блок (функция), который принимает целое число в стеке и оставляет массив коэффициентов с большим порядком байтов в стеке.
рассечение
источник
JavaScript (ES6),
337333284...252250245242 байтаОбъяснение (выбрано):
Инициализировать z = (1 + 0i) * x ^ 0
Расчет ГКД.
Поскольку мне нужно довольно часто использовать математические функции, я использовал здесь другую переменную.
Полиномиальное умножение.
Используемая формула
Сжать вывод обратно в целочисленный массив.
Выходы:
Массив целых чисел, с элементом в позиции i, представляющим коэффициент x ^ i.
Одна из проблем, с которой сталкивается JS, состоит в том, что, поскольку JS не предоставляет собственную библиотеку для вычислений по полиномам и комплексным числам, их необходимо реализовывать в виде массива.
console.log (phi (105)) дает
337> 333 (-4): изменен код для проверки неопределенного значения
333> 284 (-49): изменена функция умножения полиномов, поскольку ее можно упростить
284> 277 (-7): удален некоторый избыточный код
277> 265 (-12): используйте 2 переменные вместо 2-элементного массива, чтобы уменьшить использование байтов в массиве
265> 264 (-1): используйте Array.push () вместо Array.concat () для уменьшения 4 байтов, но добавьте 3 для фигурных скобок цикла и переменную z
264> 263 (-1): далее игра в гольф по последней поправке
263> 262 (-1): играли в петлю
262> 260 (-2): игра в гольф
260> 258 (-2): далее объединили декларации
258> 252 (-6): игра в гольф при повторном использовании ссылок на массивы
252> 250 (-2): заменить некоторые унарные операторы как бинарные операторы
250> 245 (-5): переместить инкремент в Array.map () к последней ссылке на счетчик, чтобы удалить байты
245> 242 (-3): используйте расширенный синтаксис вместо Array.push ()
источник