Ваша цель - определить, является ли данное число n
простым в наименьшем количестве байтов. Но ваш код должен быть одним выражением Python 2 для чисел, состоящих только из
- операторы
- входная переменная
n
- целочисленные константы
- скобки
Нет циклов, нет присваиваний, нет встроенных функций, только то, что перечислено выше. Да, это возможно.
операторы
Вот список всех операторов в Python 2 , которые включают арифметические, побитовые и логические операторы:
+ adddition
- minus or unary negation
* multiplication
** exponentiation, only with non-negative exponent
/ floor division
% modulo
<< bit shift left
>> bit shift right
& bitwise and
| bitwise or
^ bitwise xor
~ bitwise not
< less than
> greater than
<= less than or equals
>= greater than or equals
== equals
!= does not equal
Все промежуточные значения являются целыми числами (или False / True, что неявно равно 0 и 1). Возведение в степень не может использоваться с отрицательными показателями, поскольку это может привести к плавающим эффектам. Обратите внимание, что /
делает разделение по полу, в отличие от Python 3, поэтому //
не требуется.
Даже если вы не знакомы с Python, операторы должны быть довольно интуитивно понятными. В этой таблице приведен приоритет операторов, а в этом разделе и ниже - подробная спецификация грамматики. Вы можете запустить Python 2 на TIO .
I / O
Входные данные: положительное целое число n
, по крайней мере 2.
Выходные данные: 1, если n
простое число, и 0 в противном случае. True
и False
также может быть использован. Побеждает несколько байтов.
Поскольку ваш код является выражением, это будет фрагмент, ожидающий входное значение, сохраненное как n
, и вычисляющий желаемый результат.
Ваш код должен работать для n
сколь угодно больших системных ограничений. Поскольку тип целых чисел Python не ограничен, операторы не имеют ограничений. Ваш код может занять много времени для запуска.
Ответы:
43 байта
Попробуйте онлайн!
Этот метод аналогичен второму (удаленному) ответу Дениса, но этот ответ легче доказать, что он правильный.
доказательство
Краткая форма
Наиболее значимая цифра2n n
(4**n+1)**n%4**n**2
в базе которая не делится на , сделает следующую (менее значимую) цифру ненулевой (если эта «следующая цифра» не находится в дробной части), тогда выполняется a с битовой маской для проверьте, если любая цифра в нечетной позиции отлична от нуля. n(4**n+1)**n%4**n**2/n
&
2**(2*n*n+n)/-~2**n
Длинная форма
Пусть будет числом, имеющим представление этого базового , то есть , а будет цифрой в «позиции» в базе представление. b a n b n + ⋯ + a 1 b 1 + a 0 b 0 a i i b[an,…,a1,a0]b b anbn+⋯+a1b1+a0b0 ai i b
Потому что (с с) - целое число, и , = , n 2 n - 1 ⌊ 2 n2n×4n2−11+2n=2n(2n−1)×(4n)n−14n−1=[2n−1,0,2n−1,0,2n−1,0]2n n 2n−1 [2n-1,0,2n-1,0,2n-1,0]2n⌊2n1+2n⌋=0 [2n−1,0,2n−1,0,2n−1,0]2n
2**(2*n*n+n)/-~2**n
Далее рассмотрим
%4**n**2
усекаем число до последних цифр - это исключает (который равен 1), но включает все другие биномиальные коэффициенты.О себе
/n
:Если простое число, результатом будет . Все цифры в нечетной позиции равны нулю.n [(nn−1)/n,0,…,0,(n1)/n,0,0]2n
Если не простое число:n
Пусть будет наибольшим целым числом таким, что ( ). Переписать дивиденд какa n∤(na) n>a>0
Первое слагаемое имеет все цифры, кратные , а цифра в позиции равна нулю.n 2a−1
Второе слагаемое имеет самую значимую цифру (в позиции ), не делимую на и (основание) , поэтому при делении этого числа на будет иметь место цифра в позиции отличная от нуля.2a n 2n>n n 2a−1
Следовательно, конечный результат (2n 2a+1
(4**n+1)**n%4**n**2/n
) должен иметь цифру ( конечно, основание ) в позиции отличной от нуля.Наконец, побитовое И (2n a&0=0,a&(2n−1)=a 0≤a<2n n n
&
) выполняет векторизованное побитовое И для цифр в базе (потому что основание является степенью 2), и потому для всех , равно нулю, если все цифры в первых нечетных позициях равны нулю - что эквивалентно простому .(4**n+1)**n%4**n**2/n&2**(2*n*n+n)/-~2**n
(4**n+1)**n%4**n**2/n
источник
(4**n+1)**n%2**n**2/n&2**n**2/-~2**n<1
работать?n
чтобы не вызывать нежелательных взаимодействий между базой цифр4**n
.(4**n+1)**n%4**n**2/n<<n&4**n**2/-~2**n<1
. Мне любопытно, если эта задача возможна без побитовых операторов.Python 2 , 56 байт
Попробуйте онлайн!
Это доказательство правильности концепции , что эта задача выполнима только с арифметическими операторами, в частности , без побитового
|
,&
или^
. Код использует побитовые операторы и операторы сравнения только для игры в гольф, и их можно легко заменить арифметическими эквивалентами.Однако решение очень медленное, и я не смог запустить `, благодаря двухуровневым показателям типа .n=6 2nn
Основная идея - сделать выражение для факториала, что позволяет нам сделать тест на первичность теоремы Вильсона где является оператором по модулю.n! (n−1)!%n>n−2 %
Мы можем сделать выражение для биномиального коэффициента , который состоит из факториалов
Но не ясно, как извлечь только один из этих факториалов. Хитрость заключается в том, чтобы разбить на частисделав действительно огромным.n! m
Таким образом, если мы допустим, чтобы было произведением , мы имеемc (1−1m)(1−2m)⋯(1−n−1m)
Если бы мы могли просто игнорировать , мы бы сделали. В остальной части этого поста рассказывается, насколько нам нужно сделать чтобы это можно было сделать.c m
Обратите внимание, что приближается к снизу как . Нам просто нужно сделать достаточно большим, чтобы пропуск дал нам значение с целой частьютак что мы можем вычислитьc 1 m→∞ m c n!
Для этого достаточно иметьчтобы избежать отношения передачи следующего целого числа .1−c<1/n! n!+1
Заметим, что является произведением из членов, наименьшее из которых равно . Итак, мы имеемc n (1−n−1m)
что означает . Так как мы ищемдостаточно взять .1−c<n2m 1−c<1/n! m≥n!⋅n2
В коде мы используем . Так как теорема Вильсона используетнам нужно только . Легко видеть, что удовлетворяет оценке для малых значений и быстро асимптотически перерастает правую часть, скажем, в приближении Стирлинга .m=nn (n−1)! m≥(n−1)!⋅(n−1)2 m=nn
источник
В этом ответе не используется теоретический номер. Он спамит побитовые операторы Python, чтобы создать руководство «для цикла», проверяя все пары чтобы узнать, .1≤i,j<n i×j=n
Python 2, слишком много байтов (278 спасибо Джо Кингу в комментариях!)
Попробуйте онлайн!
Это намного больше байтов, чем другие ответы, поэтому я пока оставлю это без присмотра. Приведенный ниже фрагмент кода содержит функции и назначение переменных для ясности, но подстановка превращает isPrime (n) в одно выражение Python.
Почему это работает?
Я сделаю тот же алгоритм здесь в базе 10 вместо двоичного. Посмотрите на эту аккуратную фракцию:
Если мы поместим большую степень 10 в числитель и используем деление по полу в Python, это даст перечисление чисел. Например, с разделением по этажам, перечисляя числа .1015/(9992)=1002003004 1,2,3,4
Допустим, мы умножаем два числа, как это, с разными расстояниями от нуля. Я буду вводить запятые в продукт.
Продукт перечисляет в трехзначной последовательности таблицу умножения до 4 раз. Если мы хотим проверить, является ли число 5 простым, нам просто нужно проверить, появляется ли где-нибудь в этом продукте.005
Для этого мы XOR вышеупомянутого продукта по номеру , а затем вычитаем число . Назовите результат . Если появилось в перечислении таблицы умножения, это приведет к переносу вычитания и положит в соответствующее место в .005005005…005 001001001…001 d 005 999 d
Чтобы проверить это переполнение, мы вычисляем AND для и число . Результат равен нулю тогда и только тогда, когда 5 - простое число.d 900900900…900
источник