Is it a Proth number?

37

2

A Proth number, named after François Proth, is a number that can be expressed as

N = k * 2^n + 1

Where k is an odd positive integer and n is a positive integer such that 2^n > k. Let's use a more concrete example. Take 3. 3 is a Proth number because it can be written as

(1 * 2^1) + 1

and 2^1 > 1 is satisfied. 5 Is also a Proth number because it can be written as

(1 * 2^2) + 1

and 2^2 > 1 is satisfied. However, 7 is not a Proth number because the only way to write it in the form N = k * 2^n + 1 is

(3 * 2^1) + 1

and 2^1 > 3 is not satisfied.

Your challenge is fairly simple: you must write a program or function that, given a postive integer, determines if it is a Proth number or not. You may take input in any reasonable format, and should output a truthy value if it is a Proth number and a falsy value if it is not. If your language has any "Proth-number detecting" functions, you may use them.

Test IO

Here are the first 46 Proth numbers up to 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

Every other valid input should give a falsy value.

As usual, this is code-golf, so standard loopholes apply, and the shortest answer in bytes wins!


Number theory fun-fact side-note:

The largest known prime that is not a Mersenne Prime is 19249 * 2^13018586 + 1, which just so happens to also be a Proth number!

James

Posted 2016-08-10T22:07:56.617

Reputation: 54 537

Answers

41

Jelly, 5 bytes

’&C²>

Try it online! or verify all test cases.

Background

Let j be a strictly positive integer. j + 1 toggles all trailing set bits of j and the adjacent unset bit. For example, 100112 + 1 = 101002.

Since ~j = -(j + 1) = -j - 1, -j = ~j + 1, so -n applies the above to the bitwise NOT of j (which toggles all bits), thus toggling all bits before the last 1.

By taking j & -j – the bitwise AND of j and -j – all bits before and after the last set bit are nullified (since unequal in j and -j), thus yielding the highest power of 2 that divides j evenly.

For input N, we want to apply the above to N - 1 to find 2n, the highest power of 2 that divides N - 1. If m = N - 1, -m = -(N - 1) = 1 - N, so (N - 1) & (1 - N) yields 2n.

All that's left to test is if 2n > k. If k > 0, this is true if and only if (2n)2 > k2n, which is true itself if and only if (2n)2 ≥ k2n + 1 = N.

Finally, if (2n)2 = N = k2n + 1, 2n must be odd (1) so the parities of both sides can match, implying that k = 0 and N = 1. In this case (N - 1) & (1 - N) = 0 & 0 = 0 and ((N - 1) & (1 - N))2 = 0 < 1 = N.

Therefore, ((N - 1) & (1 - N))2 > N is true if and only if N is a Proth number.

How it works

’&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.

Dennis

Posted 2016-08-10T22:07:56.617

Reputation: 196 637

woah. thats incredible – don bright – 2019-02-21T05:18:16.807

46

Python, 22 bytes

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

This is a port of my Jelly answer. Test it on Ideone.

How it works

Let j be a strictly positive integer. j + 1 toggles all trailing set bits of j and the adjacent unset bit. For example, 100112 + 1 = 101002.

Since ~j = -(j + 1) = -j - 1, -j = ~j + 1, so -n applies the above to the bitwise NOT of j (which toggles all bits), thus toggling all bits before the last 1.

By taking j & -j – the bitwise AND of j and -j – all bits before and after the last set bit are nullified (since unequal in j and -j), thus yielding the highest power of 2 that divides j evenly.

For input N, we want to apply the above to N - 1 to find 2n, the highest power of 2 that divides N - 1. If m = N - 1, -m = -(N - 1) = 1 - N, so (N - 1) & (1 - N) yields 2n.

All that's left to test is if 2n > k. If k > 0, this is true if and only if (2n)2 > k2n, which is true itself if and only if (2n)2 &geq; k2n + 1 = N.

Finally, if (2n)2 = N = k2n + 1, 2n must be odd (1) so the parities of both sides can match, implying that k = 0 and N = 1. In this case (N - 1) & (1 - N) = 0 & 0 = 0 and ((N - 1) & (1 - N))2 = 0 < 1 = N.

Therefore, ((N - 1) & (1 - N))2 > N is true if and only if N is a Proth number.

Ignoring floating point inaccuracies, this is equivalent to the code N-1&1-N>N**.5 in the implementation.

Dennis

Posted 2016-08-10T22:07:56.617

Reputation: 196 637

23I frequent Math.SE, and my eyes really wish for beautiful LaTeX on this site instead of looking like a 90s site... – qwr – 2016-08-11T23:41:25.943

This one's my favorite. – Qix - MONICA WAS MISTREATED – 2016-08-12T21:47:38.867

9

Mathematica, 50 48 45 40 38 35 31 29 bytes

Mathematica generally sucks when it comes to code golf, but sometimes there's a built-in that makes things look really nice.

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

A test:

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}

Edit: Actually, if I steal Dennis's bitwise AND idea, I can get it down to 23 22 20 bytes.

Mathematica, 23 22 20 bytes (thanks A Simmons)

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

Michael Lee

Posted 2016-08-10T22:07:56.617

Reputation: 221

2Welcome to Programming Puzzles and Code Golf! :) – Adnan – 2016-08-10T22:41:01.067

1No need to begin with g=, a pure function is fine! – A Simmons – 2016-08-11T10:01:47.860

Oh, sweet. Fixed it now. – Michael Lee – 2016-08-11T14:04:40.297

By the way, your test can be significantly simplified to Select[Range@1000,f]. – numbermaniac – 2017-05-20T09:11:44.743

9

Python 2, 23 bytes

lambda n:(~-n&1-n)**2>n

feersum

Posted 2016-08-10T22:07:56.617

Reputation: 29 566

8

05AB1E, 14 10 bytes

Thanks to Emigna for saving 4 bytes!

Code:

<©Ó¬oD®s/›

Uses the CP-1252 encoding. Try it online!.

Explanation:

For the explanation, let's use the number 241. We first decrement the number by one with <. That results into 240. Now, we calculate the prime factors (with duplicates) using Ò. The prime factors are:

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

We split them into two parts. Using 2Q·0K, we get the list of two's:

[2, 2, 2, 2]

With ®2K, we get the list of the remaining numbers:

[3, 5]

Finally, take the product of both. [2, 2, 2, 2] results into 16. The product of [3, 5] results into 15.

This test case is truthy since 16 > 15.

Adnan

Posted 2016-08-10T22:07:56.617

Reputation: 41 965

<©Ó¬oD®s/› or <DÓ0èoDŠ/› for 10. – Emigna – 2016-08-11T20:50:48.320

@Emigna That is genius! Thanks :). – Adnan – 2016-08-11T23:06:34.033

7

Brain-Flak, 460 350 270 266 264 188 176 bytes

Try it online!

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

Explanation

The program goes through powers of two and four until it finds a power of two greater than N-1. When it finds it it checks for the divisibility of N-1 by the power of two using modulo and outputs the result

({}[()])      #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

This program is not stack clean. If you add an extra 4 bytes you can make it stack clean:

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

Post Rock Garf Hunter

Posted 2016-08-10T22:07:56.617

Reputation: 55 382

5

ECMAScript Regex, 48 43 41 bytes

Neil's and H.PWiz's regexes (both also ECMAScript flavour) are beautiful in their own right. There is another way to do it, which by a pretty neat coincidence was 1 byte more than Neil's, and now with H.PWiz's suggested golfing (thanks!), is 1 byte more less than H.PWiz's.

Warning: Despite this regex's small size, it contains a major spoiler. I highly recommend learning how to solve unary mathematical problems in ECMAScript regex by figuring out the initial mathematical insights independently. It's been a fascinating journey for me, and I don't want to spoil it for anybody who might potentially want to try it themselves, especially those with an interest in number theory. See this earlier post for a list of consecutively spoiler-tagged recommended problems to solve one by one.

So do not read any further if you don't want some advanced unary regex magic spoiled for you. If you do want to take a shot at figuring out this magic yourself, I highly recommend starting by solving some problems in ECMAScript regex as outlined in that post linked above.

So, this regex works quite simply: It starts by subtracting one. Then it finds the largest odd factor, k. Then we divide by k (using the division algorithm briefly explained in a spoiler-tagged paragraph of my factorial numbers regex post). We sneakily do a simultaneous assertion that the resultant quotient is greater than k. If the division matches, we have a Proth number; if not, we don't.

I was able to drop 2 bytes from this regex (43 → 41) using a trick found by Grimy that can futher shorten division in the case that the quotient is guaranteed to be greater than or equal to the divisor.

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

Try it online!


 # 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*$
 

Deadcode

Posted 2016-08-10T22:07:56.617

Reputation: 3 022

1O_o wow, only 48 bytes – ASCII-only – 2019-01-24T02:43:29.633

Neil's is more similar to mine than to Dennis' – H.PWiz – 2019-01-24T08:24:53.827

5

MATL, 9 bytes

qtYF1)EW<

Truthy output is 1. Falsy is 0 or empty output. (The only inputs that produce empty output are 1 and 2; the rest produce either 0 or 1).

Try it online!

Explanation

Let x denote the input. Let y be the largest power of 2 that divides x−1, and z = (x−1)/y. Note that z is automatically odd. Then x is a Proth number if and only if y > z, or equivalently if y2 > 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

Luis Mendo

Posted 2016-08-10T22:07:56.617

Reputation: 87 464

5

Haskell, 55 46 bytes

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

Edit: Thanks to nimi, now 46 bytes

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

X88B88

Posted 2016-08-10T22:07:56.617

Reputation: 91

4Welcome to Programming Puzzles & Code Golf! – Dennis – 2016-08-11T03:00:56.623

Thanks man! Been a lurker here for a while. Big fan btw, jelly is super cool. Wish I could learn but alas, I don't really understand – X88B88 – 2016-08-11T15:16:00.373

2A general tip: if you're just interested in the length of a list created by a comprehension, you can use sum[1| ... ]. Here we can go further and move the equality test in front of the | and check with or if any of them is true: f x=or[k*2^n+1==x|k<-...,n<-...,2^n>k]. – nimi – 2016-08-11T15:33:03.167

Wow. Great tips. I'll definitely revise. – X88B88 – 2016-08-11T15:50:04.527

2

If you're interested in learning Jelly, check out the wiki or join the Jelly room.

– Dennis – 2016-08-11T18:00:35.560

5

Brachylog, 28 bytes

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

Try it online!

Verify all testcases at once. (Slightly modified.)

Explanation

Brachylog, being a derivative of Prolog, is very good at proving things.

Here, we prove these things:

>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

Leaky Nun

Posted 2016-08-10T22:07:56.617

Reputation: 45 011

4

Regex (ECMAScript), 40 38 bytes

-2 bytes thanks to Deadcode

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

Try it online!

Commented version:

# 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*$)

Grimmy

Posted 2016-08-10T22:07:56.617

Reputation: 12 521

Wow, this is very cool. So many different ways to do this problem! – Deadcode – 2019-02-21T20:55:01.423

1

38 bytes: ^x(?=((xx)+?)(\1\1)*$)(?!(\1x\2*)\4*$) (Try it online)

– Deadcode – 2019-02-21T21:12:02.877

4

Julia, 16 bytes

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

Credits to @Dennis for the answer and some golfing tips!

Mama Fun Roll

Posted 2016-08-10T22:07:56.617

Reputation: 7 234

That doesn't work. In Julia, & has the same precedence as *. – Dennis – 2016-08-11T02:58:49.733

1Oh right. Fixed :P I should really test my code. – Mama Fun Roll – 2016-08-11T03:39:22.440

2You can use -~-x instead of (1-x). Also, there's √x instead of x^.5, but it doesn't save any bytes. – Dennis – 2016-08-11T03:40:36.637

4

R, 52 50 bytes

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

The program begins by dividing N-1 (called here P and x) by 2 as long as possible in order to find the 2^npart of the equation, leaving k=(N-1)/2^n, and then computes wether or not k is inferior to 2^n, using the fact that 2^n>x/2^n <=> (2^n)²>x <=> 2^2n>x

Frédéric

Posted 2016-08-10T22:07:56.617

Reputation: 2 059

1You can pull the P= at the beginning, and change the end to 2^n>x and save like 5 or 6 bytes – user5957401 – 2016-08-11T23:14:39.953

2

Retina 0.8.2, 47 bytes

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

Try it online! Explanation: Given a Proth number \$ k · 2^n + 1 \$, you can derive two new Proth numbers \$ (2k±1) · 2^{n + 1} + 1 \$. We can run this in reverse until we obtain a Proth number where \$ k = 1 \$. This is readily performed by transforming the binary representation.

\d+
$*

Convert to unary.

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

Convert to binary.

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

Repeatedly run the Proth generation formula in reverse.

^10*1$

Match the base case of the Proth generation formula.

Edit: I think it's actually possible to match a Proth number directly against a unary number with a single regex. This currently takes me 47 bytes, 7 bytes more than my current Retina code for checking whether a unary number is a Proth number:

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

Neil

Posted 2016-08-10T22:07:56.617

Reputation: 95 035

2

ECMAScript Regex, 42 bytes

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

Try it online! (Using Retina)

I essentially subtract 1, divide by the largest possible odd number k, then check that at least k+1 is left over.

It turns out that my regex is very similar to the one Neil gives at the end of his answer. I use x(xx)* instead of (x*)\2x. And I use a shorter method to check k < 2^n

H.PWiz

Posted 2016-08-10T22:07:56.617

Reputation: 10 962

Wow, this is awesome! Very nicely done. Note that you can make it a little bit faster by changing (\3\3)*)$ to (\3\3)*$) – Deadcode – 2019-01-24T08:35:10.593

Nice job with that Retina code. I didn't know about $= and $.=. It can be improved even better.

– Deadcode – 2019-01-24T09:28:39.110

2

@Deadcode If you're going to nitpick the header and footer, then have some further improvements.

– Neil – 2019-01-24T10:42:43.643

@Neil That looks like good golf, but unfortunately it seems to have a bug. Try single numbers. They don't work.

– Deadcode – 2019-01-24T10:54:47.267

1@Deadcode Sorry, I hadn't realised that single numbers were part of the "spec". – Neil – 2019-01-24T10:59:19.313

2

Brain-Flak, 128 bytes

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

Try it online!

I used a very different algorithm than the older Brain-Flak solution.

Basically, I divide by 2 (rounding up) until I hit an even number. Then I just compare the result of the last division with the two to the power of the number of times I divided.

Explanation:

({
  # (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
([({}[{}(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}

MegaTom

Posted 2016-08-10T22:07:56.617

Reputation: 3 787

2

J, 10 bytes

%:<<:AND-.

Based on @Dennis' bitwise solution.

Takes an input n and returns 1 if it is Proth number else 0.

Usage

   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

Explanation

%:<<: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))

miles

Posted 2016-08-10T22:07:56.617

Reputation: 15 654

Huh. I didn't know about AND. cool! – Conor O'Brien – 2016-11-16T16:24:07.340

1

C (gcc), 29 30 bytes

z;f(x){return--x<(z=x&-x)*z;}

Try it online!

MegaTom

Posted 2016-08-10T22:07:56.617

Reputation: 3 787

1

Hy, 37 bytes

(defn f[n](>(**(&(- n 1)(- 1 n))2)n))

Try it online!

Port of @Dennis' answer.

adl

Posted 2016-08-10T22:07:56.617

Reputation: 351

1

Japt, 12 10 9 bytes

É&1-U)>Uq

Try it online!

Port of Dennis' Jelly answer again. - 1 thanks to @Shaggy.

randomdude999

Posted 2016-08-10T22:07:56.617

Reputation: 789

-1 can be É. – Shaggy – 2019-10-26T01:36:05.490

1

Java 1.7, 49 43 bytes

Another 6 bytes the dust thanks to @charlie.

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

Try it! (ideone)

Two ways, equally long. As with most answers here, credits go to @Dennis of course for the expression.

Taking the root of the righthand side of the expression:

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

Applying power of two to the lefthand side of the expression:

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

Can shave off a single byte if a positive numeric value is allowed to represent 'truthy', and a negative value 'falsy':

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

Unfortunately because of 'Narrowing Primitive Conversion' one cannot simply write this in Java and get correct results:

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

And any attempt to widen 'p' will lead to a compile error because bitwise operators are not supported on i.e. floats or doubles :(

MH.

Posted 2016-08-10T22:07:56.617

Reputation: 261

1f = 47: boolean f(int p){return Math.sqrt(p--)<(p&-p);} – charlie – 2016-08-15T16:15:30.100

1g = 43: boolean g(int p){return p--<(p&-p)*(p&-p);} – charlie – 2016-08-15T16:15:55.367

Nice one! I knew there had to be a way to get rid of the Math.* calls; just couldn't figure out how! Thanks! – MH. – 2016-08-15T18:32:51.000

1

Maple, 100 bytes (including spaces)

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:

Nicely spaced for readbility:

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:

Same idea as several others; divide X by 2 until X is no longer evenly divisible by 2, then check the criteria 2^n > x.

DSkoog

Posted 2016-08-10T22:07:56.617

Reputation: 560

0

C# (.NET Core), 17 bytes

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

Try it online!

Port of MegaTom's C answer.

I attempted a LINQ based solution, but this was too good.

dana

Posted 2016-08-10T22:07:56.617

Reputation: 2 541

0

ink, 60 bytes

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

Try it online!

Based on @DSkoog's Maple answer - it wasn't the first of its kind to be posted, but it was the first of its kind that I saw.

Ungolfed

= 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

Sara J

Posted 2016-08-10T22:07:56.617

Reputation: 2 576

0

x86 Machine Code, 15 bytes

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

These bytes define a function that takes the input argument (an unsigned integer) in the EDI register, following the standard System V calling convention for x86 systems, and it returns the result in the EAX register, like all x86 calling conventions.

In assembler mnemonics:

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)

Try it online!

It's a pretty straightforward solution—and conceptually similar to MegaTom's C version. In fact, you could write this in C as something like the following:

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

but the machine code above is better golfed than what you'll get out of a C compiler, even when it's set to optimize for size.

The only "cheat" here is returning -1 as a "truthy" value and 0 as a "falsy" value. This trick allows the use of the 2-byte SBB instruction as opposed to the 3-byte SETB instruction.

Cody Gray

Posted 2016-08-10T22:07:56.617

Reputation: 2 639

0

Javascript ES7, 16 bytes

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

Port of my Julia answer, which is a port of @Dennis's Jelly answer.

Thanks @Charlie for 2 bytes saved!

Mama Fun Roll

Posted 2016-08-10T22:07:56.617

Reputation: 7 234

n=x=>x-1&1-x>x**.5; n(3) gives me 0 (actually it gives me 0 regardless of input) – eithed – 2016-08-11T13:49:38.610

What browser? It may be just that. – Mama Fun Roll – 2016-08-11T20:03:21.050

Chrome 52. Firefox 48 gives the same answer for n=x=>x-1&1-x>Math.pow(x,0.5); n(3) – eithed – 2016-08-11T23:45:24.520

Ok - it's the operator precedence. It has to be (x-1&1-x) as without it the operator precedence is actually: (x-1)&((1-x)>x**.5) – eithed – 2016-08-11T23:55:45.863

@eithedog fixed – Mama Fun Roll – 2016-08-12T00:08:19.910

Replace = with - and you got a Cheddar program to check proth numbers! – Downgoat – 2016-08-12T01:31:52.817

1-1 byte: x=>x--**.5<(x&-x) or x=>x**.5<(--x&-x) – charlie – 2016-08-12T08:55:51.990

-1 byte: x=>x--<(-x&x)**2 – charlie – 2016-08-15T21:06:18.803

0

Cjam, 11 bytes

Like many of us, piggybacking off of Dennis's excellent solution:

qi_(_W*&2#<

Try it online

A Simmons

Posted 2016-08-10T22:07:56.617

Reputation: 4 005

0

C (137 bytes)

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

Only came to read the answers after I tried it.

Considering N=k*2^n+1 with the conditional of k<2^n (k=1,3,5.. and n=1,2,3..

With n=1 we have one k available to test. As we increase n we get a few more k's to test like so:

n=1 ; k=1

n=2 ; k=1 k=3

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

...

Iterating through those possibilities we can be sure N is not a Prouth number if for a given n the k=1 number obtained is larger than N and no other iteration was a match.

So my code basically "brute-forces" its way into finding N.

After reading the other answers and realizing you can factor N-1 with 2 to find n and then make the conditional of k<2^n, I think my code could be smaller and more efficient using this method.

It was worth a try!

Tested all numbers given and a few "non-Prouth" numbers. Function returns 1 if the number is a Prouth number and 0 if it's not.

IanC

Posted 2016-08-10T22:07:56.617

Reputation: 111