Підрахунок ланцюгів Каннінгам


14

Прості номери завжди заворожували людей. 2300 років тому Евклід писав у своїх "Елементах"

Просте число - це те, що вимірюється лише одиницею.

що означає, що прайм ділиться лише на 1 (або сам по собі).

Люди завжди шукали відносини між простими числами і придумували якісь дивні (як у "цікавих") речі.

Наприклад, прем'єра Софі Жермен - це прем'єр pдля якої2*p+1 також є прем'єр.

Безпечний прем'єр є головним , pдля якого(p-1)/2 також простий, що саме умови назад штриха Софі Жермен.

Вони пов'язані з тим, що ми шукаємо в цьому виклику.

Cunningham ланцюг типу I являє собою ряд простих чисел, де кожен елемент , за винятком останнього, являє собою просте Sophie Germain , і кожен елемент , крім першого є безпечним прем'єр . Кількість елементів цього ланцюга називається довжиною .

Це означає, що ми починаємо з простого pі обчислюємо q=2*p+1. Якщо qце теж прем'єр, у нас є ланцюг Куннігем типу I довжиною 2. Потім ми тестуємо2*q+1 і так далі, поки наступне згенероване число не буде складене.

Ланцюги Каннінгама типу II побудовані за таким же принципом, різницею є лише те, що ми перевіряємо2*p-1 на кожному етапі.

Ланцюги Каннінгама можуть мати довжину 1 , а це означає, що ні 2 * p + 1, ні 2 * p-1 не є простими. Нас це не цікавить .

Деякі приклади ланцюжків Каннінгама

2запускає ланцюг типу I довжиною 5.

2, 5, 11, 23, 47

Наступним побудованим числом буде те, 95що не є простим.
Це також говорить нам, що 5, 11, 23і 47не починати будь-яку ланцюг типу I , так як він буде мати попередні елементи.

2також запускає ланцюг типу II довжиною 3.

2, 3, 5

Далі буде 9, що не є головним.

Спробуємо 11для II типу (раніше ми його виключили з I типу ).
Ну, 21було б наступне, що не є першочерговим, тому ми мали б довжину 1 для того "ланцюжка", який ми не враховуємо в цьому виклику.

Виклик

Написати програму або функцію , що, з огляду на число в nякості вхідних, записи / повертає вихідний номер п - й Cunningham ланцюга типу I або II , по меншій мірі , довжини 2 , з подальшим пропуском, а потім за типом ланцюга вона починається ( я або II ), за яким слідує двокрапка, а потім довжина ланцюга цього типу. У випадку, коли прайм запускає обидва типи ланцюгів (тип I і тип II), ланцюг типу I рахується першим.

Приклад: 2 I:5

Майте на увазі, що це nможе бути частиною раніше запущеної ланцюга будь-якого типу, і в цьому випадку це не повинно вважатися початковим номером ланцюга цього типу.

Давайте розглянемо, як це починається

Почнемо з 2. Оскільки це взагалі перший прайм, ми можемо бути впевнені, що немає ланцюга, починаючи з нижнього простого шару, який містить 2.
Наступним номером у ланцюжку типу I був би 2*2+1 == 5. 5є простим, тому у нас є ланцюжок принаймні довжиною 2.
Ми вважаємо це першим ланцюжком. А як щодо II типу? Наступний номер буде 2*2-1 == 3. 3є простим, тому ланцюжок принаймні довжиною 2 для типу II теж.
Ми вважаємо це другим ланцюгом. І ми зробили для 2.

Наступний прем'єр - це 3. Тут ми повинні перевірити, чи не в ланцюжку починається нижній прайм.
Перевірте тип I: (3-1)/2 == 1. 1не є простим, тому 3 може бути відправною точкою для ланцюга типу I.
Перевіримо це. Далі буде 3*2+1 == 7.7є простим, тому у нас є ланцюг типу I принаймні довжини 2. Ми вважаємо це третім ланцюгом.
Тепер ми перевіряємо, чи 3з'являється в ланцюзі типу II, що запустився нижній прайм. (3+1)/2 == 2. 2є простим, тому 3 не можна вважати вихідним номером для ланцюга типу II. Тож це не рахується, навіть якщо наступне число після 3цього ланцюга, яке було б5, є простим. (Ми, звичайно, це вже знали, і ви можете і повинні, звичайно, думати про свій власний метод, як зробити ці перевірки.)

І тому ми перевіряємо на для 5, 7, 11і так далі, підрахунку голосів , поки ми не знайдемо п - й Cunningham ланцюга , щонайменше , довжиною 2.

Тоді (або, можливо, на деякий час раніше ;)) нам потрібно визначити повну довжину знайденого нами ланцюжка і роздрукувати результат у раніше згаданому форматі.

До речі: у своїх тестах я ще не знайшов жодної прем'єри 2 що запускав обидва типи ланцюгів довжиною більше, ніж 1.

Приклади введення / виводу

Вхідні дані

1

Вихідні дані

2 I:5


Вхідні дані

10

Вихідні дані

79 II:3


Вхідні дані

99

Вихідні дані

2129 I:2


Виходи для входів 1..20

2 I: 5
2 II: 3
3 I: 2
7 II: 2
19 II: 3
29 I: 2
31 II: 2
41 I: 3
53 I: 2
79 II: 3
89 I: 6
97 II: 2
113 I: 2
131 І: 2
139 II: 2
173 I: 2
191 I: 2
199 II: 2
211 ІІ: 2
229 II: 2

Список перших 5000 виходів можна знайти тут .

Це код гольфу. Довільний пробіл дозволений у висновку, але тип і числа повинні бути відокремлені одним пробілом і двокрапкою, як показано в прикладах. Використання будь-яких лазівки не дозволено, особливо отримання результатів в Інтернеті не дозволяє дозволяється.

Удачі :)


3
Забув згадати у пісочниці: легко довести, що це 2і 3є єдиними праймерами, pдля яких обидва 2p-1і 2p+1є праймерами, так 2це єдиний прайм, який запускає нетривіальні ланцюги Кеннінгема обох типів.
— Пітер Тейлор

Добре. Дякуємо за допомогу:)
— Cabbie407

3
(Перетворений коментар від відповіді.) Там немає якихось - або інші , ніж прості чисел 2з подвійною довжиною ланцюга більше 1. Ось доказ по ліквідації.
— pbeentje

Добре дякую, що ще раз детально вказали на це. Ви просто хотіли зауважити це чи вважаєте, що я повинен якось змінити виклик через це?
— Cabbie407

Лише зауваження. Я не думаю, що це змінює виклик в будь-якому випадку, лише потенційно корисний для гольфу: коли одна ланцюжок знайдена, іншу не потрібно перевіряти.
— pbeentje

Відповіді:


2

Javascript, 236 208 байт

Збережено 28 байт:

p=(n,i=n)=>n%--i?p(n,i):i==1;f=n=>{for(k=2,c=0;c<n;k++){p(k)&&!p((k-1)/2)&&p(2*k+1)&&(c++,l=1,r='');p(k)&&c-n&&!p((k+1)/2)&&p(2*k-1)&&(c++,l=-1,r='I');};alert(--k+` I${r}:`+eval(`for(j=1;p(k=2*k+l);j++);j`))}

Збережені 9 байт на pфункцію з: p=(n,i=n)=>n%--i?p(n,i):i==1
The tфункцією були замінені eval(...)заявою безпосередньо в fфункції.


Попереднє рішення:

p=n=>{for(i=n;n%--i&&i;);return 1==i};t=(n,m)=>{for(j=1;p(n=2*n+m);j++);return j};f=n=>{for(k=2,c=0;c<n;k++){p(k)&&!p((k-1)/2)&&p(2*k+1)&&(c++,l=1,r='');p(k)&&c-n&&!p((k+1)/2)&&p(2*k-1)&&(c++,l=-1,r='I');};alert(--k+` I${r}:${t(k,l)}`)}

Приклад: f(6)

Вихід: 29 I:2

Пояснення
Я використовую 3 функції

1 p : знати, чи n є простим: p=n=>{for(i=n;n%--i&&i;);return 1==i}

2 т : знати довжину ланцюга Каннінгама, починаючи з n типу I або II, залежно від m параметра, який буде 1 або -1: t=(n,m)=>{for(j=1;p(n=2*n+m);j++);return j}

3 f : підраховує ланцюги ( для циклу ), а потім відображає результат

f=n=>{for(k=2,c=0;c<n;k++){p(k)&&!p((k-1)/2)&&p(2*k+1)&&(c++,l=1,r='');p(k)&&c-n&&!p((k+1)/2)&&p(2*k-1)&&(c++,l=-1,r='I');};alert(--k+` I${r}:${t(k,l)}`)}

для циклу : для кожного номера ланцюг Каннінгема (я тоді II, якщо потрібно) дійсний, якщо

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