我是python的新手,并决定通过对项目Euler进行一些挑战来改进我的编码(一般来说)。我目前仍然遇到问题4,我不确定出了什么问题(对于那些不知情的人,问题4如下):
回文数字两种方式相同。
由两个2位数字的乘积制成的最大回文数为9009 = 91 x 99。
找出由两个3位数字的乘积制成的最大回文。
x, y = 999, 999
palindrome = []
while True:
palindrome = [i for i in str(x * y)]
r_palindrome = palindrome[::-1]
if palindrome == r_palindrome:
break
else:
y -= 1
if y < 100:
y = x
x -= 1
print x, y, palindrome
我似乎得到了感觉非常低的答案987 * 286 = 282282
。
有人可以解释这样做的最佳方式以及我当前的代码做错了什么而不仅仅是一个简单的&#34;这里是代码&#34;请回答。
答案 0 :(得分:3)
从x = 999
和y = 999
开始,然后仅递减y
,直到您使用递减的x
重置并重置y
并不能保证您将首先击中最大的回文。
想想下面的例子:让我们想象一下产品的不同要求(不要破坏回文结果)。想象一下,您从x = 999
开始,然后到达y = 101
,直到您点击第一个“有效”结果。
在您的情况下,您会接受999 * 101 = 100899
作为最大结果。但实际上可能存在一个你从未看过的不同解决方案998 * 998 = 996004
,但显然要大得多。
因此,您需要更改决定何时停止查看并知道您达到最大数量的方式。
顺便说一下。作为Project Euler的一般提示:特别是第一个问题可以通过强力解决(即尝试所有可能的解决方案)。虽然这可能不会给你一种令人满意的感觉,你以一种聪明的方式解决了这个问题,但它确实让你知道如何到达那里。你可以随时找到一个更好的解决方案,但请记住,Project Euler实际上已经很多问题,这些问题完全不可能使用暴力,所以你有足够的后顾之忧;)
对于这个特殊的问题,你可以写一个列表理解,它会给你所有的回文,然后得到它的最大值。这是一个单线程;这是非常低效的,但对于这个特别小的输入域,它足够快,仍能立即给你一个答案:
max([(x * y, x, y) for x in range(100, 1000) for y in range(100, 1000) if str(x * y) == str(x * y)[::-1]])
答案 1 :(得分:0)
好的,只是为了找到解决方案,让我们使用暴力:
>>> prod = itertools.product(range(999,99,-1),range(999,99,-1))
>>> palindromes = [(x*y,x,y) for x,y in prod if str(x*y) == str(x*y)[::-1]]
>>> max(palindromes, key=lambda t: t[0])
(906609, 993, 913)
花了一点时间,但至少我们有答案。我已经找到了一个能够很快发挥作用的解决方案,我认为这需要你想要实现的目标:
>>> x = 999
>>> palindromes = []
>>> floor = 99
>>> while x > floor:
... for i in range(x,floor,-1):
... product = x*i
... candidate = str(product)
... if candidate == candidate[::-1]:
... palindromes.append((product,x,i))
... floor = i
... break
... x -= 1
...
>>> palindromes
[(580085, 995, 583), (906609, 993, 913), (886688, 968, 916), (888888, 962, 924)]
>>>
基本上,这会使最后给我们回文的最低数字更新。我们知道每次都不要低于这个。