Номер Proth , названный в честь Франсуа Прот, это число , которое может быть выражено как
N = k * 2^n + 1
Где k
нечетное положительное целое число и n
такое положительное целое число, что 2^n > k
. Давайте использовать более конкретный пример. Возьмите 3. 3 - число Proth, потому что оно может быть записано как
(1 * 2^1) + 1
и 2^1 > 1
доволен. 5 Это также число Proth, потому что оно может быть записано как
(1 * 2^2) + 1
и 2^2 > 1
доволен. Тем не менее, 7 не число Proth потому что единственный способ записать его в виде N = k * 2^n + 1
является
(3 * 2^1) + 1
и 2^1 > 3
не устраивает.
Ваша задача довольно проста: вы должны написать программу или функцию, которая, с учетом положительного целого числа, определяет, является ли это число Протона или нет. Вы можете принимать входные данные в любом приемлемом формате и должны выводить истинное значение, если это число Протса, и ложное значение, если это не так. Если на вашем языке есть какие-либо функции «обнаружения числа протеза», вы можете их использовать.
Тест IO
Вот первые 46 чисел Proth до 1000. ( A080075 )
3, 5, 9, 13, 17, 25, 33, 41, 49, 57, 65, 81, 97, 113, 129, 145, 161, 177, 193, 209, 225, 241, 257, 289, 321, 353, 385, 417, 449, 481, 513, 545, 577, 609, 641, 673, 705, 737, 769, 801, 833, 865, 897, 929, 961, 993
Любой другой действительный ввод должен давать ложное значение.
Как обычно, это код-гольф, поэтому применяются стандартные лазейки, и выигрывает самый короткий ответ в байтах!
Дополнительная информация о теории чисел:
Самое большое известное простое число, которое не является Mersenne Prime 19249 * 2^13018586 + 1
, и это тоже случай с числом Протса!
источник
Python, 22 байта
Это порт моего желе ответа . Проверьте это на Ideone .
Как это работает
Пусть j строго положительное целое число. j + 1 переключает все завершающие установленные биты j и соседний неустановленный бит. Например, 10011 2 + 1 = 10100 2 .
Так как ~ j = - (j + 1) = -j - 1 , -j = ~ j + 1 , то -n применяет вышеприведенное к побитовому НЕ для j (который переключает все биты), таким образом переключая все биты перед последним 1 .
Принимая j & -j - побитовое И для j и -j - все биты до и после последнего установленного бита обнуляются (поскольку они неравны по j и -j ), что дает наибольшую степень 2, которая делит j равномерно.
Для входа N мы хотим применить вышеупомянутое к N - 1, чтобы найти 2 n , наибольшую степень 2, которая делит N - 1 . Если m = N - 1 , -m = - (N - 1) = 1 - N , то (N - 1) & (1 - N) дает 2 n .
Все, что осталось проверить, это если 2 n > k . Если к> 0 , это справедливо тогда и только тогда , когда (2 л ) 2 > к2 п , что верно само по себе , если и только если (2 л ) 2 ≥ к2 п + 1 = N .
Наконец, если (2 n ) 2 = N = k2 n + 1 , 2 n должно быть нечетным ( 1 ), чтобы соотношения сторон могли совпадать, подразумевая, что k = 0 и N = 1 . В этом случае (N - 1) & (1 - N) = 0 & 0 = 0 и ((N - 1) & (1 - N)) 2 = 0 <1 = N .
Следовательно, ((N - 1) & (1 - N)) 2 > N истинно тогда и только тогда, когда N является числом Прота.
Игнорирование неточностей с плавающей запятой, это эквивалентно коду
N-1&1-N>N**.5
в реализации.источник
Python 2, 23 байта
источник
Mathematica,
5048454038353129 байтMathematica, как правило, отстой, когда дело доходит до кода гольфа, но иногда есть встроенный, который делает вещи выглядеть действительно красиво.
Тест:
Редактировать: На самом деле, если я украду битовую идею Денниса И, я могу уменьшить ее до
232220 байтов.Mathematica,
232220 байтов (спасибо Симмонс )источник
g=
, чистая функция в порядке!Select[Range@1000,f]
.05AB1E ,
1410 байтСпасибо Emigna за сохранение 4 байта!
Код:
Использует кодировку CP-1252 . Попробуйте онлайн! ,
Объяснение:
Для пояснения воспользуемся номером 241 . Сначала мы уменьшаем число на единицу с
<
. Это приводит к 240 . Теперь вычислим простые множители (с дубликатами), используяÒ
. Основными факторами являются:Мы разделили их на две части. Используя
2Q·0K
, мы получаем список из двух:С помощью
®2K
мы получаем список оставшихся номеров:Наконец, возьмите продукт обоих.
[2, 2, 2, 2]
результаты в 16 . Произведение[3, 5]
результатов в 15 .Этот тест верен с 16 > 15 .
источник
<©Ó¬oD®s/›
или<DÓ0èoDŠ/›
за 10.Brain-Flak ,
460350270266264188176 байтПопробуйте онлайн!
объяснение
Программа проходит через степени двух и четырех, пока не найдет степень двух больше, чем N-1. Когда он находит его, он проверяет делимость N-1 на степень двух, используя модуль, и выводит результат
Эта программа не чистая в стеке. Если вы добавите дополнительные 4 байта, вы можете сделать его чистым:
источник
MATL , 9 байт
Правдивый вывод есть
1
. Ложь0
или пустой вывод. (Единственные входные данные, которые производят пустой вывод, являются1
и2
; остальные производят либо0
или1
).Попробуйте онлайн!
объяснение
Пусть х обозначает вход. Пусть y будет наибольшей степенью 2, которая делит x − 1, и z = ( x − 1) / y . Обратите внимание, что z автоматически нечетно. Тогда x является числом Прота тогда и только тогда, когда y > z , или эквивалентно, если y 2 > x −1.
источник
Брахилог , 28 байт
Попробуйте онлайн!
Проверьте все тестовые случаи одновременно. (Слегка изменено.)
объяснение
Брахилог, будучи производным от Пролога, очень хорошо доказывает вещи.
Здесь мы докажем эти вещи:
источник
Haskell,
5546 байтовРедактировать: благодаря Ними, теперь 46 байтов
источник
sum[1| ... ]
. Здесь мы можем пойти дальше и двигаться тест равенства в передней части|
и проверить с ,or
если любой из них правда:f x=or[k*2^n+1==x|k<-...,n<-...,2^n>k]
.ECMAScript Regex,
484341 байтРегулярные выражения Нейла и Х.П.Виза (оба также и на ECMAScript) прекрасны сами по себе. Существует еще один способ сделать это, что по довольно аккуратным совпадение было 1 байт больше , чем Нила, и теперь предложил играть в гольф H.PWiz в (спасибо!), Составляет 1 байт
больше, меньше H.PWiz годов.Предупреждение: Несмотря на небольшой размер этого регулярного выражения, он содержит основной спойлер . Я настоятельно рекомендую научиться решать унарные математические задачи в регулярном выражении ECMAScript, самостоятельно выясняя исходные математические идеи. Для меня это было увлекательное путешествие, и я не хочу испортить его тем, кто потенциально может попробовать его сами, особенно тем, кто интересуется теорией чисел. См. Этот более ранний пост для списка последовательно рекомендованных спойлером рекомендованных проблем, чтобы решить одну за другой.
Так что не читайте дальше, если вы не хотите, чтобы какая-то продвинутая магия унарных регулярных выражений была испорчена для вас . Если вы действительно хотите сами разобраться в этой магии, я настоятельно рекомендую начать с решения некоторых проблем в регулярном выражении ECMAScript, как описано в этом посте, связанном выше.
Таким образом, это регулярное выражение работает довольно просто: оно начинается с вычитания одного. Тогда он находит самый большой нечетный фактор, k . Затем мы делим на k (используя алгоритм деления, кратко объясненный в помеченном спойлером абзаце моего поста регулярных выражений факторных чисел ). Мы украдкой делаем одновременное утверждение, что результирующее отношение больше k . Если деление совпадает, у нас есть номер Proth; если нет, то нет.
Мне удалось отбросить 2 байта из этого регулярного выражения (43 → 41), используя уловку, найденную Гримми, которая может еще больше сократить деление в случае, когда коэффициент гарантированно будет больше или равен делителю.
Попробуйте онлайн!
источник
Юлия, 16 байт
Кредиты @Dennis для ответа и несколько советов по гольфу!
источник
&
такой же приоритет, как и у*
.-~-x
вместо(1-x)
. Кроме того, есть√x
вместоx^.5
, но это не сохраняет байтов.R,
5250 байтПрограмма начинается с деления
N-1
(называемого здесьP
иx
)2
как можно дольше для того, чтобы найти2^n
часть уравнения, оставляяk=(N-1)/2^n
, а затем вычисляя, неk
уступает ли оно2^n
, используя тот факт, что2^n>x/2^n <=> (2^n)²>x <=> 2^2n>x
источник
P=
в начале, изменить конец2^n>x
и сохранить как 5 или 6 байтовРегулярное выражение (ECMAScript),
4038 байт-2 байта благодаря Deadcode
Попробуйте онлайн!
Комментируемая версия:
источник
^x(?=((xx)+?)(\1\1)*$)(?!(\1x\2*)\4*$)
( Попробуйте онлайн )J, 10 байт
На основе побитового решения @Dennis .
Принимает входные данные
n
и возвращает 1, если это число Proth, иначе 0.использование
объяснение
источник
AND
. прохладный!Сетчатка 0.8.2 , 47 байт
Преобразовать в одинарный.
Преобразовать в двоичный файл
Повторно запустить формулу поколения Proth в обратном порядке.
Соответствуйте базовому случаю формулы поколения Proth.
Редактировать: я думаю, что на самом деле можно сопоставить число Прота непосредственно с одинарным числом с одним регулярным выражением. В настоящее время это занимает 47 байтов, что на 7 байтов больше, чем мой текущий код Retina, для проверки, является ли унарное число протовым числом:
источник
ECMAScript Regex, 42 байта
Попробуйте онлайн! (С помощью Retina)
По сути, я вычитаю 1, делю на максимально возможное нечетное число
k
, затем проверяю,k+1
осталось ли хотя бы меньше .Оказывается, мое регулярное выражение очень похоже на то, которое Нил дает в конце своего ответа . Я использую
x(xx)*
вместо(x*)\2x
. И я использую более короткий метод, чтобы проверитьk < 2^n
источник
(\3\3)*)$
на(\3\3)*$)
$=
и$.=
. Это может быть улучшено даже лучше .Brain-Flak , 128 байт
Попробуйте онлайн!
Я использовал совсем другой алгоритм, чем старое решение Brain-Flak .
По сути, я делю на 2 (округляя вверх), пока не достигну четного числа. Затем я просто сравниваю результат последнего деления с двумя с степенью числа раз, которое я разделил.
Объяснение:
источник
Клен, 100 байт (включая пробелы)
Хорошо разнесены для удобства чтения:
Та же идея, что и у нескольких других; делите X на 2 до тех пор, пока X не перестанет делиться равномерно на 2, затем проверьте критерии 2 ^ n> x.
источник
Java 1.7,
4943 байтаЕще 6 байт пыли благодаря @charlie.
Попытайся! (ideone)
Два пути, одинаково длинные. Как и с большинством ответов здесь, кредиты идут на @Dennis, конечно, для выражения.Взяв корень правой части выражения:
Применяя степень два к левой части выражения:
Может сбрить один байт, если положительному числовому значению разрешено представлять «истину», а отрицательному значению «ложь»:
К сожалению, из-за «сужения примитивного преобразования» нельзя просто написать это на Java и получить правильные результаты:
И любая попытка расширить 'p' приведет к ошибке компиляции, потому что побитовые операторы не поддерживаются, то есть с плавающей запятой или с двойными числами :(источник
boolean f(int p){return Math.sqrt(p--)<(p&-p);}
boolean g(int p){return p--<(p&-p)*(p&-p);}
Math.*
звонков; просто не мог понять как! Благодарность!Hy , 37 байт
Попробуйте онлайн!
Порт ответа @Dennis.
источник
C (gcc) , 29
30байтПопробуйте онлайн!
источник
Japt ,
12109 байтПопробуйте онлайн!
Желе порт Деннис снова ответить. - 1 спасибо @Shaggy.
источник
-1
может бытьÉ
.Cjam, 11 байт
Как и многие из нас, воспользовавшись отличным решением Дениса:
Попробуйте онлайн
источник
C (137 байт)
Только пришел, чтобы прочитать ответы после того, как я попробовал.
Учитывая
N=k*2^n+1
с условиемk<2^n
(k=1,3,5..
иn=1,2,3..
У
n=1
нас есть одинk
доступный для тестирования. По мере увеличенияn
мы получим еще несколькоk's
тестов следующим образом:n = 1; к = 1
n = 2; k = 1 k = 3
n = 3; k = 1 k = 3 k = 5 k = 7
...
Перебор этих возможностей мы можем быть уверены , что N не является числом Prouth если для данного полученное число больше , чем N , и никакая другая итерация не был матч.
n
k=1
Таким образом, мой код в основном "грубой силы", чтобы найти N.
После прочтения других ответов и понимания того, что вы можете вычислить N-1 с помощью 2, чтобы найти,
n
а затем сделать условиеk<2^n
, я думаю, мой код мог бы быть меньше и эффективнее при использовании этого метода.Это стоило попробовать!
Проверены все приведенные числа и несколько «нерутовых» чисел. Функция возвращает 1, если число является числом Прута, и 0, если это не так.
источник
Javascript ES7, 16 байт
Порт моего ответа Джулии, который является портом ответа Jelly @ Dennis's.
Спасибо @Charlie за 2 сохраненных байта!
источник
n=x=>x-1&1-x>x**.5; n(3)
дает мне0
(на самом деле это дает мне 0 независимо от ввода)n=x=>x-1&1-x>Math.pow(x,0.5); n(3)
(x-1&1-x)
как без него приоритет оператора на самом деле:(x-1)&((1-x)>x**.5)
x=>x--**.5<(x&-x)
илиx=>x**.5<(--x&-x)
C # (.NET Core) , 17 байт
Попробуйте онлайн!
Порт С MegaTom ответ .
Я попробовал решение на основе LINQ, но это было слишком хорошо.
источник
чернила , 60 байт
Попробуйте онлайн!
На основе ответу @ DSkoog на Maple, он был не первым в своем роде, но и первым в своем роде, который я увидел.
Ungolfed
источник
Машинный код x86, 15 байт
Эти байты определяют функцию, которая принимает входной аргумент (целое число без знака) в
EDI
регистре, следуя стандартному соглашению о вызовах System V для систем x86, и возвращает результат вEAX
регистр, как все соглашения о вызовах x86.В мнемонике ассемблера:
Попробуйте онлайн!
Это довольно простое решение - концептуально похожее на C-версию MegaTom . На самом деле, вы можете написать это в C как что-то вроде следующего:
но машинный код выше лучше, чем тот, который вы получите от компилятора Си, даже если он настроен на оптимизацию по размеру.
Единственный «чит» здесь возвращает -1 как «истинное» значение и 0 как «ложное» значение. Этот прием позволяет использовать 2-байтовую
SBB
инструкцию, а не 3-байтовуюSETB
инструкцию.источник