项目欧拉:两个3位数的最大回文产品

时间:2017-12-27 23:03:57

标签: python eulers-number

580085 ,为什么会出错?还有另一种方法来检查数字是否是回文?

def reverse(str, aux=''):
    count = len(str)
    while count > 0:
        aux += str[count-1]
        count -= 1
    return aux

def palindrome(num):
    j = str(num)
    if j == reverse(j):
        return 1
    else:
        return 0

i = 999
found = 0
while i > 99 and not found:
    j = 999
    while j > 99 and not found:
        if palindrome(i * j):
            found = 1
            print(i * j)
        else:
            j -= 1
    if not found:
        i -= 1

我的帖子主要是代码,但我没有别的话要说。

2 个答案:

答案 0 :(得分:1)

花了一些时间研究这个问题。我尝试采用反向方法(从回文数字开始,找到它们的分隔符(如果有的话))。在 Win10 上使用 Py354

code.py

import time
from math import sqrt


def reverse(str, aux=''):
    count = len(str)
    while count > 0:
        aux += str[count-1]
        count -= 1
    return aux


def palindrome(num):
    j = str(num)
    if j == reverse(j):
        return 1
    else:
        return 0


def question_makhfi_0():
    ret = 0
    i = 999
    found = 0
    while i > 99 and not found:
        j = 999
        while j > 99 and not found:
            if palindrome(i * j):
                found = 1
                ret = i * j
            else:
                j -= 1
        if not found:
            i -= 1
    return ret, i, j


def answer_makhfi_0():
    i = 999
    _max = 0
    while i > 99:
        j = 999
        while j > 99:
            num = i * j
            if palindrome(num):
                if num > _max:
                    _max = num
                    factor0, factor1 = i, j
            j -= 1
        i -= 1
    return _max, factor0, factor1


"""
def answer_makhfi__0_improved_0():
    i = j = 999
    prod = i * j
    step = 0
    while prod > 100000:
        if step % 2:
            i -= 1
        else:
            j -= 1
        prod = i * j
        prod_str = str(prod)
        if prod_str == prod_str[::-1]:
            return prod
        step += 1
"""


def answer_cfati_0():
    pal = 999999
    while pal >= 900009:
        if pal % 10 == 9:
            pal_str = str(pal)
            if pal_str == pal_str[::-1]:
                pal_sqrt = sqrt(pal)
                for factor0 in range(101, int(pal_sqrt) + 1):
                    if pal % factor0 == 0:
                        factor1 = int(pal / factor0)
                        if 100 <= factor1 <= 999:
                            return pal, factor0, factor1
        pal -= 10
    #return pal


def time_func(f, *args):
    t0 = time.time()
    res = f(*args)
    t1 = time.time()
    return t1 - t0, res


if __name__ == "__main__":
    for func in [question_makhfi_0, answer_makhfi_0, answer_cfati_0]:
        print("\nStarting: {}".format(func.__name__))
        #print(func.__name__)
        res = time_func(func)
        print("  Time: {:.6f}\n  Result: {}".format(*res))

备注

  • 将您的代码转换为函数(执行所有必需的调整,省略涉及性能的所有内容)
  • 添加了一个衡量执行时间的附加功能
  • answer_makhfi_0
    • max替换为_max以避免隐藏内置名称
    • 最后添加了return语句(效率极低,无论如何)
  • answer_cfati_0
    • 该代码假设[900009, 999999]范围内的回文数,可以表示为2(3位)数字乘积。假设(测试支持这一点)是公平的。但是,如果针对防弹代码,这个表单不会这样做,我将不得不稍微调整一下(这将是性能损失)
    • 它使用各种数学/逻辑&#34;快捷方式&#34;避免无用的计算(我认为代码也可以在那个方向上得到改进)。

<强>输出

"e\Work\Dev\StackOverflow\q47999634>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py

Starting: question_makhfi_0
  Time: 0.008551
  Result: (580085, 995, 583)

Starting: answer_makhfi_0
  Time: 1.457818
  Result: (906609, 993, 913)

Starting: answer_cfati_0
  Time: 0.012599
  Result: (906609, 913, 993)

根据输出,原始代码之间存在差异(对于一次运行,时间会有所不同):

  • 最大回文数: 906609 - 906609
  • 计算时间: 1.457818 - 0.012599

@ EDIT0

  • 感谢您的评论,我在我的代码中发现了(严重的)逻辑错误(以及一些小错误):它返回 998899 781 * 1279 )。在修复它们之后,性能下降了一个数量级,但它仍然很快
  • 修改函数也返回因子(用于检查)

答案 1 :(得分:0)

新代码:

def reverse(str, aux=''):
    count = len(str)
    while count > 0:
        aux += str[count-1]
        count -= 1
    return aux

def palindrome(num):
    j = str(num)
    if j == reverse(j):
        return 1
    else:
        return 0

i = 999
max = 0
while i > 99:
    j = 999
    while j > 99:
        num = i * j
        if palindrome(num):
            if num > max:
                max = num
                print(max)
        j -= 1
    i -= 1