(Я написал это, не осознавая ограничений на размер целых чисел в 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. Но это идеи, которые вы должны попробовать, прежде чем остановиться на куске кода, чтобы начать набирать символы.
Теорема Уилсона бесполезна в 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);}
Ответы:
5957 байтНа основе решения @feersum, но проверка первичности может быть продолжена
Отредактировано на основе комментариев Runer112
источник
d=p++%999
. В остальном это выглядит довольно герметично для игры в гольф!67 байт
В Си нет реальной альтернативы пробному делению, но это, безусловно, можно немного поиграть в гольф.
Требуется начальное объявление C99, что экономит 1 байт.
источник
(Я написал это, не осознавая ограничений на размер целых чисел в C, так что, скорее всего, это не очень полезно для сокращения кода.)
Сначала пару слов об алгоритме. Перед тем, как сыграть в свой код, вы должны подумать о наилучшей общей стратегии, чтобы получить результат.
Вы проверка простоты, выполнив пробное деление - тестирование каждый потенциальный делителя
p
изi
. Это дорого в символах, потому что это занимает два цикла. Таким образом, тестирование простоты без цикла может спасти символы.Часто более короткий подход заключается в использовании теоремы Вильсона : число
n
является простым тогда и только тогда, когдагде
fact
- факториальная функция Поскольку вы тестируете все возможноеn
от и1
до1000
, легко избежать внедрения факториала, отслеживая работающий продуктP
и обновляя егоP*=n
после каждого цикла. Вот реализация этой стратегии на Python для печати простых чисел до миллиона.С другой стороны, тот факт, что ваша программа должна быть только до 1000, открывает другую стратегию: тест первичности Ферма . Для некоторых
a
каждое простое числоn
удовлетворяетК сожалению, некоторые композиты
n
также проходят этот тест для некоторыхa
. Это псевдопричины Ферма . Ноa=2
иa=3
не терпите неудачу вместе до тех порn=1105
, пока их не будет достаточно для проверки простых чисел до 1000. (Если бы вместо 1000 использовалось 100, вы могли бы использовать толькоa=2
.) Итак, мы проверяем простоту с помощью (кода без ключа)Это также не может распознать простые числа 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
она будет отличаться для каждой итерации внешнего цикла.7877 символов(Просто применил некоторые трюки, изученные на других языках.)
76 символов в режиме C99
источник
58 символов (или 61 для полной программы)
Еще одно повторное использование моего ответа на аналогичный вопрос .
РЕДАКТИРОВАТЬ : автономный кусок кода, нет функции для вызова.
Полная программа:
источник
6764 байтаВдохновленный решением Алхимика:
источник