Можно ли сделать этот код 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. Но это идеи, которые вы должны попробовать, прежде чем остановиться на куске кода, чтобы начать набирать символы.
ints 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);}