Примитивные Корни Единства

11

Позвольте zбыть комплексное число. zявляется n-ым примитивным корнем единства, если для определенного положительного целого числа n и для любого положительного целого числа k < n .

Вызов

Напишите полную программу или функцию, которая, учитывая положительное целое число в nкачестве входных данных, выводит все n-е примитивные корни единства. Вы можете вывести их в полярной форме ( e^θiили e^iθаргумент должен быть десятичным с не менее чем двумя десятичными разрядами) или прямоугольной форме ( a + biили аналогичной форме, действительные и мнимые части также должны быть десятичными), и они могут выводиться в списке вашего языка / формат массива или в виде строки с числами, разделенными пробелами или переводами строки. Встроенные модули, которые вычисляют n-е корни единства или n-е первообразные корни единства, не допускаются.

Это , поэтому выигрывает самый короткий код в байтах.

Образцы входов и выходов

6 -> e^1.05i, e^-1.05i # polar form
3 -> e^2.094395i, e^-2.094395i # any number of decimal places is OK as long as there are more than 2
8 -> 0.707 + 0.707i, 0.707 - 0.707i, -0.707 + 0.707i, -0.707 - 0.707i # rectangular form
1 -> 1 + 0i # this is OK
1 -> 1 # this is also OK
4 -> 0 + i, 0 - i # this is OK
4 -> i, -i # this is also OK
спагетто
источник
Так что + -i не является решением z ^ 8 = 1?
РосЛюП

Ответы:

9

Желе, 11 9 байт

Спасибо @Dennis за -2 байта!

Rg=1O÷H-*

Я хотел сгенерировать числа, взаимно простые с N, сложив разность множеств по всем корням единицы от 1 до N, но я не мог понять, как именно так я использовал метод @ Dennis.

Rg=1O÷H-*         Monadic chain:          6
R                 Range                   [1,2,3,4,5,6]
 g                Hook gcds with range    [1,2,3,2,1,6]
  =1              [gcds equal to one]     [1,0,0,0,1,0]
    O             Replicate indices       [1,5]
     ÷H           Divide by half of N     [1/3,5/3]
       -          Numeric literal: - by itself is -1.
        *         Take -1 to those powers [cis π/3,cis 5π/3]

Попробуй это здесь . Действительно в этой версии Jelly, но может отсутствовать в версиях после 1 февраля 2016 г.

lirtosiast
источник
4

Желе , 14 байт

Rg=1O°÷×ı360Æe

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

Как это работает

z = e 2tπi является n- м корнем 1 тогда и только тогда, когда t = k / n для некоторого целого числа k .

г является примитивным тогда и только тогда , когда к и п взаимно просты.

Rg=1O°÷×ı360Æe  Main link. Input: n

R               Yield [1, ..., n].
 g              Compute the GCDs of reach integer and n.
  =1            Compare the GCDs with 1.
    O           Get all indices of 1's.
                This computes all the list of all k in [1, ..., n] 
                such that k and n are coprime.
     °          Convert the integers to radians.
      ÷         Divide the results by n.
       ×ı360    Multiply the quotient by the imaginary number 360i.
            Æe  Map exp over the results.
Деннис
источник
2

Юлия, 48 байт

n->cis(360deg2rad(filter(k->gcd(k,n)<2,1:n))/n)

Это лямбда-функция, которая принимает целое число и возвращает массив сложных чисел с плавающей точкой. Чтобы вызвать его, присвойте его переменной. Он использует тот же подход, что и ответ Денниса «Желе».

Ungolfed:

function f(n::Int)
    # Get the set of all k < n : gcd(k,n) = 1
    K = filter(k -> gcd(k,n) < 2, 1:n)

    # Convert these to radian measures
    θ = deg2rad(K)

    # Multiply by 360, divide by n
    θ = 360 * θ / n

    # Compute e^iz for all elements z of θ
    return cis(θ)
end
Алекс А.
источник
2

Рубин, 46 байт

Это не «язык игры в гольф» реализации ответа Желе Томаса Ква .

->n{(1..n).map{|j|1i**(4.0*j/n)if j.gcd(n)<2}}

Ungolfed:

def r(n)
  (1..n).each do |j|
    if j.gcd(n) == 1    # if j is coprime with n, then this will be a primitive root of unity
      p 1i**(4.0*j/n)   # print the fourth power of i**(j/n), i.e. the root of unity
    end
  end
end
Sherlock9
источник
2

MATL , 27 байт

:1-tGYf1X-!\Xpg)2j*YP*G/Ze!

Использует релиз (9.3.1) , который является более ранним, чем этот вызов.

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

(Онлайн-компилятор использует более новую версию, но код запускается в версии 9.3.1 и дает тот же результат)

объяснение

Есть три основных шага:

  1. Генерировать целые числа 0, 1, ..., N-1, соответствующие всем корням.
  2. Оставьте только целые числа, соответствующие примитивным корням. Они идентифицируются с использованием разложения по основным факторам N.
  3. Генерация фактических корней с мнимой экспоненциальной.

Код:

:1-           % 1. Implicit input "N". Produce vector [0,1,...,N-1]
t             %    duplicate
GYf           % 2. Prime factors of N
1X-           %    remove factor "1" if present (only if N==1)
!\            %    all combinations of [0,1,...,N-1] modulo prime factors of N
Xpg           %    logical "and" along the prime-factor dimension
)             %    index into original vector [0,1,...,N-1] to keep only primitive roots
2j*YP*G/Ze    % 3. Imaginary exponential to produce those roots
!             %    transpose for better output format
Луис Мендо
источник
1

Matlab 49 байт

n=input('');q=0:n-1;exp(i*2*pi/n.*q(gcd(n,q)==1))

Не получил задание в первый раз, но теперь вот оно. Выходы следующие:

6
ans =
    0.5000 + 0.8660i   0.5000 - 0.8660i
brainkz
источник
3
Ваш ответ отображает все корни единства, а не только примитивные .
flawr
@flawr спасибо за замечание, сначала я не получил задание. Я отредактировал решение
brainkz
1

ES6, 96 байт

n=>[...Array(n).keys()].filter(i=>g(i,n)<2,g=(a,b)=>a?g(b%a,a):b).map(i=>'e^'+Math.PI*2*i/n+'i')

Полярная форма была самым коротким выходом.

Нил
источник
1

PARI / GP, 41 байт

Довольно просто: найдите числа от 1 до n, которые взаимно просты с n, затем

n->[exp(2*Pi*I*m/n)|m<-[1..n],gcd(n,m)<2]

Должен быть какой-то более короткий путь, но это было лучшее, что я мог найти.

Чарльз
источник