Можно ли сделать этот код C меньше? Распечатывает все простые числа от 0 до 1000.
С, 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);}
Можно ли сделать этот код C меньше? Распечатывает все простые числа от 0 до 1000.
С, 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);}
Ответы:
59 57 байт
На основе решения @feersum, но проверка первичности может быть продолжена
for(int p=1,d;d=p++%999;d||printf("%d\n",p))for(;p%d--;);
Отредактировано на основе комментариев Runer112
d=p++%999
. В остальном это выглядит довольно герметично для игры в гольф!
(Я написал это, не осознавая ограничений на размер целых чисел в 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. Но это идеи, которые вы должны попробовать, прежде чем остановиться на куске кода, чтобы начать набирать символы.
int
s 32-битные. То же самое касается Ферма.
fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }
то результат не будет переполнен 32-битным целым числом даже для довольно больших значений n
. ( m
это модуль)
(n*fact(n-1,m)) % m
. Что подчеркивает проблему: вы не можете избежать рекурсии в реализации, fact
потому что m
она будет отличаться для каждой итерации внешнего цикла.
Еще одно повторное использование моего ответа на аналогичный вопрос .
РЕДАКТИРОВАТЬ : автономный кусок кода, нет функции для вызова.
for(int m,n=2;n<999;m>1?m=n%m--?m:n++:printf("%d\n",m=n));
Полная программа:
n=2;main(m){n<999&&main(m<2?printf("%d\n",n),n:n%m?m-1:n++);}
Вдохновленный решением Алхимика:
int i=1,p;for(;i++<1e3;p-i||printf("%d\n",i)){p=1;while(i%++p);}