Всі праймери від 0 до 1000


9

Чи можна зробити цей код С меншим? Він друкує всі праймери від 0 до 1000.

C, 89 символів

int i,p,c;for(i=2;i<1e3;i++){c=0;for(p=2;p<i;p++)if(i%p==0)c++;if(c==0)printf("%u\n",i);}

6
Тільки для того, щоб попередньо зняти деякі підказки "Ми не хочемо конкретних мовних викликів", прохання допомогти розіграти якийсь код - це тема, що відрізняється від проблем.
Мартін Ендер

4
Чи потрібно зберігати алгоритм чи лише кінцевий результат?
Іван Дворак

Я почав би я в 2 строго точно, оскільки це друкує 0 і 1.
гістократ

ви намагаєтеся змусити код виконувати швидше чи намагаєтесь використовувати менше символів у вихідному коді?
користувач3629249

1
Оскільки ви просите допомоги з гольфом, було б корисно включити в свій пост кількість символів вашого поточного рішення (я роблю це як 89).
Марк Рід

Відповіді:


7

59 57 байт

На основі рішення @feersum, але перевірку первинності можна додатково програти в гольф

for(int p=1,d;d=p++%999;d||printf("%d\n",p))for(;p%d--;);

Відредаговано на основі коментарів Runer112


2
Пов'язана перевірка може бути golfed трохи більше: d=p++%999. Інакше це виглядає досить герметичною роботою з гольфу!
Runer112

10

67 байт

У C немає реальної альтернативи пробному поділу, але, безумовно, можна трохи пограти в гольф.

for(int p=1,d;p++<999;d&&printf("%d\n",p))for(d=p;--d>1;)d=p%d?d:1;

Потрібні початкові декларації C99, що дозволяє економити 1 байт.


6

(Я написав це, не розуміючи обмеження розміру на цілі числа в C, тому, ймовірно, це не корисно для скорочення коду.)

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

Ви перевірка простоти, виконавши пробне розподіл - тестування кожен потенційний дільника pз i. Це дорого коштує в символах, оскільки для цього потрібно дві петлі. Отже, тестування первинності без циклу, ймовірно, врятує символів.

Часто коротший підхід полягає у використанні теореми Вілсона : число nє простим, якщо і лише тоді

fact(n-1)%n == n-1

де factфункціональна функція. Оскільки ви протестуєте все можливе nвід 1до 1000, легко уникнути впровадження факториуму, відстежуючи запущений продукт Pта оновлюючи його P*=nпісля кожного циклу. Ось реалізація цієї стратегії Python для друку простих розмірів до мільйона.

Крім того, той факт, що у вашій програмі має бути до 1000, відкриває ще одну стратегію: тест перманентності Ферма . Для деяких aкожен прем'єр nзадовольняє

pow(a,n-1)%n == 1

На жаль, деякі композити nтакож для деяких проходять цей тест a. Вони називаються псевдокринами Ферма . Але, a=2і a=3не провалюйтесь разом n=1105, поки їх вистачить для вашої мети перевірки простих ліній до 1000. (Якщо 1000 замість цього 100, ви можете використовувати лише це a=2.) Отже, ми перевіряємо примітивність за допомогою (невиявленого коду)

pow(2,n-1)%n == 1 and pow(3,n-1)%n == 1

Це також не вдається розпізнати прості 2 і 3, тому їх потрібно було б застосувати до спеціальних обставин.

Чи ці підходи коротші? Я не знаю, тому що я не кодую в C. Але це ідеї, які слід спробувати, перш ніж влаштуватися на шматок коду, щоб почати виписувати символи.


1
Теорема Вілсона не є корисною для C, оскільки ints є 32-розрядною. Те саме стосується і Ферма.
feersum

@feersum Ой, стріляй. Це теж проблема для фабрикантів. Чи існує тип big-int?
xnor

@xnor Не вбудований.
Мартін Ендер

1
якщо визначити, fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }результат не переллє 32-бітове ціле число для навіть досить великих значень n. ( mє модуль)
apnorton

@anorton Я думаю, ти маєш на увазі (n*fact(n-1,m)) % m. Що підкреслює проблему: ви не можете уникнути рекурсії при здійсненні, factоскільки mвона буде різною для кожної ітерації зовнішньої петлі.
hvd

4

78 77 символів

(Просто застосуйте деякі хитрощі, вивчені іншими мовами.)

int i=0,p,c;for(;i<1e3;i++){c=0;for(p=2;p<i;)c+=i%p++<1;c||printf("%u\n",i);}

76 символів в режимі C99

for(int i=0,p,c;i<1e3;i++){c=0;for(p=2;p<i;)c+=i%p++<1;c||printf("%u\n",i);}


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