Google Foobar:如何查找边缘案例并确定测试用例。蟒

时间:2017-08-21 06:04:16

标签: python google-foobar

问题

  

燃油喷射完美

     

指挥官Lambda已经请求你帮助改进自动装置   LAMBCHOP世界末日的量子反物质燃料喷射系统   设备。这是一个很好的机会让你仔细看看   LAMBCHOP - 当你在它的时候可能会偷偷地进行一些破坏 -   所以你很乐意接受这份工作。

     

量子反物质燃料采用小颗粒,方便   因为LAMBCHOP的许多活动部件都需要加油   一次一个颗粒。但是,小兵将颗粒散装到粪便中   燃料摄入量。您需要找出最有效的排序方式   将颗粒一次性转移到一个颗粒上。

     

燃料控制机制有三个操作:

     

添加一个燃料芯块取出一个燃料芯块将整个组分开   燃料颗粒为2(由于a时释放的破坏性能量)   量子反物质颗粒被切成两半,安全控制将   如果有均匀数量的颗粒,只允许这种情况发生)写   一个名为answer(n)的函数,它将正整数作为字符串   并返回转换所需的最小操作数   颗粒数量为1.燃油进气控制面板只能显示   一个长达309位的数字,所以不会有更多的颗粒   你可以用那么多数字来表达。

     

例如:answer(4)返回2:4 - > 2 - > 1回答(15)返回5:15    - > 16 - > 8 - > 4 - > 2 - > 1

     

测试用例

     

输入:(字符串)n =“4”输出:(int)2

     

输入:(字符串)n =“15”输出:(int)5

这是我的解决方案:

import math
import decimal
def answer(n):
    n = long(n)
    if n <= 1 or n >= long('9' * 309):
        return 0
    # 1. Find closest power of 2
    round_threshold_adjust = math.log(3,2)- (1.5)
    log_n = math.log(n, 2)
    power = log_n - round_threshold_adjust

    # Round power down if X.50000. If n is equally between two powers of 2,
    # choose the lower power of 2. E.g. For 6, choose, 4 not 8
    power2 = long(decimal.Decimal(power).quantize(0, decimal.ROUND_HALF_DOWN))

    # 2. Calculate the difference, add to iterations
    # 3. Take log 2 of that, add that to iteration
    iters = abs(n - 2**power) + power
    return(iters)

我的解决方案目前通过了10个测试用例中的3个。我相信其他测试用例是边缘情况。请您指点我如何识别我的代码失败的位置? (我无法访问测试用例)

以下是我尝试过的一些测试用例:

assert answer(15) == 5
assert answer(4) == 2
assert answer(3) == 2
assert answer(2) == 1
assert answer(6) == 4
assert answer(7) == 4
assert answer(10) == 5
assert answer(1024) == 10
assert answer(1025) == 11
assert answer(1026) == 12
assert answer(1027) == 13
assert answer(768) == 256 + 9

3 个答案:

答案 0 :(得分:1)

如果我理解正确,给定768颗颗粒你需要256 + 9步才能将其转化为1颗颗粒?

我可以分十步完成:

  • 将768除以2
  • 重复7次 - &gt;你最终得到3颗颗粒
  • 减1
  • 减1

我认为你的第一步,加上/减去直到你以2的幂为单位,并不是最快的解决方案。

我不确定如何编写更好的解决方案,但这可能会指向正确的方向。直觉上,我的下一步是查看数字的二进制表示,并将允许的操作转换为该表示。这可能会简化正确算法的创建。

答案 1 :(得分:1)

这是我的解决方法:

#!/usr/bin/python
#fuel-injection-perfection
#Program to count the naximum number of operations needed to recursively divide a number by 2. Add or subtract 1 where needed.
#V2 - Initial version was done using recursion but failed for large numbers due to python limitation & performance issues.  
cnt=0
def divide(x):
    global cnt
    while(x>1):
        if (x & 1==0):
            #Dividing even number by two by shifting binary digits one step to the right.
            x=x>>1
        else:
            a=x+1
            b=x-1
            #counters ac & bc will be used to count trailing 0s
            ac=bc=0
            #count trailing 0's for x+1
            while(a & 1==0):
                a=a>>1
                ac+=1
            #count trailing 0's for x-1
            while(b & 1==0):
                b=b>>1
                bc+=1
            #go with x+1 if it has more trailing 0s in binary format. Exception is number 3 as b10 can be divided in less steps than b100.
            #edge case 3 identified by manually testing numbers 1-10.
            if (ac>bc and x!=3):
                x+=1
            else:
                x-=1
        cnt+=1

def solution(n):
    global cnt
    n=int(n)
    divide(n)
    return cnt

答案 2 :(得分:0)

这是Python3的答案。我创建了两个函数,一个函数加1,另一个函数减1,然后进行比较,从而以最少的步长给出最佳答案。

#function for the adding 1 to the odd number
def np(n):
    c = 0
    while n > 1:
        if n%2 == 0:
            n = n/2
            c += 1
        else:
            n += 1
            c += 1
    return c

#function for the subtracting 1 to the odd number
def nn(n):
    c = 0
    while n > 1:
        if n%2 == 0:
            n = n/2
            c += 1
        else:
            n -= 1
            c += 1
    return c

#Solution function
def solution(n):
    n = int(n)
    if np(n) > nn(n):
        return nn(n)
    else:
        return np(n)

希望这能奏效,加油。