这个数字是-2的整数次幂吗?


41

有很多聪明的方法来确定数字是否为2的幂。这不再是一个有趣的问题,因此让我们确定给定的整数是否为-2的整数次幂。例如:

-2 => yes: (-2)¹
-1 => no
0 => no
1 => yes: (-2)⁰
2 => no
3 => no
4 => yes: (-2)²

规则

  • 您可以编写程序或函数,并使用接收输入和提供输出的任何标准方法

  • 您的输入是一个整数,如果该整数是-2的整数次幂,则输出必须是一个真实值,否则,则必须是一个虚假值。不允许其他输出(例如警告消息)。

  • 通常的整数溢出规则适用:您的解决方案必须能够在语言的假设(或实际)版本中使用任意大整数,默认情况下,所有整数都是无界的,但是如果您的程序由于实现而在实践中失败不支持大整数,这不会使解决方案无效。

  • 您可以使用任何编程语言,但是请注意,默认情况下,这些漏洞是禁止的。

获奖条件

这是一场比赛:字节数最少(在您选择的编码中)的答案是获胜者。


17
@KritixiLithos我不明白为什么要这么做。没有i这样的整数(-2)^i = 2
Fatalize'Apr

2
指数是正数还是-0.5应该有效,因为它是 2 ^(-1)
Xcoder先生17年

1
@ Mr.Xcoder,因为输入始终是整数值,所以不需要(或可能)使用负指数。
Toby Speight

1
@SIGSEGV也许i是不自然的
Xcoder先生17年

2
@Jason,在您的语言中支持的数量/自然数量-请参阅第三条规则。这是代码高尔夫,因为它需要一个客观的获胜标准才能成为话题,“令人满意的解决方案”并不能解决这个问题(尽管我很喜欢Mathematica的答案-让我感到惊讶)。
Toby Speight

Answers:


26

Mathematica,22个字节

EvenQ@Log2@Max[#,-2#]&

在线尝试!(相反,在此解决方案也可以使用数学的情况下。)

我尝试了一段时间的按位运算符解决方案,虽然确实存在一个解决方案,但最终找到了可能更简单的方法:

  • Max[#,-2#]如果输入为负,则将其乘以-2。乘以另一个因子-2不会改变该值是否为-2的幂。但是,现在的所有奇数权力-2已化作甚至权力-2
  • 但是,即使-2的幂也等于2的幂,因此我们可以使用simple Log2@...并检查结果是否为整数(以检查其是否为2的幂)。这已经节省了两个字节Log[4,...](另一种查看-2次方的方法)。
  • 另外,检查一个值是否为偶数比检查一个整数是否短:我们可以通过使用EvenQ代替来节省三个字节IntegerQ

考虑到-2的偶数次幂是4的整数次幂是否有帮助?我喜欢将值乘以-2来使所有结果都为正的想法-尽管失望的是到目前为止没有看到任何混乱。
Toby Speight

5
@TobySpeight将它们视为2的幂实际上节省了5个字节。我起初使用4的幂,但Log[4,...]长于Log2@...IntegerQ长于EvenQ
Martin Ender

16

果冻,5个字节

æḟ-2=

在线尝试!

这个怎么运作

æḟ-2=  Main link. Argument: n

æḟ-2   Round n towards 0 to the nearest power of -2.
    =  Test if the result is equal to n.

12

Python,46个字节

-2个字节感谢@ovs。

def g(x):
 while x%-2==0!=x:x/=-2
 return x==1

功能与用法:

g(4) # put your number between the brackets

在线尝试!


print g(8)版画False
Felipe Nardi Batista

2
@FelipeNardiBatista不是吗?
Xcoder先生17年

2
抱歉,我的例子很糟糕,print g(4)是否也一样
Felipe Nardi Batista

等等,有一个小错误,很快修复它
Xcoder先生

1
我放了;一个换行符,而不是换行符。固定@FelipeNardiBatista
先生17年

11

果冻,6个字节

b-2S⁼1

在线尝试!

这是基于果冻如何将整数转换Ñ到任何任意碱基,通过转换这样做Ñ到阵列,其中每个整数是数字d(的Ñ,其可具有一个值0≤ V d < 。这里,我们将0的索引数字从右边,所以每数位增加了V dd以形成ÑV d < V dd < BB d = d 1,因此每个可能的如果我们忽略(NB中的前导0,则N仅具有一个唯一的表示形式。

在此,d=输入,B= -2。ñ = d = 1个d = V dd ⇔1= V dV d = 1,和,因为我们没有加入权力的任何其他倍数,每隔V将为0眼下,该数组应为1,并与d 0 串联。由于Jelly 1从左开始索引,我们应该检查数组的第一个元素是否为1,所有其他元素是否为0。

嗯...一切都好吧?没有?这是怎么回事?哦,是的,我有个更好的主意!首先,让我们获取数组中所有整数的总和,将其视为整数数组而不是以2为底的数字。如果为1,则表示只有一个1,而所有其他整数均为0。由于不能有前导零,除非是0 -2(总和为0≠1),则第一个整数必须为非零。数组中唯一的非零整数是1,因此它必须是第一个。因此,这是数组中所有整数之和为1的唯一情况,因为一对正整数的最小可能总和为Σ{1,1} = 2,因为最小正整数为1 。基本表示形式中的每个整数都是非负的,因此,总和为1的唯一方法是只有一个1,而所有其他整数均为0。因此,我们可以检查是否在整数中求和数组是1。

代码是这样的:

b-2S⁼1 Main link. Arguments: d
b-2    Convert d to base -2.
   S   Take the sum.
    ⁼1 Check if the sum is equal to 1.

1
ew,这种解释花了一些时间写……
暴民埃里克(Erik the Outgolfer)'17

我不希望看到一个长程序的解释会是什么样子……
boboquack

1
@boboquack在这里,我正在解释为什么我使用基本转换的东西。我认为对于长程序的解释不会这么长。一个帖子最多可以包含30000个markdown字符,而且对于更长程序的说明反而会更简洁。另外,我已经读了更长的解释,它们并不是那么无聊。
暴民埃里克(Erik the Outgolfer)'17年



10

Excel,40 36字节

CallumDA保存了4个字节

Excel当然可以做到,但更正错误会增加11个字节

=IFERROR(-2^IMREAL(IMLOG2(A1)),1)=A1

输入在单元格中A1。输出为TRUEFALSE

如果允许返回错误值FALSE#NUM!错误,则返回值只有25个字节:

=-2^IMREAL(IMLOG2(A1))=A1

这是一个小的改进:=IFERROR(-2^IMREAL(IMLOG2(A1)),1)=A1
CallumDA'4

1
@CallumDA谢谢!我试图找到一种使用复数函数的方法,但是我想到的所有内容都更长。
Engineer Toast

9

05AB1E,8个字节

Y(IÄÝm¹å

在线尝试! 或作为测试套件

说明

Y(         # push -2
  IÄÝ      # push range [0 ... abs(input)]
     m     # element-wise power
      ¹å   # check if input is in the resulting list

为什么要下票?
Kritixi Lithos'4

@KritixiLithos:好像有人否决了所有高尔夫语言。
Emigna'4-4-6

6
也注意到了。尽管我已经很久没有接触PPCG了,但是我已经知道,标准语言中的创意和有趣的解决方案比高尔夫语言中的3字节解决方案受到更多的欢迎。但是,有些人(不幸地)否定了高尔夫语言中非常有创意的解决方案,只是因为他们认为所有内容都是内置的,并且不了解算法的出色程度(尽管用高尔夫语言编写)。+1令人难以置信的解决方案@Emigna
Xcoder先生17年

ÄLY(småO为8. Y(sÄLm¢Z8 ......没关系,所有8
魔术八达通金塔

9

JavaScript(ES6),37 28 24字节

f=x=>!x|x%2?x==1:f(x/-2)

感谢Arnauld,节省了4个字节。

f=x=>!x|x%2?x==1:f(x/-2)

console.log(f(-2));
console.log(f(-1));
console.log(f(0));
console.log(f(1));
console.log(f(2));
console.log(f(3));
console.log(f(4));


当我单击“运行代码段”时,为什么会看到一些错误(在true / false值之前)?
numbermaniac

@numbermaniac我不确定,也许您使用的浏览器不完全支持ES6?
汤姆(Tom),

哭泣,刷新并重试,没有错误。不知道第一次发生了什么。
numbermaniac


8

MATL9 8字节

2_y|:q^m

在线尝试!验证所有测试用例

这个怎么运作

以输入-8为例

2_    % Push -2
      % STACK: -2
y     % Implicit input. Duplicate from below
      % STACK: -8, -2, -8
|     % Absolute value
      % STACK: -8, -2, 8
:     % Range
      % STACK: -8, -2, [1 2 3 4 5 6 7 8]
q     % Subtract 1, element-wise
      % STACK: -8, -2, [0 1 2 3 4 5 6 7]
^     % Power, element-wise
      % STACK: -8, [1 -2 4 -8 16 -32 64 -128]
m     % Ismember. Implicit display
      % STACK: 1

如果我正确理解了您的解释,那么在给定input的情况下n,这会创建一个大小数组n作为中间步骤。效率不是这里的标准的好工作!
Toby Speight

2
@Toby当然!这就是代码高尔夫,谁在乎效率?:-D
路易斯·门多


6

PHP,41字节

for(;$argn%-2==0;)$argn/=-2;echo$argn==1;

PHP,52字节

echo($l=log(abs($argn),2))==($i=$l^0)&&$argn>0^$i%2;

PHP,64字节

使用正则表达式

echo preg_match("#^".($argn>0?1:"1+0")."(00)*$#",decbin($argn));


5

JavaScript(ES6),21个字节

返回0或的递归函数true

f=n=>n==1||n&&f(n/-2)

这个怎么运作

这不包括任何显式测试(例如n,奇数或abs(n)小于1),以便在输入的确切乘方不是 -2 时,尽早停止递归。

仅当n等于1或时,我们才退出0

但是,这确实可行0,因为由于算术下溢,任何IEEE-754浮点数在被除以2(或-2)次之后最终都会舍入到。

测试用例



4

Java 7,55个字节

boolean c(int n){return n==0?0>1:n%-2==0?c(n/-2):n==1;}

说明:

boolean c(int n){  // Method with integer parameter and boolean return-type
  return n==0 ?    //  If n is zero:
    0>1//false     //   Return false
   : n%-2==0 ?     //  Else-if n mod -2 is zero:
    c(n/-2)        //   Recursive call for the input divided by -2
   :               //  Else:
    n==1;          //   Return if n is one
}                  // End of method

测试代码:

在这里尝试。

class M{
  static boolean c(int n){return n==0?0>1:n%-2==0?c(n/-2):n==1;}

  public static void main(String[] a){
    for(int i = -2; i <= 4; i++){
      System.out.println(i + ": " + c(i));
    }
  }
}

输出:

-2: true
-1: false
0: false
1: true
2: false
3: false
4: true

非递归方式缩短了5个字节:boolean c(int n){while(0==n%-2)n/=-2;return 1==n;}
奥利维尔·格雷戈雷

@OlivierGrégoire不幸的是,这n=0在Java中不起作用,因为0%-2==0它将true0/-2现在仍然存在0,从而导致无限循环,这就是为什么我将此n==0?0>1部分添加到递归方法中的原因。
凯文·克鲁伊森

很好发现!
奥利维尔·格雷戈尔


3

Javascript(ES7),45个字节

x=>-1**Math.log2(Math.abs(x))*Math.abs(x)==x

Math.abs(x)的长度大于x> 0?x:-x,11字节至8字节。您还应该能够执行-2 ** ...而不是-1 ...来删除第二个Math.abs(x)
fəˈnɛtɪk

ES7的具体功能是什么?
Arjun

@ DobbyTheFree-Elf **是。
Qwertiy

3

Perl 6,21个字节

{$_==(-2)**(.lsb//0)}

试试吧

展开:

{  # bare block lambda with implicit parameter 「$_」

  $_                  # is the input
  ==                  # equal to
  (-2)**( .lsb // 0 ) # -2 to the power of the least significant bit of the input
}

请注意,0.lsbNilreturn用作数字时会产生警告,因此使用define或operator  //
(认为//作为||与不同的倾斜)

隐式调用方法,该方法调用没有引人注目的地方$_。(.lsb

也适用于.msb


我喜欢这一个!
tale852150


3

Python,24字节

lambda n:n*n&n*n-1<n%3%2

在线尝试!

位技巧k&k-1==0检查是否k为2的幂(或k==0)。检查k=n*nas可以n*n&n*n-1==0告诉我们是否abs(n)为2的幂。

要进一步查看是否n为-2的幂,我们只需要检查即可n%3==1。这是可行的,因为mod 3的值-2等于1,因此其幂为1。相反,它们的取反是2 mod 3,当然0等于0 mod 3。

我们结合检查n*n&n*n-1==0n%3==1成一个单一的表达。第一个可以用<1for 编写==0,因为它永远不会为负。在n%3==1相当于n%3%2,给予0或1。因此,我们可以将它们组合成n*n&n*n-1<n%3%2


2

R,22个字节

从stdin获取输入,返回TRUEFALSE相应地返回。

scan()%in%(-2)^(0:1e4)

我不是100%肯定这是一个有效的答案,因为它仅适用于R大小限制以下的整数,并且如果整数是无界的,则将不起作用。但是,规则规定:

通常的整数溢出规则适用:您的解决方案必须能够在语言的假设(或实际)版本中使用任意大整数,默认情况下,所有整数都是无界的,但是如果您的程序由于实现而在实践中失败不支持大整数,这不会使解决方案无效。

在R的假设版本中,允许无界整数,那么对于相同的字节数,我们可以使用以下代码:

scan()%in%(-2)^(0:Inf)

当然,在实数R中,以上代码仅给出Error in 0:Inf : result would be too long a vector


2

bc 88字节

bc -l <<< "n=$1;q=l(sqrt(n*n));p=4*a(1);((n<1)*c(q/l(2)*p/2)+(n>1)*(s(q/l(4)*p)))^2==0"

我有这样一个文件neg2.sh和它打印1的权力-20以其他方式

我知道这很长,但是很有趣

测试

$ for i in {-129..257}; do echo -n "$i: "; ./neg2.sh $i; done | grep ': 1'
-128: 1
-32: 1
-8: 1
-2: 1
1: 1
4: 1
16: 1
64: 1
256: 1

说明

主体有两个部分,都试图将的幂等于0 -2

q=l(sqrt(n*n))               % ln of the absolute value of the input
p=4*a(1)                     % pi: arctan(1) == pi/4
q/l(2) -> l(sqrt(n*n))/l(2)  % change of base formula -- this gives
                             % the power to which 2 is raised to equal
                             % sqrt(n*n). It will be an integer for 
                             % numbers of interest
n<1                          % 1 if true, 0 if false. for negative
                             % numbers check for powers of 2
n>1                          % for positive numbers, check for powers
                             % of 4
c(q/l(2)*p/2)                % cos(n*pi/2) == 0 for integer n (2^n)
s(q/l(4)*p)                  % sin(n*pi) == 0 for integer n (4^n)
(....)^2==0                  % square the result because numbers are
                             % not exactly zero and compare to 0

我没想到三角函数!好答案!
Toby Speight


2

傅立叶,53字节

I~X1~N~G0(0-2*G~GX*X~PG*G>P{1}{0~O~N}G{X}{1~O0~N}N)Oo

我将在以后打高尔夫球,但是它的概要是:

X = User input
G = N = 1
Loop until N = 0
    G = -2 * G
    P = X*X 
    If G*G > P then
        N = O = 0
    End if
    If G = X then
        O = 1
        N = 0
    End if
End loop
Print O

当输出是0用于falsey1truthy

在线尝试!


在算法描述中最好不要使用P变量并写出如果G * G> X * X然后...?
RosLuP

@RosLuP那会更好,但是傅立叶会简单地将其视为(G*G > X)*X
Beta Decay

2

卡西欧BASIC,76字节

请注意,这是我的计算器所说的76个字节。

?→X
0→O
While Abs(X)≥1
X÷-2→X
If X=1
Then 1→O
IfEnd
WhileEnd
O

这是我对Casio BASIC的首次尝试...我从未意识到我可以在计算器上编写如此出色的程序:D


1

Python 2.7,40个字节

a=input()
while a%-2==0:a/=-2
print a==1

对于长度为43个字节的原始代码,感谢Xcoder先生。由于我没有足够的声誉发表评论,因此不得不将其发布为单独的答案。


这是同一回事,因为我已经使答案版本通用,因此它在Python 2和3中都可以使用。如果要在Python 3中进行此操作,则应该添加int(input())超出了限制的内容该def样功能。此外,在python 3中,您必须使用print()哪个会浪费1个字节。这就是为什么我选择这种方式的原因,因为在Python 3中它会更长……
Xcoder先生17年

1

视网膜,27字节

+`(1+)\1
$1_
^(1|-1_)(__)*$

在线尝试!

以一元形式输入,这对于Retina来说是相当标准的。前两行基于Tutorial条目的前两行代码进行部分一元到二进制转换(任何多余的1s都会导致匹配失败,反之亦然),而最后一行则检查四次幂或负次幂两个。

+`(1+)\1\1\1
$1_
^(-1)?1_*$

在线尝试!

这次我做了部分一元至四进制的转换。四的^1_*$幂的最终结果为,而二的负奇数的最终结果为^-11_*$

+`\b(1111)*$
$#1$*
^(-1)?1$

在线尝试!

这次,我将保持四分之三,然后检查1-11结束。

+`\b(1+)\1\1\1$
$1
^(-1)?1$

在线尝试!

另一种除以四的方法。而且仍然令人讨厌的27个字节...


1

方案,60字节

(define(f n)(cond((= 1 n)#t)((<(abs n)1)#f)(#t(f(/ n -2)))))

递归解决方案。

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.