Примери числа з простим індексом


13

Напишіть програму або функцію, яка виводить / повертає перші 10000 простих індексованих простих чисел.

Якщо ми називаємо n- м простим p(n), цей список є

3, 5, 11, 17, 31, 41, 59 ... 1366661

тому що

p(p(1)) = p(2) = 3
p(p(2)) = p(3) = 5
p(p(3)) = p(5) = 11
p(p(4)) = p(7) = 17
...
p(p(10000)) = p(104729) = 1366661

Стандартні лазівки заборонені, а стандартні методи виведення дозволені. Ви можете відповісти за допомогою повної програми, іменованої функції або анонімної функції.


2
Як правило, слід спробувати опублікувати виклики в пісочниці спочатку (див. Посилання праворуч), щоб вирішити проблеми.
aditsu кинути, тому що SE - EVIL

6
Оптимізація для виконання - це не те, що ми робимо в коді-гольфі; найкоротша програма завжди виграє.
lirtosiast

1
Прайми з простими підписками: A006450 .

1
@bilbo Відповіді на код гольфу зазвичай приймаються через тиждень, і їх слід сприймати як найкоротший успішний код. Якщо ви хотіли швидкості коду , для цього є тег. Дивіться цю сторінку про тег-код-гольф .
Аддісон Кримп

1
Усі змагання потребують об'єктивного критерію виграшу; інакше вони поза темою. Якщо ви збираєтеся судити відповіді за розміром і швидкістю, вам потрібно розкрити спосіб поєднання обох. Це слід зробити, коли конкурс розміщений, а не через 14 годин та 10 відповідей пізніше. Я скасував усі зміни, пов’язані зі швидкістю, оскільки єдиним іншим варіантом було б закрити цю публікацію, оскільки вона була поза темою.
Денніс

Відповіді:



9

Пітон, 72 байти

P=p=1;l=[]
while p<82e5/6:l+=P%p*[p];P*=p*p;p+=1
for x in l:print l[x-1]

Після закінчення друку 10000 номерів це завершується "помилковим індексом поза діапазоном", який дозволено за замовчуванням .

Використовує метод теореми Вілсона для створення спискуl простих чисел до 10000-го простого. Потім друкується праймес із позиціями у списку, зміщеними на 1 для нульової індексації, поки ми не вичерпаємо меж після 10000-го найвищого рівня.

Зручно, що верхню межу 1366661можна оцінити, 82e5/6яка є 1366666.6666666667, економивши знак.

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

P=p=1;l=[]
while p<104730:
 l+=P%p*[p]
 if len(l)in P%p*l:print p
 P*=p*p;p+=1

Це набагато краще, ніж сміття, про яке я писав. +1
Мего

Це тільки друкує 1229 номерів
aditsu quit тому, що SE - EVIL

@aditsu Я думаю, що бачу свою помилку. Чи можете ви запустити цей код із більшою межею?
xnor

Мабуть, це займе багато часу: p
aditsu quit тому, що SE - EVIL

Я думаю, це закінчилося \ (@ ; ◇ ; @) /, це здається правильним
aditsu кинь, тому що SE - EVIL

8

J, 11 байт

p:<:p:i.1e4

Виводить праймери у форматі

3 5 11 17 31 41 59 67 83 109 127 ...

Пояснення

        1e4  Fancy name for 10000
      i.     Integers from 0 to 9999
    p:       Index into primes: this gives 2 3 5 7 11 ...
  <:         Decrement each prime (J arrays are 0-based)
p:           Index into primes again

4

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

Prime@Prime@Range@1*^4&

Чиста функція, що повертає список.


1
Prime Listableтак просто Prime@Prime@Range@1*^4&зробити

Я знаю почуття ... У будь-якому випадку, я думаю, що це найкрасивіше рішення Mathematica, яке я бачив тут!

Дозвольте здогадатися, @оператор має більшу перевагу, ніж ^при написанні Range@10^4? Це класична Mathematica зіпсує вашу гру в гольф. Гарний трюк!

4

Haskell, 65 байт

p=[x|x<-[2..],all((>0).mod x)[2..x-1]]
f=take 10000$map((0:p)!!)p

Виходи: [3,5,11,17,31,41,59,67,83,109,127.....<five hours later>...,1366661]

Не дуже швидко. Як це працює: pце нескінченний список прайметів (наївно перевіряючи всі mod x ys на y in [2..x-1]). Візьміть перші 10000елементи списку, який ви отримаєте, коли 0:p!!(get n-й елемент p) відображено p. Я повинен коригувати список простих чисел, з яких я беру елементи, попередньо додавши одне число (-> 0:), оскільки функція індексу ( !!) заснована на нулі.



3

AWK - 129 байт

... oookay ... занадто довго, щоб виграти очки за компактність ... але, можливо, це може отримати певну честь за швидкість?

xфайл:

BEGIN{n=2;i=0;while(n<1366662){if(n in L){p=L[n];del L[n]}else{P[p=n]=++i;if(i in P)print n}j=n+p;while(j in L)j=j+p;L[j]=p;n++}}

Запуск:

$ awk -f x | nl | tail
  9991  1365913
  9992  1365983
  9993  1366019
  9994  1366187
  9995  1366327
  9996  1366433
  9997  1366483
  9998  1366531
  9999  1366609
 10000  1366661

Читає:

BEGIN {
        n=2
        i=0
        while( n<1366662 ) {
                if( n in L ) {
                        p=L[n]
                        del L[n]
                } else {
                        P[p=n]=++i
                        if( i in P ) print n
                }
                j=n+p
                while( j in L ) j=j+p
                L[j]=p
                n++
        }
}

Програма обчислює потік праймерів, використовуючи Lяк «стрічку чисел», утримуючи знайдені прайми, що стрибають, Lщоб позначити довколишні числа, для яких, як відомо, дільник. Ці стрибкові праймери будуть просуватися в той час, коли "стрічка чисел" Lвідсікається числом за номером від початку.

Хоча відрізати голову стрічки L[n]порожньою означає, що немає відомого (основного) дільника.

L[n]утримуючи значення означає, що це значення є простим і відомим для поділу n.

Таким чином, або ми знайшли головний дільник, або новий простір. Тоді цей прем'єр буде перенесений на наступний L[n+m*p]на стрічці, яка виявиться порожньою.

Це схоже на сито Ератосфена, "витягнувши пляшку Клейна". Ви завжди дієте на стрічковому старті. Замість стрільби декількох праймів через стрічку, ви використовуєте прайми, які вже знайдені, як курсори, що відскакують від стрічки, починаються на декількох відстанях власного значення, поки не знайдеться вільна позиція.

У той час як зовнішній цикл генерує одне просте чи не перше рішення за цикл, знайдені прайми підраховуються та зберігаються в Pякості ключа, значення цієї пари (ключ, значення) не є актуальним для потоку програми.

Якщо їх ключ iвиявляється у Pвже ( i in P), у нас є простір породи p (p (i)).

Запуск:

$ time awk -f x.awk | wc -l
10000

real    0m3.675s
user    0m3.612s
sys     0m0.052s

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

Час зайняв мій старий добрий Thinkpad T60, тому я думаю, що його заслуговують на те, щоб викликати його швидко.

Тестовано з mawkі gawkна Debian8 / AMD64


хороші 129 байт у gawk: зараз із Debian10 / AMD64 на моєму corei7-i870@3.6 ГГц: реальний користувач 0m2,417s 0m2,205s sys 0m0,042s
JeanClaudeDaudin

ви можете зберегти один байт за допомогою: BEGIN {n = 2; i = 0; while (n <1366662) {if (n in L) {p = L [n]; del L [n]} else {P [p = n] = ++ i; якщо (i в P) надрукувати n} j = n + p; в той час як (j в L) j + = p; L [j] = p; n ++}}
JeanClaudeDaudin


1

Perl, 55 байт

use ntheory':all';forprimes{print nth_prime$_,$/}104729

Використання @DanaJ «и Math::Prime::Utilмодуль для Perl (завантажується з Прагма ntheory). Отримайте його за допомогою:

cpan install Math::Prime::Util
cpan install Math::Prime::Util::GMP

0

05AB1E, 7 байт (неконкурентоспроможний)

Код:

4°L<Ø<Ø

Спробуйте в Інтернеті! , зверніть увагу, що я змінив 4на 2. Якщо у вас багато часу, ви можете змінити 2спинку 4, але це займе багато часу. Мені потрібно закріпити алгоритм для цього.

Пояснення:

4°       # Push 10000 (10 ^ 4)
  L      # Create the list [1 ... 10000]
   <     # Decrement on every element, [0 ... 9999]
    Ø    # Compute the nth prime
     <   # Decrement on every element
      Ø  # Compute the nth prime
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.