- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这是我对 Project Euler problem 36 的解决方案,内容如下:
The decimal number, 585 = 1001001001₂ (binary), is palindromic in both bases.
Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2.
(Please note that the palindromic number, in either base, may not include leading zeros.)
我的结果有点不对。谁能帮忙?
def findnum(n):
a = 0
for i in range(0, n + 1):
temp = '{0:08b}'.format(i)
if str(i) == str(i)[::-1] and str(temp) == str(temp)[::-1]:
a += i
return a
print findnum(1000000)
我得到的结果是872096,但是正确答案好像是872187。不过这两者之差,91,不是回文。我做错了什么?
最佳答案
你在问题描述中遗漏了一些东西:
Please note that the palindromic number, in either base, may not include leading zeros.
但您正在使用前导零:
temp = '{0:08b}'.format(i)
从格式中删除 08
;这里根本不需要将其填充到宽度:
temp = '{0:b}'.format(i)
通过此更改,您将获得正确答案。
您也可以只使用 format()
function相反,因为您没有将字符串放入更大的模板中。您不需要将它提供给 str()
,因为 format()
已经生成了一个字符串。我会交换测试以首先测试二进制回文并避免额外的 str()
调用。 range()
调用中的 n + 1
不是必需的;问题描述要求所有 100 万以下的数字:
for i in range(n):
temp = format(i, 'b')
if temp == temp[::-1] and str(i) == str(i)[::-1]:
a += i
或者您可以先测试十进制回文,然后格式:
for i in range(n):
decimal = str(i)
if decimal != decimal[::-1]:
continue
binary = format(i, 'b')
if binary == binary[::-1]:
a += i
这减少了整个运行时的相当多的调用,使最终版本的速度提高了一倍多:
>>> from timeit import timeit
>>> def findnum_orig(n):
... a = 0
... for i in range(0, n + 1):
... temp = '{0:b}'.format(i)
... if str(i) == str(i)[::-1] and str(temp) == str(temp)[::-1]:
... a += i
... return a
...
>>> def findnum_optimised(n):
... a = 0
... for i in range(n):
... decimal = str(i)
... if decimal != decimal[::-1]:
... continue
... binary = format(i, 'b')
... if binary == binary[::-1]:
... a += i
... return a
...
>>> timeit('fn(1000000)', 'from __main__ import findnum_orig as fn', number=10)
10.886759996414185
>>> timeit('fn(1000000)', 'from __main__ import findnum_optimised as fn', number=10)
3.7782959938049316
那是因为 str()
比 format()
快很多:
>>> timeit('for i in range(1000): str(i)', number=1000)
0.17951107025146484
>>> timeit('for i in range(1000): format(i, 'b')', number=1000)
0.2837510108947754
由于100万以下只有1999个十进制数和2000个二进制回文数:
>>> sum(1 for i in range(1000000) if str(i) == str(i)[::-1])
1999
>>> sum(1 for i in range(1000000) if format(i, 'b') == format(i, 'b')[::-1])
2000
除了那些 1999 十进制回文之外,避免所有较慢的操作可以节省您很多时间。
我们可以通过切换将整数转换为二进制的方式来使其更快; bin()
function也产生二进制数,尽管带有 0b
前缀。即使必须删除该前缀,使用该函数也比使用 format()
更快:
>>> timeit('for i in range(1000): format(i, "b")', number=1000)
0.46987009048461914
>>> timeit('for i in range(1000): bin(i)[2:]', number=1000)
0.24124693870544434
如果您使用的是 Python 2.x,您还应该使用 xrange()
function避免创建包含 1.000.000 个整数的列表。这将最终时间安排为:
>>> def findnum_bin_xrange(n):
... a = 0
... for i in xrange(n):
... decimal = str(i)
... if decimal != decimal[::-1]:
... continue
... binary = bin(i)[2:]
... if binary == binary[::-1]:
... a += i
... return a
...
>>> findnum_bin_xrange(1000000)
872187
>>> timeit('fn(1000000)', 'from __main__ import findnum_bin_xrange as fn', number=10)
3.5071611404418945
这大约是原始代码时间的 1/3。
关于python - 两个基数中的回文数,欧拉计划 #36,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28351928/
在编程中,我只使用整数。不过这次要进行一些计算。我需要计算Euler-Mascheroni Constant γ .最多 n 位小数。{虽然 n ∈ [30, 150]对我来说已经足够了。 [x] =
有人可以帮忙处理这段代码吗?它应该得到第 10,001 个素数。我知道 is_prime 函数可以测试一个数字是否为素数,因为我成功地利用此代码解决了上一个问题。现在我只是尝试在 for 循环中调用它
我发现了几个与这个问题相关的主题,我只是想知道为什么我的代码返回不正确的数据。所以我们必须找到第一个除数超过 500 的三角形数。详情可在此处找到:http://projecteuler.net/pr
#include int main(void) { char *num = "73167176531330624919225119674426574742355349194934"
我正在尝试投影欧拉问题 8,但是我遇到了问题。1000位数字中相邻四位的乘积最大为9×9×8×9=5832。 731671765313306249192251196744265747423553491
这是针对 Project Euler 19 的。我几乎想出了代码,但由于某种原因我的输出是 +1。 #include #define SIZE 12 int main(void) {
int main(void) { int n, div, a, b; double phi; printf("Enter n:\n"); if (scanf("%d", &n) < 1
欧拉问题: 如果我们列出所有 10 以下的自然数,它们是 3 或 5 的倍数,我们得到 3、5、6 和 9。这些倍数的和是 23。 求 1000 以下的所有 3 或 5 的倍数之和。 我试图从 pro
我知道这可能会被否决,但我真的很沮丧 24 小时,查看其他 Euler 3 线程并没有帮助我解决这个问题。有人可以帮助我的代码吗?我认为我非常接近。 function is_prime(num) {
我卡在了Question 7欧拉计划。我有这段代码。 #include int main (void) { int contador = 0, i, n, variavel = 0;
我正在尝试使用 sympy 的 idiff 函数对某些表达式执行隐式微分。 在本例中,rdot 为 dr/ds,其中 s 是仿射参数。我想对相同的仿射参数对 Ltdot、Lphidot 和 Lrdot
我正在尝试解决我的第一个项目 Euler 问题,只是为了玩 Rust,但被困在似乎需要极长计算时间的问题上 问题: https://projecteuler.net/problem=757 我想出了这
我正在学习C编程,并制定了以下算法来解决这个问题: 代码实际上有效,但最初循环只有 10 次重复(rep int main() { float p; //the power for e
我之前曾尝试暴力破解它,但没有成功。这是我的递归尝试#2(第一次使用递归方法)。请帮忙! 发生的情况是这样的:代码运行良好,数字较小,但是当我们达到一百万时,代码就会运行,并且什么也不会发生。在 Ec
Given a number find the 5 digits before the trailing 0. 9! = 362880 so f(9)=36288 10! = 3628800 so f
我是一名优秀的程序员,十分优秀!