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