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


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.