在不使用+,-操作的情况下检查整数是否为2的幂。


30

编写一个程序检查整数是否为2的幂。


输入样例:

8

样本输出:

Yes

输入样例:

10

样本输出:

No

规则:

  • 不要使用+-操作。

  • 使用某种输入流来获取数字。输入不应最初存储在变量中。

  • 最短的代码(以字节为单位)获胜。

您可以使用任何真实/错误的响应(例如true/ false)。您可以假设输入数字大于0


1
是否还允许输出“ true”而不是“ yes”和“ false”而不是“ no”?
ProgramFOX 2014年

2
是的,您可以使用任何正面/负面反应。问题已更新。
gthacoder 2014年

1
将该pred函数应用于整数n时,返回n-1。是否也禁止像这样的函数,它们在禁止的运算符周围是伪装的?
韦恩·康拉德2014年

1
@Wayne就像golfscript )或大多数基于C的语言一样--
门把手

2
我知道现在已经是3年了,但是“ +/-运算符”是不可观察的,或者至少是较弱的定义。
ATaco

Answers:


13

GolfScript,6个字符,不减量

~.3/&!

这是一种不x & (x-1)任何形式使用该方法的解决方案。它使用x & (x/3)代替。;-) 0如果为false,1则输出,如果为true,则输出。

说明:

  • ~ 评估输入字符串以将其转换为数字,
  • .复制它(用于后续&),
  • 3/ 将其除以三(截断),
  • & 计算除法值与原始值的按位与,当且仅当输入为零或2的幂(即最多设置了一位)时,该值才为零,并且
  • ! 从逻辑上将其否定,将零映射到一个,并将所有其他值映射到零。

笔记:

  • 根据明确的规则,零不是有效输入,即使输出,此代码也可以1输入为零。

  • 如果(允许使用GolfScript减量运算符,那么aditsu发布5个字符的解决方案就足够了。但是,这似乎违反了规则的精神~.(&! ,即使不是文字。

  • x & (x/3)几年前,我在Fun Perl邮件列表中想到了这个技巧。(我确定我不是第一个发现它的人,但是我是独立地(重新)发明了它。) 这是原始文章的链接,包括它确实有效的证明。


我认为这确实有点愚蠢,golfscript允许在不实际违反规则的情况下编写OP想要排除的确切解决方案。
Tim Seguine 2014年

1
@Tim:好的,那么这是一个不减量的。;)
Ilmari Karonen 2014年

这怎么工作?例如7/3 = 2 (0010),因此7 & 2 = 0111 & 0010 = 0010最后一位显然不是1
phuclv 2014年

@LưuVĩnhPhúc:不,但第二位是。尝试对二进制进行3的长除法运算,这很显然很明显,如果分红设置了多个,为什么总是会发生这种情况。
Ilmari Karonen 2014年

啊,我误读为“被2整除”
phuclv 2014年

15

杀伤人员地雷(7)

是的,那是7 个字节。现在假设我正在使用IBM代码页907而不是Unicode,然后每个字符都是一个字节:)

0=1|2⍟⎕

0 = mod(log(input(),2),1)


只是想知道,如果给它0或负数会发生什么?
2014年

@aditsu我不知道infinity mod 1是什么,但它肯定应该为零。
Tim Seguine 2014年

1
Indeterminate尝试时,@ TimSeguine Mathematica给了我。
LegionMammal978

7

GolfScript,11(代表1(真)和0(假))

.,{2\?}%?0>

将数字放在堆栈上,然后运行。

GolfScript,22(是/否)

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

我喜欢将1/ 转换0Yes/ No接受与挑战本身一样多的代码的方式:D

警告:效率极低;)对于10000以下的数字,它确实可以正常工作,但是一旦达到如此高的水平,您就会开始注意到轻微的滞后。

说明:

  • .,:转nn 0..n.复制,, 0..N范围)
  • {2\?}:2的幂
  • %:将“ 2的幂”映射到“ 0..n”,因此它变为 n [1 2 4 8 16 ...]
  • ?0>:检查数组是否包含数字(0大于索引)

1
1个字节的短是/否:.,{2\?}%?0<'YesNo'3/=; 同样,我认为您是在通过要求“将数字放入堆栈”来作弊,所以应该以开头~
aditsu

1
在1失败,即2 ^ 0
Joachim Isaksson 2014年

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}

{正确,正确,错误,错误}


4

Perl 6(17个字符)

say get.log(2)%%1

该程序从STDIN get函数获得一行,以2为底计算对数(log(2)),然后检查结果是否除以1(%%1%%除以运算符)。不像GolfScript解决方案那么短,但是我发现这是可以接受的(无论如何,GolfScript赢得了一切),但是速度更快(即使考虑到Perl 6现在很慢)。

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

2
其原因+-被禁止这一挑战,是因为如果x & (x - 1)等于0,则x是2的幂
ProgramFOX

@ProgramFOX:我知道了。有趣的把戏。
Konrad Borowski14年

1
@ProgramFOX但x&~(~0*x)仍然有效。只有两个字符长。
orlp 2014年


4

R,13 11

基于Perl解决方案。返回FALSETRUE

!log2(i)%%1

该参数i表示输入变量。

用户输入的替代版本:

!log2(scan())%%1

4

GolfScript,5岁

输出1为true,0为false。基于user3142747的想法:

~.(&!

注意:(是递减的,希望它不算为-:)
如果是递减的(并且OP的注释表明可能),那么请参考Ilmari Karonen的解决方案
对于Y / N输出,请'NY'1/=在末尾附加(另外7个字节)。


4

Python,31岁

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

31如果您愿意bin(input()).rfind('1')<3
Blender 2014年

@Blender衣冠楚楚。我2==之所以用过,是因为我认为它也适用于非正数。这显然不是规则所必需的,所以……
展位,2014年

1
+1。我本来要张贴print bin(input()).count('1')<2的字符总数为31个,但与您的字符太相似。
Steven Rumbalski 2014年

4

C,48

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

如果允许一元求反,则可以较短;如果不允许负常数,则可以更长。假设两个的补码。
orlp 2014年

*具有比Binary更高的优先级&,您不需要括号。而且如果返回值被接受(仅询问),exit(x&x*-1)则将短得多。
凯文

有一个-x*-1
klingt.net 2014年

@ klingt.net是的,但这是数字常量的一部分。从技术上讲,如现在所说,仅-禁止操作员。
凯文(Kevin)2014年

1
@ klingt.net将其替换为不使用任何符号的版本。
orlp 2014年

4

我决定使用另一种方法,基于人口总数或数字的横向和(1位的数量)。这个想法是,所有的2的幂都有一个1一位,而没有其他的。我添加了一个JavaScript版本,因为我发现它很有趣,尽管它肯定不会赢得任何高尔夫比赛的胜利。

J,14 15个字符(输出0或1)

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

JavaScript,76个字符(输出正确或错误)

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

这使用了附加功能,而附加功能却无法解决。
FUZxxl 2015年

嗯 我不知道我写这篇文章时在想什么...我已经修复了它,因此它实际上遵循了规则。
FireFly

4

9 8 7

!%lnxWO

从标准输入中读取一个数字。

说明:

首先,Z= 0W= 2O= 1。这样的放置WO彼此相邻,而使用21将被解释为21的数量没有分离空间(不想要的额外字符)。在Clip中,模函数(%)在非整数上起作用,因此,要确定某个值v是否为整数,请检查vmod 1 =0。使用Clip语法,写为=0%v1。但是,由于布尔值存储为1(或其他任何值)和0,所以检查是否等于就等于0“不”。为此,Clip具有!运算符。在我的代码中,vlnx2x是stdin的输入,n将字符串转换为数字,然后lab是对数ba。因此,程序将(更易于理解)转换为0 = ((log base 2 of parseInt(readLine)) mod 1)

例子:

8

输出

1

10

输出

0

编辑1:更换012ZOW

编辑2:替换=Z!

也:

佩斯 5

进一步压缩Clip版本,因为Pyth对已评估的输入具有Q值,并且具有log2(a)函数,而不仅仅是一般的log(a,b)。

!%lQ1


3

Mathematica(21)

IntegerQ@Log2@Input[]

没有输入它会更短

IntegerQ@Log2[8]

真正

IntegerQ@Log2[7]


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

1
@alephalpha最后使用24个字节表示UTF-8字符。另一个21字节程序是Log2@Input[]~Mod~1==0
LegionMammal978

2

JavaScript,41个 40个字符

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

工作原理:您可以使用以2为底的对数 l(prompt()) / l(2),如果模1的结果等于0,则其为2的幂。

例如:以8为底的对数后2,得到33 modulo 1等于0,因此返回true。

在以2为底的对数取7后,得到2.8073549220576042.807354922057604 modulo 1等于0.807354922057604,因此返回false。


您无需将输入强制转换为数字。Math.log将已经完成:“以下每个Math对象函数将ToNumber抽象运算符应用于其每个参数...”
apsillers 2014年

它不存在数字误差吗?
Mark Jeronimus 2014年

@MarkJeronimus:我实际上不知道。可能是,但是我还没有遇到错误的结果。
ProgramFOX

2

JavaScript,35岁

适用于字节。

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

46个字符的版本,适用于16位数字。

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

该技巧适用于大多数动态语言。

说明:将数字转换为以2为底,将该字符串解释为以10为底,对9求模以得到数字总和,必须为1。


什么0x2ff这2为基数,1111111111
彼得·泰勒

@PeterTaylor,您说对了,已解决
复制

因此,您要做的真正的工作是检查无余数的10模,但是您使用9刮掉了代码的字符+1
Math chiller

这有点作弊,但是是另一种方法:alert(!(Number.MAX_VALUE%prompt()))
冥王星


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.