Check whether an integer is a power of 2 without using +,- operations

30

8

Write a program that checks if the integer is a power of 2.


Sample input:

8

Sample output:

Yes

Sample input:

10

Sample output:

No

Rules:

  • Don't use +,- operations.

  • Use some sort of input stream to get the number. Input is not supposed to be initially stored in a variable.

  • The shortest code (in bytes) wins.

You can use any truthy/falsy response (for instance, true/false). You may assume that input number is greater than 0.

gthacoder

Posted 12 years ago

Reputation: 941

Question was closed 8 years ago

Simple answer:log2 then check if it has numbers under the fp – Matthew Roh – 9 years ago

Can input be unary? – Comrade SparklePony – 9 years ago

1Is it also allowed to output "true" instead of "yes" and "false" instead of "no"? – ProgramFOX – 12 years ago

2Yes, you can use any positive/negative response. Question is updated. – gthacoder – 12 years ago

@gthacoder You may want to clarify input requirements, I'm almost feeling like I'm cheating using a variable with the value to check as input. Is that ok, seeing that GolfScript passes the value on the stack? – Joachim Isaksson – 12 years ago

1The pred function, when applied to an integer n, returns n - 1. Are functions such as this, which are thin disguises around the forbidden operator, also forbidden? – Wayne Conrad – 12 years ago

1@Wayne just like golfscript's ), or most c-based languages' --. – Doorknob – 12 years ago

1Can we output 1 or 0? 'T' or 'F'? – Mark Plotnick – 12 years ago

1@JoachimIsaksson Good point. Input is supposed to be typed by user. Question is updated. – gthacoder – 12 years ago

Requiring the input from a stream automatically penalizes languages such as AS3 or Java which don't have that sort of capability within arm's reach. Allowing "input" variables would level the playing field. – IQAndreas – 12 years ago

1What is the range of valid input? This is important because a number of answers here break if the input is 0. – Peter Taylor – 12 years ago

Don't worry about 0. Input number is supposed to be greater than 0. Question is updated. – gthacoder – 12 years ago

@gthacoder Is -- alowed for C(++)? And unary - (negate)? What about negative constants? (-1) – orlp – 12 years ago

1@nightcracker Question is created with idea that you can't use the fact that if n & (n - 1) is equal to 0, then n is a power of 2 (reason why +, - are forbidden). Otherwise, you can use any operators. – gthacoder – 12 years ago

@gthacoder But see my answer, I don't use + or - and it still works. I do use -1 though. – orlp – 12 years ago

I am not seeing the need for plus or minus so much. It seems pretty easy to do it without. – Tim Seguine – 12 years ago

Can you use return value instead of explicitly printing? – Kevin – 12 years ago

It is supposed to be a complete program with input and output. – gthacoder – 12 years ago

If we use + in a regex, is that OK? – O-I – 12 years ago

@O-I + OPERATION is forbidden, so + symbol in a regular expression is OK. I found you rewrote your answer without + anyway. – gthacoder – 12 years ago

@gthacoder My C answer is smaller than vershov's. – orlp – 12 years ago

@nightcracker Yes, you are right. My bad. Sorry. Question is updated. – gthacoder – 12 years ago

@gthacoder Add some bonus for code that works also for 0 (return False). Many answers do not work for this case (should crash if use log, or return wrong answer). – Gari BN – 12 years ago

Can you add Perl 6? It's a separate language to Perl 5, even with confusing name. – Konrad Borowski – 12 years ago

@xfix Good point. They differ fundamentally indeed. Question is updated. – gthacoder – 12 years ago

if -1 as a constant is allowed I can get the javascript down to 28 characters (cannot post, need reputation!) alert(((a=prompt())&a*-1)>1) – serakfalcon – 12 years ago

1alert(!((a=prompt())&(a/3))) is also 28 characters and avoids the - sign altogether – serakfalcon – 12 years ago

Is there an upper limit to the range of valid inputs? – Khuldraeseth na'Barya – 8 years ago

2I know we're 3 years in the future now, but "+/- operators" is non-observable, or at the very least weakly defined. – ATaco – 8 years ago

Answers

13

GolfScript, 6 chars, no decrements

~.3/&!

Here's a solution that doesn't use the x & (x-1) method in any form. It uses x & (x/3) instead. ;-) Outputs 0 if false, 1 if true.

Explanation:

  • ~ evals the input string to turn it into a number,
  • . duplicates it (for the subsequent &),
  • 3/ divides it by three (truncating down),
  • & computes the bitwise AND of the divided value with the original, which will be zero if and only if the input is zero or a power of two (i.e. has at most one bit set), and
  • ! logically negates this, mapping zero to one and all other values to zero.

Notes:

  • Per the clarified rules, zero is not a valid input, so this code is OK, even though it outputs 1 if the input is zero.

  • If the GolfScript decrement operator ( is allowed, then the 5-character solution ~.(&! posted by aditsu is enough. However, it seems to go against the spirit of the rules, if not the letter.

  • I came up with the x & (x/3) trick years ago on the Fun With Perl mailing list. (I'm sure I'm not the first to discover it, but I did (re)invent it independently.) Here's a link to the original post, including a proof that it actually works.

Ilmari Karonen

Posted 12 years ago

Reputation: 19 513

My Pyth !%lQ1 beats this :) as long as it was invented after the question was posted, which I'm not sure about. – bcsb1001 – 10 years ago

I think it is a bit silly really, golfscript allows one to write the exact solution that the OP wanted to exclude without actually breaking the rules. – Tim Seguine – 12 years ago

1@Tim: OK, here's one without decrements, then. ;) – Ilmari Karonen – 12 years ago

how can this work? For example 7/3 = 2 (0010), so 7 & 2 = 0111 & 0010 = 0010 which clearly the last bit is not 1 – phuclv – 12 years ago

@LưuVĩnhPhúc: No, but the second bit is. Try doing long division by 3 in binary and it's pretty obvious why this always happens if the dividend has more than one bit set. – Ilmari Karonen – 12 years ago

ah I misread this with "divisible by 2" – phuclv – 12 years ago

I am impressed. It is even shorter now. – Tim Seguine – 12 years ago

15

APL (7)

Yes, that's 7 bytes. Assume for the moment that I'm using IBM codepage 907 instead of Unicode and then each character is a byte :)

0=1|2⍟⎕

i.e. 0 = mod(log(input(),2),1)

marinus

Posted 12 years ago

Reputation: 30 224

1@TimSeguine Mathematica gives me Indeterminate when I try that. – LegionMammal978 – 10 years ago

Just wondering, what happens if you give it 0 or a negative number? – aditsu quit because SE is EVIL – 12 years ago

@aditsu I don´t know what infinity mod 1 is, but it certainly shouldn't be zero. – Tim Seguine – 12 years ago

7

GolfScript, 11 (for 1 (true) and 0 (false))

.,{2\?}%?0>

Put the number on the stack and then run.

GolfScript, 22 (for Yes/No)

.,{2\?}%?0>'Yes''No'if

I love how converting 1/0 to Yes/No takes as much code as the challenge itself :D

Warning: EXTREMELY inefficient ;) It does work fine for numbers up to 10000, but once you get that high you start to notice slight lag.

Explanation:

  • .,: turns n into n 0..n (. duplicate, , 0..n range)
  • {2\?}: to the power of 2
  • %: map "power of 2" over "0..n" so it becomes n [1 2 4 8 16 ...]
  • ?0>: checks to see if the array contains the number (0 is greater than index)

Doorknob

Posted 12 years ago

Reputation: 68 138

11 byte shorter for Yes/No: .,{2\?}%?0<'YesNo'3/=; also I think you're cheating by asking to "Put the number on the stack", you should start with a ~. – aditsu quit because SE is EVIL – 12 years ago

1Fails on 1, which is 2^0 – Joachim Isaksson – 12 years ago

6

Mathematica 28

Numerator[Input[]~Log~2]==1

For integer powers of 2, the numerator of the base 2 log will be 1 (meaning that the log is a unit fraction).

Here we modify the function slightly to display the presumed input. We use # in place of Input[] and add & to define a pure function. It returns the same answer that would be returned if the user input the number in the above function.

    Numerator[#~Log~2] == 1 &[1024]
    Numerator[#~Log~2] == 1 &[17]

True
False

Testing several numbers at a time.

    Numerator[#~Log~2] == 1 &&/@{64,8,7,0}

{True, True, False, False}

DavidC

Posted 12 years ago

Reputation: 24 524

4

Perl 6 (17 characters)

say get.log(2)%%1

This program gets a line from STDIN get function, calculates logarithm with base 2 on it (log(2)), and checks if the result divides by 1 (%%1, where %% is divides by operator). Not as short as GolfScript solution, but I find this acceptable (GolfScript wins everything anyway), but way faster (even considering that Perl 6 is slow right now).

~ $ perl6 -e 'say get.log(2)%%1'
256
True
~ $ perl6 -e 'say get.log(2)%%1'
255
False

Konrad Borowski

Posted 12 years ago

Reputation: 11 185

2The reason that + and - are forbidden for this challenge, is because if x & (x - 1) is equal to 0, then x is a power of 2. – ProgramFOX – 12 years ago

@ProgramFOX: I see. Interesting trick. – Konrad Borowski – 12 years ago

1@ProgramFOX But x&~(~0*x) still works. That's only 2 characters longer. – orlp – 12 years ago

4

Octave (15 23)

EDIT: Updated due to user input requirement;

~mod(log2(input('')),1)

Lets the user input a value and outputs 1 for true, 0 for false.

Tested in Octave, should work in Matlab also.

Joachim Isaksson

Posted 12 years ago

Reputation: 1 161

Works in Matlab also :) – jub0bs – 12 years ago

4

R, 13 11

Based on the Perl solution. Returns FALSE or TRUE.

!log2(i)%%1

The parameter i represents the input variable.

An alternative version with user input:

!log2(scan())%%1

Sven Hohenstein

Posted 12 years ago

Reputation: 2 464

4

GolfScript, 5

Outputs 1 for true, 0 for false. Based on user3142747's idea:

~.(&!

Note: ( is decrement, hopefully it doesn't count as - :)
If it does (and the OP's comments suggest that it might), then please refer to Ilmari Karonen's solution instead.
For Y/N output, append 'NY'1/= at the end (7 more bytes).

aditsu quit because SE is EVIL

Posted 12 years ago

Reputation: 22 326

4

Python, 31

print 3>bin(input()).rfind('1')

boothby

Posted 12 years ago

Reputation: 9 038

31 if you do bin(input()).rfind('1')<3 – Blender – 12 years ago

@Blender Well-spotted. I'd used 2== because I figured it should work for nonpositive numbers too. That's explicitly not required by the rules, so... – boothby – 12 years ago

1+1. I was going to post print bin(input()).count('1')<2 at a total of 31 characters, but it's too similar to yours. – Steven Rumbalski – 12 years ago

4

C, 48

main(x){scanf("%i",&x);puts(x&~(x*~0)?"F":"T");}

orlp

Posted 12 years ago

Reputation: 37 067

Can be shorter if unary negate is allowed, is longer if negative constants aren't allowed. Assumes two's complement. – orlp – 12 years ago

* has higher precedence than binary &, you don't need the parens. And if return value is accepted (just asked) exit(x&x*-1) would be much shorter. – Kevin – 12 years ago

There is a -: x*-1. – klingt.net – 12 years ago

@klingt.net yes, but that's part of a numerical constant. Technically, as it is worded now, only the operator - is forbidden. – Kevin – 12 years ago

Either way, I think you can get away with ~0 instead of -1 if necessary. – Kevin – 12 years ago

@Kevin But ~ has a higher presedence than *, so the parens are necessary. – orlp – 12 years ago

Oh yes, missed that ~ – Kevin – 12 years ago

That was also my initial idea, but i thougt that every -/+ sign was forbidden. I should read the specification the next time more carefully ;) – klingt.net – 12 years ago

1@klingt.net Replaced it with a version that uses no signs. – orlp – 12 years ago

4

I decided to to use another approach, based on the population count or sideways sum of the number (the number of 1-bits). The idea is that all powers of two have exactly one 1 bit, and no other number does. I added a JavaScript version because I found it amusing, though it certainly won't win any golfing competition.

J, 14 15 chars (outputs 0 or 1)

1=##~#:".1!:1]1

JavaScript, 76 chars (outputs true or false)

alert((~~prompt()).toString(2).split("").map(Number).filter(Boolean).length)

FireFly

Posted 12 years ago

Reputation: 7 107

This uses addition, which is precluded by the challenge. – FUZxxl – 11 years ago

Huh. I've no idea what I was thinking when I wrote this... I've fixed it now so it actually follows the rules. – FireFly – 11 years ago

4

Clip, 9 8 7

!%lnxWO

Reads a number from stdin.

Explanation:

To start with, Z = 0, W = 2 and O = 1. This allows placing of W and O next to each other, whereas using 2 and 1 would be interpreted as the number 21 without a separating space (an unwanted extra character). In Clip, the modulo function (%) works on non-integers, so, to work out if some value v is an integer, you check if v mod 1 = 0. Using Clip syntax, this is written as =0%v1. However, as booleans are stored as 1 (or anything else) and 0, checking if something is equal to 0 is just 'not'ing it. For this, Clip has the ! operator. In my code, v is lnx2. x is an input from stdin, n converts a string to a number and lab is log base b of a. The program therefore translates (more readably) to 0 = ((log base 2 of parseInt(readLine)) mod 1).

Examples:

8

outputs

1

and

10

outputs

0

Edit 1: replaced 0, 1 and 2 with Z, O and W.

Edit 2: replaced =Z with !.

Also:

Pyth, 5

Compresses the Clip version even further, as Pyth has Q for already evaluated input and a log2(a) function instead of just general log(a, b).

!%lQ1

bcsb1001

Posted 12 years ago

Reputation: 450

3

Javascript (37)

a=prompt();while(a>1)a/=2;alert(a==1)

Simple script that just divides by 2 repeatedly and checks the remainder.

Joachim Isaksson

Posted 12 years ago

Reputation: 1 161

1same idea with a for loop (also 37 chars) for(i=prompt();i>1;i/=2){}alert(i==1) – Math chiller – 12 years ago

3

Mathematica (21)

IntegerQ@Log2@Input[]

Without input it is a bit shorter

IntegerQ@Log2[8]

True

IntegerQ@Log2[7]

False

ybeltukov

Posted 12 years ago

Reputation: 1 841

1@alephalpha That ends up using 24 bytes for the UTF-8 characters. Another 21-byte program is Log2@Input[]~Mod~1==0. – LegionMammal978 – 10 years ago

⌊#⌋==#&@Log2@Input[] – alephalpha – 12 years ago

2

JavaScript, 41 40 characters

l=Math.log;alert(l(prompt())/l(2)%1==0);

How this works: you take the logarithm at base 2 using l(prompt()) / l(2), and if that result modulo 1 is equal to zero, then it is a power of 2.

For example: after taking the logarithm of 8 on base 2, you get 3. 3 modulo 1 is equal to 0, so this returns true.

After taking the logarithm of 7 on base 2, you get 2.807354922057604. 2.807354922057604 modulo 1 is equal to 0.807354922057604, so this returns false.

ProgramFOX

Posted 12 years ago

Reputation: 8 017

You don't need to cast the input to a number; Math.log will do that already: "Each of the following Math object functions applies the ToNumber abstract operator to each of its arguments..."

– apsillers – 12 years ago

Doesn't it suffer from numerical inaccuracies? – Mark Jeronimus – 12 years ago

@MarkJeronimus: I actually don't know. It could be, but I haven't yet encountered an incorrect result. – ProgramFOX – 12 years ago

2

JavaScript, 35

Works for bytes.

alert((+prompt()).toString(2)%9==1)

46 character version, Works for 16 bit numbers.

x=(+prompt()).toString(2)%99;alert(x==1|x==10)

The trick works in most dynamic languages.

Explanation: Convert the number to base 2, interpret that string as base 10, do modulo 9 to get the digit sum, which must be 1.

copy

Posted 12 years ago

Reputation: 6 466

This is kinda cheating but another method: alert(!(Number.MAX_VALUE%prompt())) – Pluto – 11 years ago

What about 0x2ff, which in base 2 is 1111111111? – Peter Taylor – 12 years ago

@PeterTaylor You're right, fixed – copy – 12 years ago

so the real thing your doing is checking for modulo 10 without a remainder, but you used 9 to shave a character of your code, +1! – Math chiller – 12 years ago

2

K/Kona (24 17)

d:{(+/(2_vs x))~1

Returns 1 if true and 0 if false. Any power of 2 has a single bit equal to 1:

2_vs'_(2^'(!10))
(,1
1 0
1 0 0
1 0 0 0
1 0 0 0 0
1 0 0 0 0 0
1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0)

(this prints out all the powers of 2 (from 0 to 9) in binary)

So I sum up all the components of the binary expression of x and see if it's equal to 1; if yes then x=2^n, otherwise nope.

...knew I could make it smaller

Kyle Kanos

Posted 12 years ago

Reputation: 4 270

@gthacoder: I made the code smaller, hope you can update you main post to reflect this! – Kyle Kanos – 12 years ago

Doesn't this use addition? And doesn't the question, err, forbid that? – zgrep – 8 years ago

2

python 3, 38

print(1==bin(int(input())).count('1'))

python, 32

However, the code doesn't work in every version.

print 1==bin(input()).count('1')

Notice that the solution works also for 0 (print False).

Gari BN

Posted 12 years ago

Reputation: 624

Upvoted because this was my solution as well. – jscs – 12 years ago

1What if you replace == with &? – SimonT – 12 years ago

@SimonT This is not true. Replacing the '==' with '&' will print 1 for every number that has odd number of '1' in its binary representation. Check for example 7=111. There are 3=11 ones. It will return 11&1 = 1. – Gari BN – 12 years ago

2

Perl 5.10+, 13 + 1 = 14 chars

say!($_&$_/3)

Uses the same method from an old FWP thread as my GolfScript entry. Prints 1 if the input is a power of two, and an empty line otherwise.

Needs to be run with perl -nE; the n costs one extra char, for a total of 14 chars. Alternatively, here's an 18-character version that doesn't need the n:

say!(($_=<>)&$_/3)

Ilmari Karonen

Posted 12 years ago

Reputation: 19 513

2

Ruby — 17 characters (fourth try)

p /.1/!~'%b'%gets

My current best is a fusion of @steenslag's answer with my own. Below are my previous attempts.

Ruby — 19 characters (third try)

p /10*1/!~'%b'%gets

Ruby — 22 characters (second try)

p !('%b'%gets)[/10*1/]

Ruby — 24 characters (first try)

p !!('%b'%gets=~/^10*$/)

O-I

Posted 12 years ago

Reputation: 759

there's still a "+" in your program – phuclv – 12 years ago

I know. :-/ I've asked for clarification whether '+' and '-' are strictly forbidden, or whether they can be used in other contexts besides addition and subtraction. I'm in the process of rewriting regardless. – O-I – 12 years ago

Great improvement. It seems like it's the best Ruby result so far. I updated the leaders table in the question text. – gthacoder – 12 years ago

@gthacoder Just combined steenslag's regex with my binary formatting. Definitely can't take all the credit. – O-I – 12 years ago

2

C# (54 characters)

 Math.Log(int.Parse(Console.ReadLine()),2)%1==0?"Y":"N"

Merin Nakarmi

Posted 12 years ago

Reputation: 247

The task clearly states that input is not stored in a variable, it should be obtained from an input stream of some kind (like stdin), also, this is [tag:code-golf], try shortening your code a little, at least by removing whitespace – mniip – 12 years ago

I think you just mean Int32, not ToInt32... – Chris – 12 years ago

Ya ya. Thanks for pointing out Chris. Earlier it was Convert.ToInt32 and I wanted to change it to Int32.Parse to shorten it. :D – Merin Nakarmi – 12 years ago

2use int instead of Int32 for 2 fewer characters. – Rik – 12 years ago

2

Rebmu (9 chars)

z?MOl2A 1

Test

>> rebmu/args [z?MOl2A 1] 7
== false

>> rebmu/args [z?MOl2A 1] 8 
== true

>> rebmu/args [z?MOl2A 1] 9 
== false

Rebmu is a constricted dialect of Rebol. The code is essentially:

z? mo l2 a 1  ; zero? mod log-2 input 1

Alternative

14 chars—Rebmu does not have a 'mushed' bitwise AND~

z?AND~aTIddA 3

In Rebol:

zero? a & to-integer a / 3

rgchris

Posted 12 years ago

Reputation: 304

1

SmileBASIC, 29 bytes

This is a fairly uncreative and basic (no pun intended) answer. 0 is false, 1 is true.

INPUT N
A=LOG(N,2)?(0OR A)==A

We know that if n is a power of 2, then log2(n) will be an integer. So, this calculates the base-2 log of N, our input number, and checks if it is an integer using the following method.

In SB there are actually two number types, doubles and integers. It also has automatic coercion between doubles and ints depending on the context. When a float is coerced to an int, it simply truncates the fraction and produces an integer which represents the whole part (assuming that number is in the valid integer size–signed 32 bit.) The bitwise OR operator OR expects both of its terms to be integers, so it will automatically cast doubles to ints. Thus, 0 OR double simply produces that double's whole part, which we then check against the original value. If these two are equal, it is a power of two.

snail_

Posted 12 years ago

Reputation: 1 982

A<<0 is shorter and doesn't need parentheses. And you can maybe use > or < instead of == – 12Me21 – 9 years ago

1

Haskell, 47 bytes

(or 21 bytes if input/output can be function argument/return)

f 0=0
f 1=1
f n=f$n/2
main=interact$show.f.read

Returns 1 for powers of 2, and 0 otherwise.

Opportunist

Posted 12 years ago

Reputation: 159

Welcome to PPCG! Check out our Haskell golfing rules. In particular, just functions are fine, you don't need the last line. (Edit: Actually, this challenge is really old (2014) before functions were default. Maybe stick with the program.)

– xnor – 9 years ago

@xnor Thanks. I'm aware that this site usually accepts functions as answers, but I was unsure of the rules on function vs full program because the question states "Use some sort of input stream to get the number" and the other haskell answer does the same. Also, I didn't realize that this question was so old. Is it considered rude to neco old questions here?

– Opportunist – 9 years ago

1

Python 2, 29,25 bytes

x=input();print x&x*~0==x

Try it online!

using x&x*~~x/~x is a modified version of x&(~x+1)! Since the later uses + had to use ~x which is equivalent to -x-1!

  • saved 4 bytes by using x*~0 instead of x*~~x/~x!

Keerthana Prabhakaran

Posted 12 years ago

Reputation: 759

1

GTB, 46 bytes

2→P`N[@N=Pg;1P^2→P@P>1E90g;2]l;2~"NO"&l;1"YES"

Timtech

Posted 12 years ago

Reputation: 12 038

1

Python 2.7 (30 29 39 37)

EDIT: Updated due to user input requirement;

a=input()
while a>1:a/=2.
print a==1

Brute force, try to divide until =1 (success) or <1 (fail)

Joachim Isaksson

Posted 12 years ago

Reputation: 1 161

you have a space after 2. Removing that would save a byte! – Keerthana Prabhakaran – 9 years ago

1not a%2 can be written as a%2==0. Granted, this would be longer in many languages, but not Python. – Konrad Borowski – 12 years ago

@xfix Thanks, tested and updated. – Joachim Isaksson – 12 years ago

1or even better, a%2<1. – boothby – 12 years ago

1

APL (12 for 0/1, 27 for yes/no)

≠/A=2*0,ιA←⍞ 

or, if we must output text:

3↑(3x≠/A=2*0,ιA←⍞)↓'YESNO '

Read in A. Form a vector 0..A, then a vector 20..2A (yes, that's way more than necessary), then a vector comparing A with each of those (resulting in a vector of 0's and at most one 1), then xor that (there's no xor operator in APL, but ≠ applied to booleans will act as one.) We now have 0 or 1.

To get YES or NO: multiply the 0 or 1 by 3, drop this number of characters from 'YESNO ', then take the first 3 characters of this.

Mark Plotnick

Posted 12 years ago

Reputation: 1 231

1

Ruby, 33, 28, 25

p /.1/!~gets.to_i.to_s(2)

steenslag

Posted 12 years ago

Reputation: 2 070

1

Python, 35

print bin(input()).strip('0')=='b1'

Doesn't use not only +/- operations, but any math operations aside from converting to binary form.

Other stuff (interesting, but not for competition):

I have also a regexp version (61):

import re;print re.match(r'^0b10+$',bin(input())) is not None

(Love the idea, but import and match function make it too long)

And nice, but boring bitwise operations version (31):

x=input();print x and not x&~-x

(yes, it's shorter, but it uses ~-x for decrement which comtains - operation)

Ivan Anishchuk

Posted 12 years ago

Reputation: 111

boothby's answers uses the same idea as my first, but is shorter :( – Ivan Anishchuk – 12 years ago

1

C, 65 bytes

main(k){scanf("%i",&k);while(k&&!(k%2))k/=2;puts(k==1?"T":"F");}

vershov

Posted 12 years ago

Reputation: 111

You can cut off 5 chars by using main(k){..., relying on the implicit int typing. It might be UB, but this is code golf. NEVER use something like that in production, of course. – Kevin – 12 years ago

1

Haskell (52 50)

k n=elem n$map(2^)[1..n]
main=interact$show.k.read

Zeta

Posted 12 years ago

Reputation: 681

1

Python (33)

print int(bin(input())[3:]or 0)<1

Blender

Posted 12 years ago

Reputation: 665

int(bin(input()*2)[3:])<1 also works from the python shell with only 25 chars. – gmatht – 12 years ago

1

OCaml - 43 or 45

Since no-one has submitted an OCaml solution, I submit one inspired by nightcrackers C solution.

There is some debate as to whether the operator - includes unary negation. Other entries have managed to sidestep the issue by finding a solution that is equally short without unary negation. I instead give two answers:

let x=read_int()in 0=x land lnot(x*(-1));;

and

let x=read_int()in 0=x land lnot(x*lnot 0);;

the ;; ends a group of statements in the Ocaml interpreter and causes the result to be printed as - : bool = false or - : bool = true, which are clear negative/positive answers as required by the question.

gmatht

Posted 12 years ago

Reputation: 676

1

Python 2 - 23

x=input();print x&x/3<1

This is a direct port of the golf-script solution above, that beats the current best python solution by 8 characters. The order of operations works out amazingly well here.

isaacg

Posted 12 years ago

Reputation: 39 268

1

Bash + dc + grep, 24

dc -e2o?p|grep -c ^10\*$

Reads from stdin. Outputs "1" if a power of 2 and "0" otherwise:

$ dc -e2o?p|grep -c ^10\*$
8
1
$ dc -e2o?p|grep -c ^10\*$
10
0
$ 

Pure Bash (only builtins), 40

[[ `read a;printf %o $a` =~ ^[124]0*$ ]]

Reads from stdin. Returns success (0) if a power of 2 and failure (1) otherwise:

$ [[ `read a;printf %o $a` =~ ^[124]0*$ ]]
8
$ echo $?
0
$ [[ `read a;printf %o $a` =~ ^[124]0*$ ]]
10
$ echo $?
1
$

Digital Trauma

Posted 12 years ago

Reputation: 64 644

1

Java 7, 124

This is pretty short in Java. Most of the program is just boilerplate code and to read the integer.

class H{public static void main(String[]b){int a=new java.util.Scanner(System.in).nextInt();System.out.println((a&a/3)<1);}}

TheNumberOne

Posted 12 years ago

Reputation: 10 855

I know it's been two years, but you can golf it by 2 bytes by simply using print instead of println. – Kevin Cruijssen – 9 years ago

0

AutoHotkey 33 bytes

a=%1%
While a>1
a:=a/2
Send % a=1

Input parameters are assigned to variables 1, then 2, etc. It means you have to assign it to another variable before using it in math because AHK will think you mean the number 1 and not the variable 1. It would be slightly shorter still but AHK treats a/=2 as a a floor divide by 2 instead of just a divide by 2 if and only if it is the left-most assignment operation on a line. I'm sure it has its reasons.


This is, surprisingly, slightly shorter than the method that uses log():

a=%1%
Send % Mod(Log(a)/Log(2),2)=0

Engineer Toast

Posted 12 years ago

Reputation: 5 769

0

Excel 19 bytes

=MOD(LOG(A1,2),2)=0

Nothing magical or tricky. Input is from cell A1. Returns TRUE or FALSE.

Engineer Toast

Posted 12 years ago

Reputation: 5 769

0

Haskell, 41 bytes

f n=mod(2^n)n<1
main=interact$show.f.read

Alternative:

main=interact$show.(<1).(mod=<<(2^)).read

Try it online!


43 bytes

main=interact$show.(1==).until(<2)(/2).read

Try it online. Halves x until it's less than 2, and checks if the result is 1.

xnor

Posted 12 years ago

Reputation: 115 687

0

PHP, 86 chars

function P($a,$c){if($c==$a)return 1;if($c>$a)return 0;return P($a,$c*2);}echo P(x,2);

Replace x with the number you want to test.

Vereos

Posted 12 years ago

Reputation: 4 079

I'm almost sure this can be shorter, by use of ternary operator... then again, ternary operator in PHP is rather strange, so you may need some parenthesis to enforce precedence. – Konrad Borowski – 12 years ago

0

PHP (58)

<?php $a=fgets(STDIN);while($a%2==0)$a/=2;echo $a==1?1:0;

Simple divide-by-2 loop and remainder check.

Joachim Isaksson

Posted 12 years ago

Reputation: 1 161

This shaves off few characters <?php $a=$argv[1];while(!($a%2))$a/=2;echo $a==1?1:0; Basically $argv[1] instead of fgets(STDIN)and!($a%2)instead ofa%2==0` – dkasipovic – 12 years ago

0

ActionScript 3 (63 characters*)

var r = Math.log(prompt())/Math.log(2);
return ( (r > 0) && (int(r) == r) );

* I'm going to ignore the fact that AS3 doesn't have a built-in prompt() method, (and hope AS3's lack of implementation doesn't get counted against me).

Extra white-space left in for readability and clarity, but not counted, since they can be removed before execution.

IQAndreas

Posted 12 years ago

Reputation: 1 180

I'm also going to assume that the user didn't enter something funny like NaN. – IQAndreas – 12 years ago

In my opinion, using functions that don't exist is cheating. Just change this into JavaScript code, and replace int(r) with ~~r. – Konrad Borowski – 12 years ago

@xfix No! I refuse to support the use of an un-typed and classless language! Bah, humbug! – IQAndreas – 12 years ago

It's not that you use types or classes here. Also, you have definitely too many parens (return doesn't need parenthesis, and && has bigger precedence than both parenthesis groups). – Konrad Borowski – 12 years ago

1

@xfix Fine, you win, but may the records show that I still conscientiously object to the use of JavaScript as a serious programming languages.

– IQAndreas – 12 years ago

0

GTB, 17

With 1/0

`Ar?A>1:A/2→A~A=1

With YES/NO (31)

`Ar?A>1:A/2→A@A=1$~"YES"#~"NO"&

Timtech

Posted 12 years ago

Reputation: 12 038

0

JavaScript (43 characters when compacted, 35 for some browsers)

Readable version:

var r = Math.log(prompt()) / Math.LN2;
alert( (r > 0) && (~~r == r) );

Compacted version (credit goes to FireFly for helping me shave off even more characters):

r=Math.log(prompt())/Math.LN2;alert(~~r==r)

JS Fiddle: http://jsfiddle.net/IQAndreas/LFYg7/2/

EDIT: On the off chance that you use FireFox 25+ or any other browser with Math.log2(), only 35 characters are required (thanks to xfix for this suggestion):

r=Math.log2(prompt());alert(~~r==r)

IQAndreas

Posted 12 years ago

Reputation: 1 180

You can remove the final semicolon and var. Also, JavaScript has Math.log2() function. – Konrad Borowski – 12 years ago

@xfix Nice, I also used several of your suggestions from the other answer. Thanks! – IQAndreas – 12 years ago

I save two characters by removing the >0, in which case the function will return 0 or false, but my soul is tormented enough by the shortcuts taken in this code anyway. – IQAndreas – 12 years ago

@xfix Regarding your edit, there is no Math.log2() function yet (or at least it's not standard across all browsers), it's still in the draft stage: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2#Browser_compatibility

– IQAndreas – 12 years ago

Oh, yeah, my mistake. I just prefer to use EcmaScript 6 for my code golf in JavaScript. But yeah, that makes sense - sometimes I mistake ES5 and ES6 stuff. – Konrad Borowski – 12 years ago

You can divide by Math.LN2 instead of Math.log(2). You can also get rid of the repeated Math via with: with(Math)r=log(prompt())/LN2;alert(r>0&&~~r==r) (untested, but should work). (Edit: oh, duh, with(Math) doesn't win any additional characters..) – FireFly – 12 years ago

@FireFly Thanks, LN2 saved me three more characters. – IQAndreas – 12 years ago

Oh, I think you can drop x>0&& too, since the task specifies "check whether an integer", and Math.log takes negative integers to NaN, 0 to -Infinity and positive integers to positive values, and both NaN and -Infinity give you false for r == ~~r. – FireFly – 12 years ago

@FireFly Dropping that will let through a passed in value of 1, but should that count as a power of 2? – IQAndreas – 12 years ago

I'd say yes, as 2⁰ = 1. – FireFly – 12 years ago

0

Scheme 40

(display(=(mod(/(log(read))(log 2))1)0))

It displays #t for true and #f for false (the booleans in Scheme).

For true compatibility you need to add (import(rnrs)) or (import(scheme)) (for r7rs) but it works without that in ikarus and in most REPLs.

Sylwester

Posted 12 years ago

Reputation: 3 678

0

Perl 53

perl -pe '$_=unpack"b*",pack"L",$_;s!0!!g;s!111*!no!;s!1!yes!'

I can shave off 1 character if i use + in the re, not used for adding.

hildred

Posted 12 years ago

Reputation: 1 329

1Use the y/// operator for shorter code: say unpack('b*',pack'l',$_)=~y/1//==1 – nwellnhof – 12 years ago

0

Golfscript (17 14)

Works from input, using the base builtin for binary conversion and counting ones;

~2base{1=},,1=

Old version, 17 chars, without builtin conversions and without using the decrement operator as a substitute for -;

~2*:a 1{2*.a<}do=
  • ~ lifts the input to an integer on the stack
  • 2* multiplies by 2 to solve 2^0 problem
  • :a sets the variable a to the number to search for and leaves it on stack
  • 1{2*.a<}do sets start value 1 and doubles as long as number<a
  • = compares the number to search for with the number generated

Joachim Isaksson

Posted 12 years ago

Reputation: 1 161

0

J - 17 15 bytes - not . ceiling (0==) . mod 1 . log2 . to_i . read keyboard

Result is 1 for True and 0 for False

0=1|2^.".1!:1,1

Yes/No version

(0=1|2^.".1!:1,1){'No',:'Yes'

swish

Posted 12 years ago

Reputation: 7 484

Something weird seems to have happened to the title of your answer. You might want to fix it. – Ilmari Karonen – 12 years ago

0

D (83 chars with boilerplate, 17 chars to get the solution)

import std.stdio;
void main(){
    int i;
    readf("%d", &i);
    while(!(i%2))i/2;
    writeln(i==1);
}

while the number is even divide by 2, when the result is 2 then it was a power of 2

ratchet freak

Posted 12 years ago

Reputation: 1 334

Um, It says no - operation. I see one. – Tim Seguine – 12 years ago

1@Tim not anymore you don't :P – ratchet freak – 12 years ago

0

Perl 69

$_=<>;chomp;$s=1;while($s<$_){$s*=2;$r="Yes" if $s==$_}print $r||"No"

DVK

Posted 12 years ago

Reputation: 251

158: $_=<>;chomp;++$s;($s*=2)==$_&&($r=Yes)while$s<$_;say$r||No – tobyink – 12 years ago

1I suppose ++ might count as addition. This is the same length: $_=<>;chomp;$s=1;($s*=2)==$_&&($r=Yes)while$s<$_;say$r||No – tobyink – 12 years ago

0

Perl 5 (36 or 29 bytes)

say sprintf('%b',<>)=~/^10*$/?Yes:No

If we don't want to strictly output "Yes" or "No", then we can go shorter:

say sprintf('%b',<>)=~/^10*$/

This second version outputs "1" for true, and "" for false.

tobyink

Posted 12 years ago

Reputation: 1 233

0

C99 94 92 71

int main(){int a,i=1;scanf("%d",&a);while(i){if(a==i)return 1;i<<=1;}}

readable

#include <stdio.h>

int main() {
    int a, i=1;
    scanf("%d",&a);
    while(i){
        if(a==i) return 1;
        i<<=1;
    }
}

What it does

It XORs the input value with a power of 2, until the bit of variable i is shifted out and the value becomes 0. Only if the input value is also a power of 2 (with other words, only one bit in the input was set) the XOR resolves to zero.

The input will be compared with a power of 2 value, that is left shifted in every iteration (in other words multiplied by 2) and returns if both are equal, thus the input is also a power of 2.

On success 1 is returned, 0 otherwise.

Why C99?

Because the return value of a C program is implicitly defined as 0, if not specified, since C99. Compile with: gcc -std=c99 ...

klingt.net

Posted 12 years ago

Reputation: 876

!(a^i) instead of (a^i)==0 – Kevin – 12 years ago

1Actually, I believe you can just do if(a==i) – Kevin – 12 years ago

0

autohotkey -45bytes in txt file and 48 bytes with editor and lang.

MsgBox % mod(log(k)/log(2), 1) ? "no" : "yes"

user13542

Posted 12 years ago

Reputation: 1

Can't you remove the whitespace? this is [tag:code-golf] after all... – mniip – 12 years ago

code golf? it is not. it is autohotkey. thanks for commenting in btw. – user13542 – 12 years ago

1I mean the question is tagged with [tag:code-golf], which means that the entries need to be as short as possible – mniip – 12 years ago

You should add a count of the bytes, and use \n=\n to make the language and count be bold. – luser droog – 12 years ago

if i remove spaces the code will break. – user13542 – 12 years ago

luser droog, done, thanks.:) – user13542 – 12 years ago

0

PHP, 55

<? if(fmod(log($argv[1],2),1)==0) echo 1; else echo 0;

Eg:

# php pow2.php 8
1
# php pow2.php 9
0

PHP w/ interactive I/O, 107

<? $h=fopen('php://stdin','r');$n=trim(fgets($h));fclose($h);if(fmod(log($n,2),1)==0) echo 1; else echo 0;

Sammitch

Posted 12 years ago

Reputation: 509

1the OP didn't ask you to output "yes" or "no" so you can shave your code down to: <? echo fmod(log($argv[1],2),1)==0 – serakfalcon – 12 years ago

@serakfalcon shaved. Thanks for the suggestion. – Sammitch – 12 years ago

0

Python (40 char)

p=lambda n:n>0and(n<2or n%2<1and p(n/2))

Works for negative number also (returning False)

C (39 chars)

p(n){return n>0&&(n<2||n%2<1&&p(n/2));}

or with trick, (work on old compilers without optimizing, withoput return operator returns last evaluated expression value) (32 chars)

p(n){n>0&&(n<2||n%2<1&&p(n/2));}

AMK

Posted 12 years ago

Reputation: 506

0

Java 143

Thinking binary ( a power of 2 has always only one bit set so the compare with the integer with ionly highest bit set can only return true on powers of 2 (including the ominous 0 :P)

Update: shaved 2 bytes off due to a derp

enum P{public static void main(String[]a){int i=new java.util.Scanner(System.in).nextInt();System.out.print(i==(Integer.highestOneBit(i)*1));}}

Ungolfed

enum P;
{
    public static void main(String[]a)
    {
        int i = new java.util.Scanner(System.in).nextInt();
        System.out.print(i==(Integer.highestOneBit(i)*1));
    }
}

masterX244

Posted 12 years ago

Reputation: 3 942

0

BASH, 48

x=`echo "obase=2;$1"|bc|rev|bc`;echo "$x==1"|bc

Takes input as a command line argument and returns 1 for true and 0 for false. You can easily modify it to echo Yes/No, but the bash if-construct makes it much longer.

dfernig

Posted 12 years ago

Reputation: 191

No need for x at all - 37 bytes: echo \bc<<<"obase=2;$1"|rev|bc`==1|bc` – Digital Trauma – 11 years ago

39 characters: x=`bc<<<"obase=2;$1"|rev|bc`;bc<<<$x==1 – nyuszika7h – 11 years ago

0

~-~! - 37

'=|*;~~==%['&*/~~]*|:'&^==~[@|1|]@|0|

I had to improvise with the number input...it's the Unicode value of the character you enter. Teehee.

This uses a recursive /2 solution.

cjfaure

Posted 12 years ago

Reputation: 4 213

0

JavaScript (EcmaScript 6) - 13 Characters

f=x=>!(x&x/3)

Creates a function f that takes a value and returns true (or false) if it is a power of 2 (or not) and will output the answer to the console.

Based on Ilmari Karonen's answer (so I included a few others of my own, below).

EcmaScript 6 can be run on FireFox or SpiderMonkey - no other browser/JavaScript engine yet supports EcmaScript 6 arrow functions. If you want to prompt for input then you can call it as an anonymous function (23 characters):

(x=>!(x&x/3))(prompt())

But it's less characters skip the function bit and just do:

JavaScript - 19 Characters

!((a=prompt())&a/3)

Will do the same as above but should run in all browsers and will prompt for input and output to the console (or in SpiderMonkey, you can replace prompt() [which doesn't exist as SpiderMonkey is command-line based] with readline()).

JavaScript (EcmaScript 6) - 20 Characters

f=x=>x>1?f(x/2):x==1

Creates a function f and, when called, will output the answer to the console.

JavaScript - 29 Characters

for(a=prompt();a>1;)a/=2;a==1

Same as above but will prompt the user for input and output to the console.

JavaScript - 32 Characters

for(a=prompt();!(a%2);)a/=2;a==1

JavaScript - 34 Characters

for(a=prompt();a==(a|0);)a/=2;a==1

MT0

Posted 12 years ago

Reputation: 3 373

0

dc, 13 bytes

?[2~0=m]dsmxp

Reads input from STDIN. Input is not explicitly stored in a variable, though it is stored on the stack - not sure if this too much rule-bending.

Successively divides by 2 until a 1 remainder is found. Since dc doesn't have any native concept of truthy/falsey, I'm taking the liberty of defining my own here. 0 means true, any +ve integer means false:

$ for i in 1 2 3 15 16 17 65535 65536; do dc pow2.dc <<< $i; done
0
0
1
7
0
8
32767
0
$ 

Digital Trauma

Posted 12 years ago

Reputation: 64 644

0

Batch - 24 bytes

Stealing Ilmari's winning GolfScript answer...

@cmd/c"set/a!(%1/3^&%1)"

See explanation here.

unclemeat

Posted 12 years ago

Reputation: 2 302

0

Note: This question is older than Pyth, so this answer is not eligible to win.

Pyth, 5 bytes

!%lQ1

This is essentially identical to @marinus's APL answer. We take the log base 2 of the input, take it mod 1, and take the logical not.


Pyth, 6 bytes

!stjQ2

This answer converts the input to base 2, removes the first digit, sums the remainder, and takes the logical not.

isaacg

Posted 12 years ago

Reputation: 39 268

0

Python (23)

int(bin(input())[3:])<1

Willem

Posted 12 years ago

Reputation: 1 528

You need a print statement in there... – FlipTack – 9 years ago

-1

Python 3.6, 30 bytes

from enum import _power_of_two

... there's a builtin lurking in the stdlib ...

pppery

Posted 12 years ago

Reputation: 3 987

-1

Python:

print 0==int(bin(input())[3:] or 1)

saykou

Posted 12 years ago

Reputation: 11

210 is a false positive – Joachim Isaksson – 12 years ago

-1

Easiest way: An unsigned number is a power of 2 if only 1 BIT is set: if (!(n&(n-1))). Subtracting 1 inverts all BITs. if n=10000000b (80h/128), n&01111111b=0

if (!(n&(n-1)))
  printf("%d is a power of 2", n);
else
 printf("%d is NOT a power of 2", n);

// to get specific power of 2, search from
// right to left for 1st 0 BIT

int pow2(unsigned n) { // is power of 2?
  if (n&(n-1) || n<2) // if not, return 0
  return 0;
  n--;
  for (int i=1; n&1<<i; i++);
  return i; // 2^i
}

m3ntal

Posted 12 years ago

Reputation: 1

1using + or - is not allowed... – ratchet freak – 12 years ago

1did you even read the spec? you are using both + and - – Tim Seguine – 12 years ago

-2

Basic BASH command

# assume integer is stored in variable QUERY
[ "$[(${QUERY}/2)*2]" = "$QUERY" ] && echo "Is even" || echo "Is odd"

Takes advantage of how the shell does integer division, and drops any remainder.

weylin

Weylin Piegorsch

Posted 12 years ago

Reputation: 1

2"Power of 2" is not the same thing as "even". – Ilmari Karonen – 12 years ago

-3

#include <stdio.h>

int main(){
    int i=16;
    if(i&(i-1))
        printf("No\n");
    else
        printf("Yes\n");
    return 0;
}

Deepankar

Posted 12 years ago

Reputation: 1

1You use - operation. – gthacoder – 12 years ago

3First of all, you use the - operator, that's not allowed. Also, the question is a code-golf, so the intension is that you code should be as small as possible, so remove whitespace if possible, and include the language and the character count in your answer. – ProgramFOX – 12 years ago