Коприми до N


51

Враховуючи число n >= 2, виведіть усі натуральні числа менше, ніж nде gcd(n, k) == 1kбудь-яким з вихідних чисел). Числа такого роду є спільними для одне одного.

Приклад: 10дає результат [1, 3, 7, 9](у будь-якій формі, яка вам подобається, якщо числа однозначно розділені і є в якомусь списку). У списку не може бути повторюваних записів і їх не потрібно сортувати.

Більше тестових випадків:

2 -> [1]
3 -> [1, 2]
6 -> [1, 5]
10 -> [1, 3, 7, 9]
20 -> [1, 3, 7, 9, 11, 13, 17, 19]
25 -> [1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22, 23, 24]
30 -> [1, 7, 11, 13, 17, 19, 23, 29]

Ми також не враховуємо числа, nякі є копрієм n, тільки тому, що я впевнений, що існує нескінченне рішення.

Також зверніть увагу: Числа, які є спільними для одне одного, також вважаються відносно простими або взаємно простими один для одного.


Чи розглядаються окремі рядки (наприклад 1\n3\n) як дійсний вихід?
devRicher

@devRicher, яка працює, звичайно.
Rɪᴋᴇʀ

Інтуїція про те, що існує нескінченна кількість чисел вище n, які є одночасними до n, мені здається правильною. Існує нескінченно багато праймів, і прем'єр буде одночасно з кожним номером під ним. Отже, кожен простір, більший за n (яких існує нескінченно багато), також є частиною списку копрів.
Брайан J

@BrianJ Не тільки це. Якщо c і n - coprimes, c + kn і n - також coprimes, для всіх цілих чисел k .
Денніс

1
Веселий факт: це називаються тотативами .
Wojowu

Відповіді:


17

Желе , 3 байти

gÐṂ

Спробуйте в Інтернеті!

Як це працює?

gÐṂ - (Монадік) Повна програма.

g - Найбільший загальний дільник.
 ÐṂ - Зберігайте елементи з мінімальним значенням посилання (тобто, з GCD == 1)
       Зауважте, що це автоматично створює діапазон [1, вхід] (включно).

Доказ дійсності

Оскільки ми хочемо витягнути лише копії, мінімальне значення списку «Найбільших-загальних-дільників» має бути 1, щоб ÐṂтрюк працював. Доведемо, що (двома різними методами):

  1. [1,input]1gcd(1,x)=1xZ1

  2. Два послідовних натуральних числа завжди є першочерговими. Розглянемо , при . Тоді беремо ще одне додатне ціле число таке, що і .x,yZy=x+1kkxky

    Звідси випливає, що , так , таким чином . Єдине додатне ціле число для поділу - саме , тому воно гарантовано відображатиметься у списку і завжди буде мінімальним значенням.k ( x + 1 - x ) k 1 1 1k(yx)k(x+1x)k111


2
Ви перемогли Денніса своєю мовою через 9 місяців!
Adám

@ Adám Я не впевнений, чи ÐṂіснував тоді, все одно я цим задоволений.
Містер Xcoder

2
Для запису DṂвона існувала, але вона працювала лише для монад. Комміт реалізовані Þ, ÐṂ, ÐṀдля двійок датується 9 травня 2017 року
Dennis

@Dennis Я знав, що буде вагома причина, чому у вас не було 3-байтової версії. Нам теж було цікаво про це в чаті, тож дякую за корисну інформацію!
Містер Xcoder

56

Python 2 , 61 47 байт

lambda n:[k/n for k in range(n*n)if k/n*k%n==1]

Спробуйте в Інтернеті!

Фон

Розглянемо кільце . Хоча це кільце зазвичай визначається за допомогою модулів n залишків класів , його також можна розглядати як набір Z n = { 0 , , n - 1 } , де оператори додавання та множення визначаються а + n b = ( a + б )(Zn,+n,n)nZn={0,,n1} і a n b = a ba+nb=(a+b)%n , де + ,anb=ab%n позначають звичайні оператори додавання, множення та модуля для цілих чисел.+,, and %

Два елементи і б з Z п називаються взаємні мультиплікативні інверсій по модулю п , якщо на п Ь = 1abZnn . Зауважимо, що 1anb=1%n коли n > 1 .1%n=1n>1

Виправте і нехай a є копрієм n у Z n . Якщо на п х = а л у для двох елементів х і у з Z п , ми маємо , що хn>1anZnanx=anyxyZn . Звідси випливає, що a ( x - y )ax%n=ay%n , і випливає, що n a ( x - y ) , тобто n ділить a ( x - y ) рівномірно. Оскільки n не ділиться з простими дільниками на a , це означає, що n x - y . Нарешті, оскільки - n < x - y < n , робимо висновок, що x = y . Це показує, що продукти a a(xy)%n=ax%nay%n=0na(xy)na(xy)nanxyn<xy<nx=y - всі різні елементи Z n . Оскільки Z n має рівно n елементів, один (і саме один) цих виробів повинен бути рівний 1 , тобтов Z n єунікальне b таке, що a n b = 1 .an0,,an(n1)ZnZnn1 bZnанб=1

І навпаки, виправте і нехай a - елемент Z n, який не є coprime до n . У цьому випадку існує просте p таке, що p a і p n . Якщо визнав мультиплікативний зворотний по модулю п (назвемо його б ), ми б , що п Ь = 1 , що означає , що бн>1аZннppаpнанбанб=1 і, отже, ( a b - 1 )аб%н=1 , тому n a b - 1 . Оскільки p a , то випливає, що p a b . З іншого боку, оскільки p n , ми також випливаємо, що p a b - 1 . Таким чином, p ( a b ) - ( a b - 1 ) = 1(аб-1)%н=аб%н-1=0наб-1pаpабpнpаб-1p(аб)-(аб-1)=1, що суперечить припущенню, що - просте число.p

Це доводить, що наступні твердження еквівалентні, коли .н>1

  • і n - це спірне значення.ан

  • допускає мультиплікативний зворотний модуль n .ан

  • допускаєунікальниймультиплікативний зворотний модуль n .ан

Як це працює

Для кожної пари цілих чисел і b в Z n ціле число k : = a n + b є унікальним; насправді, a і b є коефіцієнтом, а решта k поділена на n , тобто, задавши k , ми можемо відновити a = k / n і b = kабZнк: =ан+бабкнка=к/н , де / позначаєціледілення. Нарешті, оскільки a n - 1 і b n - 1 , k - елемент Z n 2 ; насправді k ( n - 1 ) n + ( n - 1 ) = n 2 - 1 .б=к%н/ан-1бн-1кZн2к(н-1)н+(н-1)=н2-1

Як зазначалося вище, якщо і n є спільними, буде унікальний b такий, що a bанб , тобто буде унікальна k така, що k / n = a і k / n kаб%н=1кк/н=а , такгенерується список буде міститирівно один раз.к/нк%н=(к/н)(к%н)%н=1а

І навпаки, якщо і n не є одночасними, умова k / n kан буде помилковим для всіх значень k таким, що a = k / n , тому створений списокнебудемістити a .к/нк%н=1ка=к/на

Це доводить, що список, який повертається лямбда, буде містити всі -ма копії в Z n рівно один раз.нZн


26
"GCD? Куди ми йдемо, нам не потрібен GCD."
Rɪᴋᴇʀ

1
Вуа. Це все, що я хотів написати, але, мабуть, мені було потрібно 15 символів. Все-таки, уау. Чудова робота.
Ерік Лагергрен

24

Желе , 4 байти

gRỊT

Спробуйте в Інтернеті!

Як це працює

gRỊT  Main link. Argument: n

 R    Range; yield [1, ..., n].
g     Compute the GCD of n and each k in [1, ..., n].
  Ị   Insignificant; return 1 for GCDs less or equal to 1.
   T  Truth; yield the indices of all truthy elements.

33
Кодування в цій мові займає деякіgRỊT
ETHproductions

1
Мені вдалося (ab) використати "мінімальне значення посилання" quick ( ÐṂ), щоб отримати 3 байти .
Містер Xcoder

14

Математика, 25 байт

Range@#~GCD~#~Position~1&

Трохи дивний формат виводу, коли кожен результат обгортається в окремий список, наприклад {{1}, {3}, {7}, {9}}. Якщо це не нормально, у мене є два рішення на 30 байт:

Select[Range[x=#],#~GCD~x<2&]&
#&@@@Range@#~GCD~#~Position~1&

Mathematica насправді є, CoprimeQале це занадто довго.


1
Що Qозначає CoprimeQ?
Conor O'Brien

2
@ ConorO'Brien "питання", я думаю. Усі вбудовані проблеми вирішення закінчуються на Q як EvenQ, PrimeQабо SubsetQ.
Мартін Ендер


10

Пітон, 93 82 74 байт

f=lambda a,b:f(b,a%b)if b else a<2
lambda c:[i for i in range(c)if f(i,c)]

fрекурсивно перевіряє наявність коприм, а друга лямбда створює їх. Виводить список.


7

Власне , 8 байт

;╗R`╜┤`░

Спробуйте в Інтернеті!

Пояснення:

;╗R`╜┤`░
  R`  `░  elements of range(1, n+1) where
;╗  ╜     n and the element
     ┤    are coprime

1
Я вважаю, що ви просто можете це зробити, range(1, n)якщо це економить будь-які байти.
ETHproductions

1
@ETHproductions Це не так. Два варіанти - R( range(1, n+1)) і r( range(n)). Оскільки вони еквівалентні, я вибрав R(оскільки випадково потрапив у блокнот під час написання коду)
Mego

Так, це я зрозумів. Я не бачив інструкції, яка здавалася присвяченою збільшенню, але я подумала, що все-таки була одна
ETHproductions



6

JavaScript (ES6), 64 61 байт

Збережено 3 байти завдяки @ user81655

n=>[...Array(n).keys()].filter(b=>(g=a=>b?g(b,b=a%b):a<2)(n))

Фрагмент тесту

f=n=>[...Array(n).keys()].filter(b=>(g=a=>b?g(b,b=a%b):a<2)(n))

for(var i = 2; i < 50; i++) console.log(i + ":", `[${ f(i) }]`);


Хіба ви не можете поміняти місцями a==з a<2?
Rɪᴋᴇʀ

@EasterlyIrk Не впевнений, aу якийсь момент може бути 0. Мені доведеться перевірити
ETHproductions

Ви можете перемістити функцію GCD у, filterщоб усунути необхідність отримання bпараметра:...keys()].filter(b=>(g=a=>b?g(b,b=a%b):a<2)(n))
user81655

@ user81655 Це чудово, дякую! :-)
ETHproductions

6

Медузи , 19 18 байт

p
[#
`B
&~xr1
NnEi

Це працює, обчислюючи основну факторизацію кожного числа в діапазоні і перевіряючи, чи воно перетинається з вхідним (медузи ще не вбудували gcd). З міркувань гольфу вихідний результат відбувається у порядку зменшення. Спробуйте в Інтернеті!

Пояснення

По-перше, iоцінюється вхід; для введення 10значення i-cell є 10.

r1
i

Тут r(діапазон) застосовується до вводу та 1. Оскільки вхід більший за 1, діапазон знаходиться в порядку зменшення; для введення 10це дає [9 8 7 6 5 4 3 2 1].

[#
`B
&~x
Nn

Ця частина - одна велика функція, яка оцінюється на iта вищенаведеному діапазоні.

~x
n

Перетин ( n) простих факторів ( x).

&~x
Nn

Це порожньо? ( N)

`
&~x
Nn

Нитка до рівня 0, тестуючи для кожного елемента діапазону.

[#
`B
&~x
Nn

Фільтр ( #) діапазон відносно цього списку булевих. Функція, що виробляється, [хоче використовувати аргумент #як власний аргумент, тому ми ставимо Bблок для #отримання будь-яких аргументів. В іншому випадку значення ~-cell буде використано як аргумент великої функції. Нарешті, pдрукується результат.


5

Складене, неконкурентне, 24 21 байт

Збережено 3 байти, навіяні рубіном Борсунго . ( 1 eqдо 2<)

{!n:>1+:n gcd 2<keep}

Спробуйте тут!

Це n-лямбда, який приймає єдиний аргумент і дає масив.

{!n:>1+:n gcd 2<keep}
{!                  }  n-lambda
  n                    push n
   :>                  range [0, n)
     1+                range [1, n]
       :               duplicate
        n gcd          element-wise gcd with n
              2<       element-wise equality with 1
                       this yields the range [1, n] and a boolean mask of coprime numbers
                keep   then, we simply apply the mask to the range and keep coprimes.

Чому це неконкурентоспроможне?
Zacharý

В основному @ZacharyT keepне працював добре.
Conor O'Brien

5

CJam , 14 байт

{:X{Xmff%:*},}

Спробуйте в Інтернеті!

Пояснення

Нам не потрібно перевіряти всі можливі дільники aта bперевіряти, чи є вони копійними. Достатньо розібратися, чи bділиться який-небудь з основних факторів a.

:X     e# Store the input in X.
{      e# Filter the list [0 1 ... X-1] by the results of this block...
  Xmf  e#   Get the prime factors of X.
  f%   e#   Take the current value modulo each of those prime factors.
  :*   e#   Multiply the results. Iff any of them divide the current
       e#   value, there's a 0 in the list, and the result of the product
       e#   is also 0, dropping the value from the resulting list.
},

5

Математика, 26 байт

Pick[r=Range@#,r~GCD~#,1]&

1
Ой, я шукав щось на кшталт Вибору. Я думаю, зараз я радий, що не знайшов. ;) Але це має бути дуже корисним для майбутніх викликів.
Мартін Ендер


4

Брахілог , 16 13 байт

>.$p'(e:A*?),

Це функція, яка приймає N в якості вхідного сигналу і генерує всі цілі числа менше, ніж і одночасно.

Спробуйте в Інтернеті! Як це часто буває в Брахілозі, до цього було додано додатковий код, щоб перетворити функцію на повну програму; Інтерпретатор Брахілогів, якщо йому надана функція, а не повна програма, запустить її, але не надрукує вихід, а це означає, що ви не можете реально спостерігати за його роботою.

Пояснення:

Програма Брахілог - це ланцюжок обмежень; зазвичай LHS одного обмеження є RHS наступного.

>.$p'(e:A*?),
>              The input is greater than
 .             the output, whose
  $p           prime factorisation does
    '(     )   not obey the following constraint:
      e        it has an element which
       :A*     can be multiplied by something to
          ?    produce the input.
            ,  (This comma turns off an unwanted implicit constraint.)

Зіштовхнувшись з трьох символів, зрозумівши, що немає підстав перевіряти, чи є загальний фактор (який, як відомо, є основним фактором виходу), є основним фактором введення. Ми вже знаємо, що це прем'єр, тому ми можемо просто перевірити, чи це фактор. Я приємно здивований, що :A*?не пересилає інтерпретатора в нескінченний цикл і не дозволяє неціле значення для A , але оскільки інтерпретатор робить те, що я хочу, я візьму його.


4

Діалог APL, 10 байт .

0~⍨⍳×1=⊢∨⍳

Пояснення (введення n):

0~⍨⍳×1=⊢∨⍳
         ⍳ - 1 ... n (Thus, ⎕IO is 1)
       ⊢∨  - Each GCD'd by n
     1=    - Test equality with 1 on each element
   ⍳×      - multiplied by its index
0~⍨        - without 0.

3
Мені подобається, як APL-код виглядає як обличчя, яке ви створюєте, коли читаєте його.
DJMcMayhem

Так, і це руйнує майже кожну мову, не орієнтовану на кодекс-гольф. :).
Zacharý

Чому тільки "може" працювати?
Rɪᴋᴇʀ

Я просто припускаю, що це працює.
Zacharý

@ZacharyT, чому ти не можеш її перевірити? Коли я вставляю його на try-apl.org, він помиляється з недійсним маркером.
Rɪᴋᴇʀ

4

Япт -f , 9 8 5 2 байти

jN

Спробуй це

  • 2 байти збережено завдяки ETH вказує на мозковий пір, що призвело до збереження іншого байта.

Ви могли б зробитиo f_jU
ETHproductions

Дякую, @ETHproductions. Не знаю, про що я тут думав! Мабуть, це був один із таких (багатьох) моментів, коли я забуваю, jтакож можна перевірити, чи 2 числа є простими.
Кудлатий

3

Математика, 33 байти

xSelect[Range@x,x~CoprimeQ~#&]

Містить U + F4A1


Що робити недрукованим?
Rɪᴋᴇʀ

3
@EasterlyIrk вводить неназвану функцію з іменованим аргументом. він відображається як стріла в Mma.
Мартін Ендер

@MartinEnder о, круто.
Rɪᴋᴇʀ

U + F4A1 - символ приватного використання. Як сказав Мартін, це відображається як стріла в Mathematica.
Zacharý



3

меми , 11 байтів, що не конкурують , застарілі

Неконкурентна, оскільки ітерація STDIN є новою. Використовує кодування UTF-8.

d`}}]i=1?ip

Пояснення:

d     Set program to not output result
`}    Loop next input-times
}]i   GCD of input and loop index
=1?   Is it equal to 1? If yes,
ip    Print out loop index

}отримує доступ до наступного елемента введення, але останній вхід проходить циклічним шляхом, коли його вводять, тому введення 6буде результатом, як 6 6 6 6 6 ...у STDIN, що робить можливим зчитування двох виходів з одного.


Ви щойно створили цей язик? Якщо він зроблений перед викликом, він повинен бути неконкурентним.
Rɪᴋᴇʀ

@EasterlyIrk Це було зроблено 3 дні тому, я просто постійно працюю над ним. Крім того, я припускаю, ви маєте на увазі після ?
devRicher

Так, друкарські спасибі І це добре, доки функції, які використовуються у відповіді, і старіші, ніж виклик.
Rɪᴋᴇʀ

@EasterlyIrk Я бачу, у такому випадку мені доведеться відредагувати свою відповідь.
devRicher

Так, вибачте. : /
Rɪᴋᴇʀ


2

Рубі, 36 34

->n{n.times{|i|p i if i.gcd(n)<2}}

Справді, це не дуже натхненно відповідь.

2 байти збережено завдяки Conor O'Brien


Ви можете поголити два байти, видаливши круглі дужки навколо(n)
Conor O'Brien

2

Python 3 , 60 байт

Імпортує gcd замість того, щоб написати нову лямбда для нього. Пропозиції з гольфу вітаються. Спробуйте в Інтернеті!

import math
lambda c:[i for i in range(c)if math.gcd(c,i)<2]

Я не думаю, що ти можеш більше це робити в гольф. Імпортує gcd безпосередньо чи математику, оскільки m обидва додають байти.
Rɪᴋᴇʀ

2

Джулія, 30 байт

n->filter(x->(gcd(n,x)<2),1:n)

Анонімна функція. filterвилучає елементи зі списку, які не є правдоподібними відповідно до функції.

У цьому випадку функція є x->(gcd(n,x)<2)(вірно, якщо gcd вводу та елемента списку менше 2). Список - це діапазон 1:n.


2

PARI / GP , 27 байт

n->[k|k<-[1..n],gcd(k,n)<2]

Для цього використовується нотація набору, введена у версії 2.6.0 (2013). У попередніх версіях було потрібно ще чотири байти:

n->select(k->gcd(k,n)<2,[1..n])

знадобиться.


Як це працює?
Rɪᴋᴇʀ

1
@EasterlyIrk Те саме, що і більшість цих подань - зробіть діапазон від 1 до n ( [1..n]), перевірте, чи gcd 1 ( gcd(n,k)<2), поверніть числа з цим властивістю. ->Є функція / закриття нотації, коротше на 2 байта , ніж нормальний синтаксис функції і [...|...<-...,...]є безліч позначення пояснені у відповіді (дивіться розділ 2.3.14 в керівництві користувача, або для пошуку <-).
Чарльз



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.