Це номер Proth?


37

Номер Proth , названий в честь Франсуа Прот, це число , яке може бути виражено як

N = k * 2^n + 1

Де kє непарне додатне ціле число і nє додатне ціле число таким, що 2^n > k. Скористаємося більш конкретним прикладом. Візьміть 3. 3 - число Прота, оскільки його можна записати як

(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

Кожен інший дійсний вхід повинен дати хибне значення.

Як завжди, це код-гольф, тому застосовуються стандартні лазівки, і найкоротша відповідь у байтах виграє!


Теорія чисел, потішних фактів:

Найбільший відомий прем'єр, який не є прем'єром Мерсенна 19249 * 2^13018586 + 1, який так само буває і номером Proth!

Відповіді:


41

Желе , 5 байт

’&C²>

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Фон

Нехай j - цілком додатне ціле число. j + 1 перемикає всі біти останнього набору j та сусідній нерозбірний біт. Наприклад, 10011 2 + 1 = 10100 2 .

Оскільки ~ j = - (j + 1) = -j - 1 , -j = ~ j + 1 , то -n застосовує вищезгадане до порозрядного НЕ j (яке перемикає всі біти), тим самим перемикаючи всі біти до останнього 1 .

Приймаючи j & -j - порозрядне AND з 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 н > 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 - число Прота.

Як це працює

’&C²>  Main link. Argument: N

’      Decrement; yield N - 1.
  C    Complement; yield 1 - N.
 &     Take the bitwise AND of both results.
   ²   Square the bitwise AND.
    >  Compare the square to N.

вау. ось неймовірно
нехай яскраво

46

Пітон, 22 байти

lambda N:N-1&1-N>N**.5

Це портрет моєї відповіді на желе . Перевірте це на Ideone .

Як це працює

Нехай j - цілком додатне ціле число. j + 1 перемикає всі біти останнього набору jостаннього та сусідній нерозбірний біт. Наприклад, 10011 2 + 1 = 10100 2 .

Оскільки ~ j = - (j + 1) = -j - 1 , -j = ~ j + 1 , то -n застосовує вище до розрядного НЕ зj (яке перемикає всі біти), тим самим перемикаючи всі біти до останнього 1 .

Приймаючи j & -j - порозрядне AND з 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 . Якщо k> 0 , це істинно, якщо і лише тоді, коли (2 n ) 2 > k2 n , що є істинним самим тоді і тільки тоді, коли (2 n )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 в реалізації.


23
Я часті Math.SE, і мої очі дійсно бажають красивого LaTeX на цьому сайті, а не схожий на сайт 90-х ...
qwr

Цей мій улюблений.
Qix


9

Математика, 50 48 45 40 38 35 31 29 байт

Математика, як правило, гадає, якщо мова йде про гольф коду, але іноді є вбудований, який робить речі дуже гарними.

1<#<4^IntegerExponent[#-1,2]&

Тест:

Reap[Do[If[f[i],Sow[i]],{i,1,1000}]][[2,1]]

{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}

Редагувати: Насправді, якщо я вкраду ідею Денніса І побіжно, я можу знизити його до 23 22 20 байт.

Mathematica, 23 22 20 байт (спасибі A Simmons )

BitAnd[#-1,1-#]^2>#&

2
Ласкаво просимо до головоломки програмування та коду для гольфу! :)
Аднан

1
Не потрібно для початку g=, чиста функція прекрасна!
A Simmons

О, мила. Виправлено це зараз.
Майкл Лі

До речі, ваш тест можна значно спростити Select[Range@1000,f].
числоманіяк

8

05AB1E , 14 10 байт

Дякуємо Еміньї за збереження 4 байтів!

Код:

<©Ó¬oD®s/›

Використовує кодування CP-1252 . Спробуйте в Інтернеті!.

Пояснення:

Для пояснення скористаємось числом 241 . Ми спочатку декрементуємо число за одним <. Це призводить до 240 . Тепер ми обчислюємо прості коефіцієнти (за допомогою дублікатів), використовуючи Ò. Основними факторами є:

[2, 2, 2, 2, 3, 5]

Ми розділили їх на дві частини. Використовуючи 2Q·0K, ми отримуємо список двох:

[2, 2, 2, 2]

З ®2K, ми отримуємо список решти цифр:

[3, 5]

Нарешті, візьміть продукт обох. [2, 2, 2, 2]результати в 16 . Продукт [3, 5]результатів у 15 .

Цей тестовий випадок є трибунним з 16 > 15 .


<©Ó¬oD®s/›або <DÓ0èoDŠ/›для 10.
Емінья

@Emigna Це геній! Спасибі :).
Аднан

7

Брейн-Флак , 460 350 270 266 264 188 176 байт

Спробуйте в Інтернеті!

({}[()])(((<>()))){{}([(((({}<(({}){})>){}){})<>[({})(())])](<>)){({}())<>}{}<>{}{}<>(({})){{}{}<>(<(())>)}{}}(<{}{}>)<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<>)

Пояснення

Програма проходить через два і чотири потужності, поки не знайде потужність у дві більше, ніж N-1. Коли він знаходить це, він перевіряє подільність N-1 силою двох за допомогою модуля і видає результат

({}[()])      #Subtract one from input
(((<>())))    #Put three ones on the other stack
{
 {}           #Pop the crap off the top
 ([(
  ((({}<(({}){})>){}){}) #Multiply the top by four and the bottom by two
  <>[({})(())])](<>)){({}())<>}{}<>{}{}<>(({})){{}{}<>(<(())>)}{} #Check if the power of four is greater than N-1
}
(<{}{}>) #Remove the power of 4
<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<{}><>) #Modulo N-1 by the power of two

Ця програма не є стеком чистою. Якщо ви додасте додаткові 4 байти, ви можете зробити його стек чистим:

({}[()])(((<>()))){{}([(((({}<(({}){})>){}){})<>[({})(())])](<>)){({}())<>}{}<>{}{}<>(({})){{}{}<>(<(())>)}{}}(<{}{}>)<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<{}><>)

5

MATL , 9 байт

qtYF1)EW<

Поточний вихід є 1. Falsy - це 0або порожній вихід. (Єдиними входами, які видають порожній вихід, є, 1а 2решта виробляють або 0або 1).

Спробуйте в Інтернеті!

Пояснення

Нехай x позначає вхід. Нехай y - найбільша потужність 2, яка ділить x −1, z = ( x −1) / y . Зауважте, що z автоматично непарно. Тоді x - число Прота тоді і тільки тоді, якщо y > z , або еквівалентно, якщо y 2 > x −1.

q    % Input x implicitly. Subtract 1
t    % Duplicate
YF   % Exponents of prime factorization of x-1
1)   % First entry: exponent of 2. Errors for x equal to 1 or 2
E    % Duplicate
W    % 2 raised to that. This is y squared
<    % Is x-1 less than y squared? Implicitly display

5

Брахілог , 28 байт

>N>0,2:N^P:K*+?,P>K:2%1,N:K=

Спробуйте в Інтернеті!

Перевірте всі тести одразу. (Трохи модифікований.)

Пояснення

Брахілог, будучи похідним від Prolog, дуже добре доводить речі.

Ось ми доводимо такі речі:

>N>0,2:N^P:K*+?,P>K:2%1,N:K=

>N>0                           input > N > 0
     2:N^P                     2^N = P
         P:K*+?                P*K+1 = input
                P>K            P > K
                  K:2%1        K%2 = 1
                        N:K=   [N:K] has a solution

5

Haskell, 55 46 байт

f x=length [x|k<-[1,3..x],n<-[1..x],k*2^n+1==x,2^n>k]>0

Редагувати: Завдяки німі, зараз 46 байт

f x=or[k*2^n+1==x|k<-[1,3..x],n<-[1..x],2^n>k]

4
Ласкаво просимо до головоломки програмування та коду для гольфу!
Денніс

Спасибі людино! На деякий час тут ховався. Великий вентилятор btw, желе - це супер круто. Бажаю, я міг би навчитися, але на жаль, я не дуже розумію
X88B88

2
Загальна порада: якщо вас просто цікавить довжина списку, створеного зрозумінням, ви можете використовувати sum[1| ... ]. Тут ми можемо піти далі і рухатися тест рівності в передній частині |і перевірити з , orякщо будь-який з них правда: f x=or[k*2^n+1==x|k<-...,n<-...,2^n>k].
німі

Ого. Чудові поради. Я обов'язково перегляну.
X88B88

2
Якщо вам цікаво вивчити Jelly, перегляньте вікі або приєднайтеся до кімнати Jelly .
Денніс

5

ECMAScript Regex, 48 43 41 байт

Реджекси Ніла та H.PWiz (обидва також аромат ECMAScript) самі по собі прекрасні. Існує ще один спосіб зробити це, що за досить акуратним збіг було 1 байт більше , ніж Нілу, і тепер запропонував грати в гольф H.PWiz в (спасибі!), Складає 1 байт більше , менше H.PWiz років.

Попередження: Незважаючи на невеликий розмір цього регексу, він містить основний спойлер . Я настійно рекомендую навчитися вирішувати одинарні математичні задачі в регулярному вираженні ECMAScript шляхом самостійного з'ясування початкових математичних даних. Це була захоплююча подорож для мене, і я не хочу її зіпсувати нікому, хто, можливо, захоче спробувати його сам, особливо тим, хто цікавиться теорією чисел. Перегляньте це попереднє повідомлення, щоб ознайомитися зі списком рекомендованих послідовно позначених спойлерами проблем, які потрібно вирішити по черзі.

Тож не читайте більше, якщо ви не хочете, щоб якась просунута онірна регекс-магія зіпсована для вас . Якщо ви хочете самостійно спробувати вирішити цю магію, я настійно рекомендую почати з вирішення деяких проблем у регулярному вираженні ECMAScript, описаних у цій публікації, зв'язаній вище.

Отже, цей регулярний вираз працює досить просто: він починається з віднімання одного. Тоді він знаходить найбільший непарний фактор, k . Тоді ми ділимо на k (використовуючи коротко пояснений алгоритм поділу в абзаці, розміченому спойлером, в моєму реєкс-повідомленні про фактичні номери ). Ми підступно робимо одночасне твердження, що отриманий коефіцієнт більший за k . Якщо поділ збігається, у нас є номер Proth; якщо ні, то ми ні.

Мені вдалося скинути 2 байти з цього регулярного виразу (43 → 41) за допомогою трюку, знайденого Грімі, який може в подальшому скоротити поділ у випадку, якщо коефіцієнт гарантовано буде більшим або рівним дільнику.

^x(?=(x(xx)*)\1*$)((\1x*)(?=\1\4*$)x)\3*$

Спробуйте в Інтернеті!


 # Match Proth numbers in the domain ^x*$
 ^
 x                         # tail = tail - 1
 (?=(x(xx)*)\1*$)          # \1 = largest odd factor of tail
 
 # Calculate tail / \1, but require that the quotient, \3, be > \1
 # (and the quotient is implicitly a power of 2, because the divisor
 # is the largest odd factor).
 (                         # \3 = tail / \1, asserting that \3 > \1
     (\1x*)                # \4 = \3-1
     (?=\1\4*$)            # We can skip the test for divisibility by \1-1
                           # (and avoid capturing it) because we've already
                           # asserted that the quotient is larger than the
                           # divisor.
     x
 )
 \3*$
 


1
О_о уау, всього 48 байт
лише ASCII

Ніл більше схожий на мій, ніж на Денніса
H.PWiz

4

Джулія, 16 байт

!x=~-x&-~-x>x^.5

Подяки @Dennis за відповідь та кілька порад з гольфу!


Це не працює. У Джулії &має той самий пріоритет, що і *.
Денніс

1
Авжеж. Виправлено: PI повинен справді перевірити свій код.
Mama Fun Roll

2
Ви можете використовувати -~-xзамість (1-x). Крім того, є √xзамість x^.5, але це не економить жодних байт.
Денніс

4

R, 52 50 байт

x=scan()-1;n=0;while(!x%%2){x=x/2;n=n+1};2^(2*n)>x

Програма починається діленням 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


1
Ви можете потягнути P=на початку та змінити кінець 2^n>xі зберегти як 5 або 6 байт
user5957401

4

Regex (ECMAScript), 40 38 байт

-2 байти завдяки Deadcode

^x(?=((xx)+?)(\1\1)*$)(?!(\1x\2*)\4*$)

Спробуйте в Інтернеті!

Коментована версія:

# Subtract 1 from the input N
^x

# Assert N is even.
# Capture \1 = biggest power of 2 that divides N.
# Capture \2 = 2.
(?=((xx)+?)(\1\1)*$)

# Assert no odd number > \1 divides N
(?!(\1x\2*)\4*$)

Ого, це дуже круто. Стільки різних способів вирішити цю проблему!
Deadcode

1
38 байт: ^x(?=((xx)+?)(\1\1)*$)(?!(\1x\2*)\4*$)( Спробуйте в Інтернеті )
Deadcode

2

J, 10 байт

%:<<:AND-.

На основі розрядного рішення @Dennis .

Бере вхід nі повертає 1, якщо це число Прот ще 0.

Використання

   f =: %:<<:AND-.
   f 16
0
   f 17
1
   (#~f"0) >: i. 100  NB. Filter the numbers [1, 100]
3 5 9 13 17 25 33 41 49 57 65 81 97

Пояснення

%:<<:AND-.  Input: n
        -.  Complement. Compute 1-n
   <:       Decrement. Compute n-1
     AND    Bitwise-and between 1-n and n-1
%:          Square root of n
  <         Compare sqrt(n) < ((1-n) & (n-1))

Ага. Я про це не знав AND. круто!
Conor O'Brien

2

Сітківка 0,8,2 , 47 байт

\d+
$*
+`(1+)\1
$+0
01
1
+`.10(0*1)$
1$1
^10*1$

Спробуйте в Інтернеті! Пояснення: Дано номер Prothк·2н+1, Ви можете отримати два нові числа Proth (2к±1)·2н+1+1. Ми можемо запустити це в зворотному порядку, поки не отримаємо номер Proth, дек=1. Це легко виконується шляхом перетворення двійкового подання.

\d+
$*

Перетворити в одинарне.

+`(1+)\1
$+0
01
1

Перетворити на бінарне.

+`.10(0*1)$
1$1

Повторно запускайте формулу покоління Proth у зворотному порядку.

^10*1$

Відповідайте базовому випадку формули покоління Proth.

Редагувати: Я думаю, що насправді можна зіставити номер Proth безпосередньо з одинаковим номером з одним регулярним виразом. Наразі це займає у мене 47 байт, що на 7 байт більше мого поточного коду сітківки для перевірки того, чи є одинарне число номер Proth:

^.(?=(.+?)(\1\1)*$)(?=((.*)\4.)\3*$).*(?!\1)\3$

2

ECMAScript Regex, 42 байти

^x(?=(x(xx)*)\1*$)(?=(x+?)((\3\3)*$))\4\1x

Спробуйте в Інтернеті! (Використання сітківки)

Я по суті віднімаю 1, ділю на найбільше можливе непарне число k, а потім перевіряю, що принаймні k+1залишилось.

Виявляється, мій регекс дуже схожий на той, який дає Ніл наприкінці своєї відповіді . Я використовую x(xx)*замість (x*)\2x. І я використовую коротший метод для перевіркиk < 2^n


Ого, це дивовижно! Дуже красиво зроблено. Зауважте, що ви можете зробити це трохи швидше, змінивши (\3\3)*)$на(\3\3)*$)
Deadcode

Гарна робота з цим кодом Retina. Я не знав про $=і $.=. Це можна вдосконалити ще краще .
Deadcode

2
@Deadcode Якщо ви збираєтеся вибирати колонтитул та нижній колонтитул, то слід додатково вдосконалити .
Ніл

@Neil Це виглядає як хороший гольф, але, на жаль, здається, що він має помилку. Спробуйте одиничні числа . Вони не працюють.
Deadcode

1
@Deadcode Вибачте, я не зрозумів, що одиничні числа є частиною "специфікації".
Ніл

2

Мозок-Флак , 128 байт

({<{({}[()]<(([{}]())<>{})<>>)}{}>{{}(<>)}{}}<><(())>){([()]{}<(({}){})>)}{}([({}[{}(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}

Спробуйте в Інтернеті!

Я використовував зовсім інший алгоритм, ніж старе рішення Brain-Flak .

В основному я ділю на 2 (округлюючи вгору), поки не потрапляю на парне число. Тоді я просто порівнюю результат останнього поділу з двома за потужністю, скільки разів я розділив.

Пояснення:

({
  # (n+1)/2 to the other stack, n mod 2 to this stack
  <{({}[()]<(([{}]())<>{})<>>)}{}>
  # if 1 (n was odd) jump to the other stack and count the one
  {{}(<>)}{}
#end and push the sum -1, with a one under it
}<>[(())])
#use the one to get a power of two
{([()]{}<(({}){})>)}{}
#compare the power of two with the remainder after all the divisions
([({}[{}(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}

1

Клен, 100 байт (включаючи пробіли)

IsProth:=proc(X)local n:=0;local x:=X-1;while x mod 2<>1 do x:=x/2;n:=n+1;end do;is(2^n>x);end proc:

Відмінні місця для читання:

IsProth := proc( X )
    local n := 0;
    local x := X - 1;
    while x mod 2 <> 1 do
        x := x / 2;
        n := n + 1;
    end do;
    is( 2^n > x );
end proc:

Така ж ідея, як і кілька інших; ділимо X на 2, поки X перестане рівномірно ділитися на 2, потім перевіримо критерії 2 ^ n> x.


1

Java 1.7, 49 43 байти

Ще 6 байт пилу завдяки @charlie.

boolean g(int p){return p--<(p&-p)*(p&-p);}

Спробуй це! (ideone)

Два способи, однаково довгі. Як і більшість відповідей тут, кредити йдуть на @Dennis, звичайно, для виразу.

Візьмемо корінь правої частини виразу:

boolean f(int p){return(p-1&(1-p))>Math.sqrt(p);}

Застосування сили двох до лівої частини виразу:

boolean g(int p){return Math.pow(p-1&(1-p),2)>p;}

Може відтіняти один байт, якщо позитивне числове значення дозволено представляти "truthy", а від'ємне значення "false":

double g(int p){return Math.pow(p-1&(1-p),2)-p;}

На жаль, через "Звуження примітивної конверсії" не можна просто написати це на Java та отримати правильні результати:

((p - 1 & (1 - p))^2) > p;

І будь-яка спроба розширити 'p' призведе до помилки компіляції, оскільки побітові оператори не підтримуються, тобто поплавці або подвійні :(


1
f = 47:boolean f(int p){return Math.sqrt(p--)<(p&-p);}
Чарлі

1
g = 43:boolean g(int p){return p--<(p&-p)*(p&-p);}
Чарлі

Хороший! Я знав, що повинен бути спосіб позбутися Math.*дзвінків; просто не міг зрозуміти, як! Спасибі!
МЗ.





0

C (137 байт)

int P(int N){int x=1,n=0,k=1,e=1,P=0;for(;e;n++){for(x=1,k=1;x&&x<N;k+=2){x=2<<n;x=x>k?x*k+1:0;if(x>N&&k==1)e=0;}if(x==N)P=1;}return P;}

Відповіді прийшов прочитати лише після того, як я спробував.

Враховуючи N=k*2^n+1умовний k<2^n(k=1,3,5.. іn=1,2,3..

З n=1нами є один kдоступний для тестування. У міру збільшення nми отримуємо ще кілька k'sтестів:

n = 1; k = 1

n = 2; k = 1 k = 3

n = 3; k = 1 k = 3 k = 5 k = 7

...

Ітератуючи за допомогою цих можливостей, ми можемо бути впевнені, що N не є числом Прауди, якщо для даного nзначенняk=1 отримане число більше , ніж N , і ніяка інша ітерація ні матч.

Тож мій код в основному "жорстоко намагається" знайти шлях до N.

Прочитавши інші відповіді та усвідомивши, що ви можете ввести коефіцієнт N-1 з 2, щоб знайти, nа потім зробити умовне k<2^n, я думаю, що мій код міг би бути меншим та ефективнішим за допомогою цього методу.

Варто було спробувати!

Перевірено всі задані числа та кілька "неістинних" чисел. Функція повертає 1, якщо число є числом Праута, і 0, якщо це не так.


0

Javascript ES7, 16 байт

x=>x--<(-x&x)**2

Порт моєї відповіді Джулії, який є порцією відповіді @ Dennis's Jelly.

Дякую @Charlie за 2 байти збережено!


n=x=>x-1&1-x>x**.5; n(3)дає мені 0(насправді це дає мені 0 незалежно від вкладу)
eithed

Який браузер? Це може бути саме так.
Mama Fun Roll

Chrome 52. Firefox 48 дає ту саму відповідьn=x=>x-1&1-x>Math.pow(x,0.5); n(3)
1616

Гаразд - це пріоритет оператора. Це повинно бути так, (x-1&1-x)як без нього насправді пріоритет оператора:(x-1)&((1-x)>x**.5)
eithed

1
-1 байт: x=>x--**.5<(x&-x)абоx=>x**.5<(--x&-x)
Чарлі


0

чорнило , 60 байт

=p(n)
~n-=n>1
~temp x=1
-(k){n%2:{n<x}->->}
~x+=x
~n=n/2
->k

Спробуйте в Інтернеті!

На основі відповіді Клена @ DSkoog - вона була не першою в своєму роді, яка була розміщена, але була першою у своєму роді, яку я побачив.

Безумовно

= is_proth(number) =

/* It's easy to check if a number is one less than a Proth number.
   We take the number and divide it by 2 until we can't.
   Once we can't, we've found the smallest possible "k".
   If we also keep track of how many times we divided, we have our corresponding "2^n"
   All we have to do then is compare those
*/

~ number -= (number > 1)            // So, we first subtract one. Except this implementation won't ever halt for 0, so we don't subtract if the input is 1 (this is fine since the desired outputs for inputs 1 and 2 are the same)
~ temp power_of_two = 1             // We declare a variable to store our "2^n"
- (check)
  {
  - number % 2:                     // Once we can't divide by 2 anymore, we've found the smallest possible "k"
    {number < power_of_two}         // At that point, we print whether it's smaller than the "2^n" we found
    ->->                            // And then we return to where we were called from
  }

  ~ number = number / 2             // We keep dividing by 2 until we can't.
  ~ power_of_two += power_of_two    // and update our "2^n" as we go
-> check

0

машинний код x86, 15 байт

4F 89 F8 F7 D8 21 F8 0F AF C0 39 C7 19 C0 C3

Ці байти визначають функцію, яка бере вхідний аргумент (непідписане ціле число) в EDIрегістр, дотримуючись стандартної конвенції виклику System V для систем x86, і повертає результат у EAXрегістр, як всі конвенції викликів x86.

В асемблері мнемоніка:

4F          dec   edi            ; input -= 1
89 F8       mov   eax, edi       ; \ temp
F7 D8       neg   eax            ; |      =
21 F8       and   eax, edi       ; /        (input & -input)
0F AF C0    imul  eax, eax       ; temp *= temp
39 C7       cmp   edi, eax       ; set CF if (input < temp)
19 C0       sbb   eax, eax       ; EAX = -CF
C3          ret                  ; return with result in EAX
                                 ;  (-1 for Proth number; 0 otherwise)

Спробуйте в Інтернеті!

Це досить просте рішення - і концептуально схоже на версію C MegaTom . Насправді, ви можете написати це на C як щось подібне:

unsigned IsProthNumber(unsigned input)
{
    --input;
    unsigned temp  = (input & -input);
    temp          *= temp;
    return (input < temp) ? -1 : 0;
}

але машинний код вище, ніж гольф, ніж те, що ви отримаєте з компілятора C, навіть якщо він налаштований на оптимізацію за розміром.

Єдиний "чіт" тут повертає -1 як значення "truthy" і 0 як "фальшиве" значення. Цей трюк дозволяє використовувати 2-байтну SBBінструкцію на відміну від 3-байтної SETBінструкції.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.