用Python跳出框框思考

本文是从我的个人博客中交叉发布的。 您可以在以下位置找到所有精美的原始文章:

http://motomastyle.com/thinking-outs...x-with-python/介绍:

我最近遇到

这项工作在论坛上发布 。 它有一个有趣的脑筋急转弯作为申请的要求。 脑筋急转弯的说法是:“以7为基数连续不包含三个零的2的最大幂的指数是多少?” 唯一的规定是申请人使用Python解决该问题。 我的初步方法:

我对这个问题的初步态度是直截了当的。 我构建了三个函数,BaseSeven将一个数字转换为七个底数,HasThreeZeros将一个数字转换为整数并检查是否有三个零,FindWithoutZeros是我程序的主循环。 下面列出了我的问题的代码:

def BaseSeven(num):
    powersOfSeven = 1;
    res = 0;
    while num / powersOfSeven > 6: powersOfSeven = powersOfSeven * 7
    while powersOfSeven != 1:
        res = res * 10 + int(num / powersOfSeven)
        num = num - int(num / powersOfSeven) * powersOfSeven
        powersOfSeven = powersOfSeven / 7
    res = res * 10 + num
    return res 
def HasThreeZeros(num):
    return str(num).find("000") != -1 
def FindWithoutZeros(power):
    lastWithoutThreeZeros = power
    failures = -1
    num = pow(2, power)
    while failures <= lastWithoutThreeZeros:
        if HasThreeZeros(BaseSeven(num)):
           failures = failures + 1
        else:
            failures = 0
            lastWithoutThreeZeros = power
            print power
        power = power + 1
        num = num * 2
        if (float(power) / 100) == int(power / 100): print "CheckPoint:", power
    return lastWithoutThreeZeros 
print FindWithoutZeros(1)
该解决方案既快速又肮脏,尽管严重缺乏优雅性和速度。 该解决方案的最大问题是程序不断对大量运算进行运算。 当指数攀升到上千时,需要花费一分钟以上的时间来建立,转换和检查单个数字。

我对自己说:“没有必要这样做,这是一种更好的方法。”

第二回合

带着一杯新咖啡,我开始进一步分析问题。 重读这个问题,我开始考虑二的幂的性质:最重要的性质是二的每个连续幂是先前的两倍。 我知道这是一个非常荒谬的结论,但是,意识到以7为基数的等价词也是成立的,这是有效解决此问题的关键。

我开始构造一个名为BaseSevenNumber的类。 我给它一个列表,命名为digits,其元素将包含一个基数为7的单个数字。 我构建了一个构造函数以将该列表初始化为[1],并创建了一个名为Double的成员函数,该成员函数将处理我的“幂”运算。 我通过创建另一个成员(恰好名为HasThreeZeros)来结束课堂,为我提供数字的当前状态。

双重功能:

BaseSevenNumber的Double函数将成为及时解决此问题的关键。 我设计的第二个程序不是对大量数字执行一次算术运算,而是对少数几个小数字执行许多算术运算。 遍历列表,Double将数字列表中的每个数字加倍,并在第二遍中执行所有以7为底的进位运算。 HasThreeZeros函数现在可以快速遍历数字列表,并为当前的基数7返回正确的状态。

class BaseSevenNumber: 
    def __init__(self):
        self.digits = [1] 
    def Double(self):
        for i in range(0, len(self.digits)):
            self.digits[i] = self.digits[i] * 2
        for i in range(len(self.digits) - 1, -1, -1):
            if self.digits[i] > 6:
                self.digits[i] = self.digits[i] - 7
                if i == 0: self.digits.insert(0,1)
                else: self.digits[i - 1] = self.digits[i - 1] + 1 
    def HasThreeZeros(self):
        for i in range(0, len(self.digits) - 2):
            if self.digits[i] == 0 and self.digits[i + 1] == 0 and self.digits[i + 2] == 0: return True
        return False 
def SolveRiddle(maxFailuresAssumeFound):
    bsn = BaseSevenNumber()
    failures = 0
    power = 1
    while failures < maxFailuresAssumeFound:
        bsn.Double()
        if bsn.HasThreeZeros(): failures = failures + 1
        else:
            failures = 0
            print power
        power = power + 1 
SolveRiddle(10000)
我对思考问题的能力感到非常满意,然后将代码进行了测试。 在短短的16秒内,它给了我我想要的答案。 谈论使用错误的工具进行工作; 仅仅因为问题指出“二的幂”和“基数为七的表示”并不意味着一个人应该将自己局限于这些方法。 对问题进行仔细而彻底的分析可以为某些最棘手的问题提供有效,优雅,快速的解决方案。

From: https://bytes.com/topic/python/insights/648799-thinking-outside-box-python

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值