检查四边情况的权力

时间:2015-04-05 05:59:48

标签: python algorithm

披露: 此问题来自codewars

  

编写一个方法,如果给定的参数是4的幂,则返回true,如果不是,则返回false。如果参数不是Integer(例如String,Array),那么方法也应返回false。

我不能为我的生活找出我失踪的边缘情况。两个代码示例都产生相同的错误,即“True”应该等于False'进行一些测试。 (当第一个没有工作的时候,我尝试了两种方式,因为我认为第二种方法是肯定的。)

def powerof4(n):
    if n <= 0 or not isinstance(n, int): return False
    else:
        while (n != 1):
            if (n%4 != 0): return False
            else: n = n/4
        return True

import math
def powerof4(n):
    if ((not isinstance(n, int)) or n&(n-1) != 0 or n == 0):
        return False

    #Now, I cheat, since 4^n = (2^n)^2
    reduce_to_2 = math.sqrt(n)

    if math.floor(reduce_to_2) != reduce_to_2:
        return False
    else:
        reduce_to_2 = int(reduce_to_2)
        return reduce_to_2&(reduce_to_2 - 1) == 0

4 个答案:

答案 0 :(得分:3)

你的第一个问题是你正在检查参数的类型是int,但是从大于2 ^ 32的数字开始,对于代码战所使用的Python 2来说是不正确的。

下一个错误是,如果您在代码大战中打印测试失败的值,您会看到调用powerof4(True)isinstance(True, (int,long))True,因为bool是int的子类。

在您的第一个代码中将您的类型检查更改为

if n <= 0 or type(n) not in (int,long): return False

为问题添加其他变体。当我最初解决这个问题时,我做了一些小小的事情:)

def powerof4(n):
    if type(n) not in (int, long):
        return False
    bin_repr = bin(n)[2:]
    return bin_repr[0]=="1" and bin_repr.count("0")%2==0 and bin_repr.count("1")==1

答案 1 :(得分:1)

有一个不太明显的问题。在Python 2中,数字可能太大而不适合int,而是long而是:

>>> isinstance(1000000000000000000000000000000, int)
False

而Python 3将返回

>>> isinstance(1000000000000000000000000000000, int)
True

任何CPython上的最简单的算法(* isinstance检查除外)可以是

def powerof4(n):
    if n <= 0 or not isinstance(n, (int, long)):
        return False
    return hex(n).rstrip('0') in ('0x1', '0x4')

将数字转换为十六进制,并删除尾随零;当且仅当十六进制表示为1或4后跟任意数量的零时,数字是4的幂。 (提示:如果它是1后跟零,它将是16的幂)。


使用按位逻辑:

test = 1
while n < test:
    test <<= 2
return n == test

在Python 2.7和3.3+中,这更容易,不需要循环:

b = n.bit_length()
return bool(b & 1) and 1 << (b - 1) == n

答案 2 :(得分:1)

有一种更简单的方法。

import math

def powerof4(n):
    return math.log(n, 4) % 1 == 0

答案 3 :(得分:0)

喜欢这个吗?

def isPowerOf4(n):
    try:
        while n:
            if n==1:
                return True
            if ((n>>2)<<2) != n:
                return False
            n >>= 2
    except:
        return False
    return False