鱼C论坛

 找回密码
 立即注册
查看: 3574|回复: 11

[技术交流] 小练习:20160912 给出100万以下所有十进制和二进制表示都是回文的数字之和

[复制链接]
发表于 2016-9-12 21:46:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 冬雪雪冬 于 2016-9-19 11:00 编辑

从现在开始我们要开展一批欧拉计划的习题练习。
其实在我们论坛中已有欧拉计划的板块,可能有些鱼油还没注意到。
什么是欧拉计划:http://bbs.fishc.com/thread-60405-1-1.html
我们欧拉板块现已给出了81道题,这批练习将从欧拉计划中选题。其实用python语言完成有很多的优势,可以更简洁更方便的实现。
如果大家有兴趣也可浏览欧拉的英文网站:https://projecteuler.net/archives
这里已经有了500余题。


                               
登录/注册后可看大图

好了言归正传,我们开始做小练习。




题目要求:
以python语言完成,如果是python2请注明。
程序以代码文字格式发帖。
题目比较简单,就不要求大家写成思路了。注重程序效率和创意。
答题在一周内完成,即9.19 10:00之前,其后将公开大家的答案,并评比成绩。

另程序和答案可以在网上搜到,希望大家独立完成。

----除列出程序外,请给出输出的结果。----


题目:

十进制数字

                               
登录/注册后可看大图
(二进制),可以看出在十进制和二进制下都是回文(从左向右读和从右向左读都一样)。

求 100 万以下所有在十进制和二进制下都是回文的数字之和。

(注意在两种进制下的数字都不包括最前面的 0)


本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-9-12 21:47:12 | 显示全部楼层
其实题目真的非常简单,我是用[::-1]算回文的。
  1. sum1 = 0
  2. for i in range(1, 1000000):
  3.     if str(i) == str(i)[::-1]:
  4.         b = '{:b}'.format(i)
  5.         if b == b[::-1]:
  6.             sum1 += i
  7. print(sum1)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-12 22:43:50 | 显示全部楼层
  1. from time import time
  2. start=time()
  3. lst=[]
  4. result=0

  5. for i in range(1,1000000,2):
  6.     b_str=bin(i)[2:]
  7.     i_str=str(i)

  8.     if i_str==i_str[::-1] and b_str==b_str[::-1]:
  9.         lst.append(i)

  10. for i in lst:
  11.     result+=i

  12. print(lst)
  13. print(result)
  14. print(time()-start)
复制代码

  1. >>> ================================ RESTART ================================
  2. >>>
  3. [1, 3, 5, 7, 9, 33, 99, 313, 585, 717, 7447, 9009, 15351, 32223, 39993, 53235, 53835, 73737, 585585]
  4. 872187
  5. 5.8598997592926025
  6. >>>
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-12 23:15:50 | 显示全部楼层
本帖最后由 wangzhenas 于 2016-9-19 04:49 编辑

答案: 872187
耗时: 0.004s
思路是利用生成器函数生成100,000以下的所有回文数,然后用filter函数判断二进制是否为回文数并求和
  1. from time import time

  2. t = time()
  3. def produce_10(maxi = 1000):
  4.     for i in range(maxi):
  5.         for n in (i,i//10):
  6.             result = i
  7.             while n > 0:
  8.                 result *= 10
  9.                 result += n % 10
  10.                 n //= 10
  11.             yield result
  12.             
  13. print(sum(filter(lambda n:bin(n)[2:] == bin(n)[2:][::-1], produce_10())),time()-t)
复制代码

评分

参与人数 1荣誉 +15 鱼币 +15 收起 理由
冬雪雪冬 + 15 + 15 热爱鱼C^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-13 11:20:13 From FishC Mobile | 显示全部楼层
本帖最后由 jerryxjr1220 于 2016-9-15 00:41 编辑

手机上写的,回去后把程序补上。
结果应该是872187

换了一种算法,只需比较一半字符串,优化运算速度。

  1. import time
  2. start = time.time()

  3. #def isCycle1(strnum):
  4. #  lennum = len (strnum)
  5. #  n = lennum - 1
  6. #  str1 = strnum[n] + strnum[:n]
  7. #  for i in range(1,n):
  8. #    str1 = str1[:i] + str1[n] + str1[i:n]
  9. #  #  return str1
  10. #  if strnum == str1:
  11. #    return 1
  12. #  else:
  13. #    return 0

  14. #def isCycle2(strnum):
  15. #  lennum = len (strnum)
  16. #  n = lennum - 1
  17. #  m = int(lennum/2-0.5)
  18. #  str1 = strnum[:m+1]
  19. #  str2 = strnum[n] + strnum[int(lennum/2):n]
  20. #
  21. #  for i in range(1,m):
  22. #      str2 = str2[:i] + str2[m] + str2[i:m]
  23. #
  24. #  if str1 == str2:
  25. #    return 1
  26. #  else:
  27. #    return 0

  28. def isCycle3(strnum):
  29.   lennum = len (strnum)
  30.   n = lennum - 1
  31.   flag = 1
  32.   for i in range(int(lennum/2)):
  33.     if strnum[i] != strnum[n-i]:
  34.       flag = 0
  35.       break
  36.   return flag


  37. # oddlist, cycodd, blist
  38. oddlist = [3,5,7,9,11,33,55,77,99]
  39. for a in range(101,1000000):
  40.   if a % 2:
  41.     oddlist.append (a)
  42.    
  43. #  print (oddlist)

  44. cycodd = []
  45. blist = []
  46. for each in oddlist:
  47.   if isCycle3(str(each)):
  48.     cycodd.append (each)
  49.     blist.append (bin(each)[2:])

  50. #  print (blist)

  51. #  finallist
  52. finallist = [1]
  53. for eachb in blist:
  54.   if isCycle3(eachb):
  55.     finallist.append (cycodd[blist.index(eachb)])

  56. print ("解答:")

  57. print (sum(finallist))
  58. #  print (finallist)

  59. end = time.time()
  60. print ("用时 %.3f秒" % (end - start))
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-14 13:45:01 | 显示全部楼层
  1. def shu(n):
  2.     n = str(n)
  3.     s1 = int(n+n[::-1])
  4.     s2 = int(n+n[:-1][::-1])
  5.     return s1,s2
  6. sum = 0
  7. for i in range(1,999):
  8.     x1,x2 = shu(i)
  9.     if bin(x1)[2:] == bin(x1)[2:][::-1]:
  10.         sum = sum+x1
  11.     if bin(x2)[2:] == bin(x2)[2:][::-1]:
  12.         sum = sum+x2
  13. print(sum)
复制代码

答案:872187

评分

参与人数 1荣誉 +15 鱼币 +15 收起 理由
冬雪雪冬 + 15 + 15 热爱鱼C^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-14 17:28:33 | 显示全部楼层
想问一下这个一百万是十进制还是二进制?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-15 09:16:58 | 显示全部楼层
  1. #答案为872187
  2. def hws(n):
  3.     n2s = str(n)
  4.     l = (len(n2s)+1)//2
  5.     for i in range(l):
  6.         if n2s[i] != n2s[-i-1]:
  7.             return False
  8.     return True

  9. s = 0
  10. for num in range(1000000):
  11.     if hws(num) and hws(int(bin(num)[2:])):
  12.         s += num
  13. print(s)
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-15 16:06:18 | 显示全部楼层
本帖最后由 小剑剑 于 2016-9-21 10:07 编辑
  1. from time import clock
  2. time,su=clock(),0
  3. def palindromic_number():
  4.        for i in range(1,10,2):
  5.               yield i
  6.        for i in range(1,1000,2):
  7.               reve=''.join(reversed(list(str(i))))
  8.               yield reve+str(i)
  9.               for ii in range(10):
  10.                      yield reve+str(ii)+str(i)
  11. def is_binary_pal(decnum):
  12.        dereve=0
  13.        copy_num=decnum
  14.        while decnum>0:
  15.               dereve=dereve*2+decnum%2
  16.               decnum//=2
  17.        return copy_num==dereve
  18. for i in palindromic_number():
  19.        if is_binary_pal(int(i)):
  20.               su+=int(i)

  21. print(su,clock()-time)
复制代码

  1. 25837859 0.09252274984565001
复制代码



感动的一B,范围错了,版主都发鱼币
修改后
  1. from time import clock
  2. time,su=clock(),0
  3. def palindromic_number():
  4.        for i in range(1,10,2):
  5.               yield i
  6.        for i in range(1,1000,2):
  7.               reve=''.join(reversed(list(str(i))))
  8.               yield reve+str(i)
  9.               if i<100:
  10.                      for ii in range(10):
  11.                             yield reve+str(ii)+str(i)
  12.        for i in range(10,1000,20):
  13.               reve=''.join(reversed(list(str(i))))
  14.               yield str(i)+reve
  15. def is_binary_pal(decnum):
  16.        dereve=0
  17.        copy_num=decnum
  18.        while decnum>0:
  19.               dereve=dereve*2+decnum%2
  20.               decnum//=2
  21.        return copy_num==dereve
  22. for i in palindromic_number():
  23.        if is_binary_pal(int(i)):
  24.               su+=int(i)

  25. print(su,clock()-time)
  26. 872187
  27. 0.015596389770507812
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-18 09:03:56 | 显示全部楼层
  1. # -*- coding:Utf-8 -*-
  2. import time
  3. start = time.clock()

  4. def ishw(m):
  5.    if str(m)==str(m)[::-1]:
  6.        return 1
  7.    else:
  8.        return 0

  9. sum_hw=0
  10. for i in range(1,1000000):
  11.     if ishw(i):
  12.         if ishw(bin(i)[2:]):
  13.             sum_hw+=i
  14. print(sum_hw)

  15. end = time.clock()
  16. print ("read: %f s" % (end - start))
复制代码


计算结果:
  1. 872187
  2. read: 1.067628 s
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-19 20:59:28 | 显示全部楼层
wangzhenas 发表于 2016-9-12 23:15
答案: 872187
耗时: 0.004s
思路是利用生成器函数生成100,000以下的所有回文数,然后用filter函数判断 ...

能将这段程序都一句都注疏下不
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-20 03:47:23 | 显示全部楼层
寒园 发表于 2016-9-19 20:59
能将这段程序都一句都注疏下不

我就简单说下思路吧
首先函数的作用是生成一百万以下的回文数
比如:从123可以得到123321,12321两个回文数,因此只需迭代到1000, 因为999最大可以生成999999
然后用yield语句将函数包装为生成器,即一个可迭代对象(在这里相当于返回了一个所有回文数的列表)
然后用filter过滤出二进制为回文数的情况
最后用sum求和
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-21 14:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表