+、-演算を使用せずに、整数が2のべき乗かどうかを確認します[終了]


30

整数が2のべき乗かどうかをチェックするプログラムを作成します。


サンプル入力:

8

サンプル出力:

Yes

サンプル入力:

10

サンプル出力:

No

ルール:

  • +-操作を使用しないでください。

  • 何らかの入力ストリームを使用して、数値を取得します。入力は、最初は変数に保存されることは想定されていません。

  • 最短のコード(バイト単位)が優先されます。

真実/偽の応答(たとえば、true/ false)を使用できます。入力数がより大きいと仮定できます0


1
「yes」ではなく「true」、「no」ではなく「false」を出力することもできますか?
ProgramFOX

2
はい、正/負の応答を使用できます。質問が更新されます。
-gthacoder

1
pred整数nは、戻りnに適用される関数、 - 1はまた、禁止禁止オペレータの周りに薄い変装であるこのような機能はありますか?
ウェインコンラッド14年

1
@Wayneはgolfscriptの)、またはほとんどのCベースの言語のように--
ドアノブ

2
私たちは今から3年後のことを知っていますが、「+/-演算子」は観察できません。
アタコ

回答:


13

GolfScript、6文字、減分なし

~.3/&!

これはx & (x-1)どのような形式でメソッドを使用しないソリューションです。x & (x/3)代わりに使用します。;-) 0falseの1場合、trueの場合に出力します。

説明:

  • ~ 入力文字列を評価して数値に変換し、
  • .それを複製します(後続の&
  • 3/ 3で割る(切り捨て)、
  • & 除算された値と元のビット単位のANDを計算します。入力がゼロまたは2のべき乗の場合にのみゼロになります(つまり、最大1ビットが設定されます)。
  • ! これを論理的に否定し、ゼロを1にマッピングし、他のすべての値をゼロにマッピングします。

ノート:

  • 明確化された規則に従って、ゼロは有効な入力はないため1、入力がゼロの場合は出力されますが、このコードは問題ありません

  • GolfScriptの減少演算子(が許可されている場合、aditsu投稿し5文字のソリューションで十分です。ただし、手紙ではないにしても、ルールの精神に反するようです。~.(&!

  • x & (x/3)Fun With Perlメーリングリストで何年も前にこのトリックを思いつきました。(私はそれを最初に発見したわけではないと確信していますが、私はそれを独立して(再)発明しました) 実際の動作の証拠を含む、元の投稿へのリンクです。


本当にばかげていると思いますが、golfscriptを使用すると、OPが除外したい正確なソリューションを、実際にルールを破らずに記述することができます。
ティムセギーン14年

1
@ティム:OK、デクリメントなしの1つです。;)
イルマリカロネン14年

これはどのように機能しますか?例えば7/3 = 2 (0010)、そう7 & 2 = 0111 & 0010 = 0010どの明確に最後のビットが1ではありません
phuclv

@LưuVĩnhPhúc:いいえ、しかし2番目のビットはそうです。バイナリで3による長い除算を実行してみてください。配当に複数のビットが設定されている場合、これが常に発生する理由は明らかです。
イルマリカロネン14年

ああ、私は「2で割り切れる」でこれを読み違える
phuclv

15

APL(7)

はい、それは7 バイトですです。今のところ、Unicodeの代わりにIBMコードページ907を使用しており、各文字が1バイトであると仮定します:)

0=1|2⍟⎕

すなわち 0 = mod(log(input(),2),1)


ただ、0または負の数を指定するとどうなりますか?
aditsu

@aditsu無限大mod 1が何であるかはわかりませんが、0 であってはなりません。
ティムセギーン14年

1
@TimSeguine Mathematica Indeterminateを試してみると私に教えてくれます。
LegionMammal978

7

GolfScript、11(1(true)および0(false)の場合)

.,{2\?}%?0>

スタックに番号を付けて実行します。

GolfScript、22(はい/いいえ)

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

私はどのように変換愛1/ 0Yes/No D:挑戦自体として多くのコードのようになります

警告:非常に非効率的です;)10000までの数値に対しては正常に動作しますが、一度それを高くすると、わずかな遅れに気づき始めます。

説明:

  • .,:になりnますn 0..n.重複、,0..n範囲)
  • {2\?}:2の累乗
  • %:「0..n」の上に「2のべき乗」をマップして、 n [1 2 4 8 16 ...]
  • ?0>:配列に数値が含まれているかどうかを確認します(0はインデックスより大きい)

1
Yes / Noの場合は1バイト短くなり.,{2\?}%?0<'YesNo'3/=ます。また、「スタックに番号を入れてください」と尋ねることでごまかしていると思います~
aditsu

1
1で失敗、つまり2 ^ 0
Joachim Isaksson 14年

6

Mathematica 28

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

2の整数のべき乗の場合、2を底とする対数の分子は1になります(つまり、対数は単位分数です)。

ここでは、推定入力を表示するために関数をわずかに変更します。の#代わりに使用してInput[]追加&し、純粋な関数を定義します。ユーザーが上記の関数で数値を入力した場合に返されるのと同じ回答を返します。

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


一度に複数の数値をテストします。

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

{True、True、False、False}


4

Perl 6(17文字)

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

2
The 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

@ProgramFOX: I see. Interesting trick.
Konrad Borowski

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

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.


Works in Matlab also :)
jub0bs

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

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).


4

Python, 31

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

31 if you do bin(input()).rfind('1')<3
Blender

@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

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

4

C, 48

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

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

* 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

There is a -: x*-1.
klingt.net

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

1
@klingt.net Replaced it with a version that uses no signs.
orlp

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)

This uses addition, which is precluded by the challenge.
FUZxxl

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

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

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.


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

3

Mathematica (21)

IntegerQ@Log2@Input[]

Without input it is a bit shorter

IntegerQ@Log2[8]

True

IntegerQ@Log2[7]

False


⌊#⌋==#&@Log2@Input[]
alephalpha

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

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.


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

Doesn't it suffer from numerical inaccuracies?
Mark Jeronimus

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

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.


What about 0x2ff, which in base 2 is 1111111111?
Peter Taylor

@PeterTaylor You're right, fixed
copy

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

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


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).


Upvoted because this was my solution as well.
Josh Caswell

1
What if you replace == with &?
SimonT

@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

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

there's still a "+" in your program
phuclv

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

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

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

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


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

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

2

C# (54 characters)

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

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 code-golf, try shortening your code a little, at least by removing whitespace
mniip

I think you just mean Int32, not ToInt32...
Chris

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

2
use int instead of Int32 for 2 fewer characters.
Rik

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


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)


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

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)


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

@xfix Thanks, tested and updated.
Joachim Isaksson

1
or even better, a%2<1.
boothby

you have a space after 2. Removing that would save a byte!
Keerthana Prabhakaran

1

Python (33)

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

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


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.


1

C, 65 bytes

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

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

1

Haskell (52 50)

k n=elem n$map(2^)[1..n]
main=interact$show.k.read
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.