Check whether an integer is a power of 2 without using +,- operations
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)
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.
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:
.,
: turnsn
inton 0..n
(.
duplicate,,
0..n range){2\?}
: to the power of 2%
: map "power of 2" over "0..n" so it becomesn [1 2 4 8 16 ...]
?0>
: checks to see if the array contains the number (0 is greater than index)