找回密码
 欢迎注册
查看: 3256|回复: 17

[擂台] 找出所有的生日素数!

[复制链接]
发表于 2022-10-11 12:29:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
比如19491001这个1949年10月1日(星期六),这天出生的是素数,现在要找出所有的这样的生日素数,
时间从1900年到2023年

  1. Clear["Global`*"];(*Clear all variables*)
  2. (*生成生日素数的所有可能,从1900年开始到2023年,day必然是奇数,需要删选掉部分不存在的日期*)
  3. aaa=Table[year*10000+month*100+day,{year,1900,2023},{month,1,12},{day,1,31,2}]
  4. bbb=Flatten@aaa;(*压平,成一个列表*)
  5. ccc=Select[bbb,PrimeQ[#]&](*选出所有的素数*)
  6. ddd=Select[ccc,Mod[#,10^4]==1111&](*选出光棍节的生日*)
复制代码


我筛选出了所有的光棍节那天的素数
{19051111,19181111,19321111,19421111,19541111,19591111,19631111,19771111,19931111,20051111,20141111}

大家继续上!


百度告诉我最孤独的质数
https://bbs.emath.ac.cn/thread-18619-1-1.html
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2022-10-11 12:52:08 | 显示全部楼层
本帖最后由 nyy 于 2022-10-11 13:26 编辑

算出上面的ccc,
然后用正则表达式把结果中的19000103替换成1900-01-03,然后粘贴到Excel中,
Excel对于准确的日期,自动右对齐,
然后不合格的日期,自动当成文本,自动左对齐
然后利用Excel的排序功能,正确的日期自动在前,错误的日期自动在后!
最后求解结果如下:
  1. 1900/01/03
  2. 1900/01/23
  3. 1900/02/13
  4. 1900/02/29
  5. 1900/04/09
  6. 1900/04/11
  7. 1900/05/11

  8. 删除很多结果,因为结果太长影响阅读
  9. -------------------------错误日期以下-------------------------
  10. 1901-11-31
  11. 1902-04-31
  12. 1904-04-31
  13. 1907-11-31
  14. 删除很多结果,因为结果太长影响阅读
  15. 1921-02-29
  16. 删除很多结果,因为结果太长影响阅读
  17. 2022-06-31
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2022-10-11 12:56:02 | 显示全部楼层
nyy 发表于 2022-10-11 12:52
算出上面的ccc,
然后用正则表达式把结果中的19000103替换成1900-01-03,然后粘贴到Excel中,
Excel对于 ...

上面有个错误日期
1900/02/29

这个是由于Excel的bug导致的!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2022-10-11 13:25:10 | 显示全部楼层
  1. Clear["Global`*"];(*Clear all variables*)
  2. (*生成生日素数的所有可能,从1900年开始到2023年,day必然是奇数,需要删选掉部分不存在的日期*)
  3. aaa=Table[year*10000+month*100+day,{year,1900,2023},{month,1,12},{day,1,31,2}];
  4. bbb=Flatten@aaa;(*压平,成一个列表*)
  5. ccc=Select[bbb,PrimeQ[#]&];(*选出所有的素数*)
  6. (*子函数,判别8位日期(比如19010203)是否是正确日期,正确返回1,错误返回0*)
  7. fun[n_]:=Module[{lst,year,month,day,leap},
  8.     lst=IntegerDigits[n,10];(*十进制下每位上的数字*)
  9.     year=FromDigits[lst[[1;;4]]];(*得到年*)
  10.     month=FromDigits[lst[[5;;6]]];(*得到月*)
  11.     day=FromDigits[lst[[7;;8]]];(*得到日*)
  12.     If[MemberQ[{1,3,5,7,8,10,12},month]&&(1<=day<=31),Return[1]];(*大月天数不超过31*)
  13.     If[MemberQ[{4,6,9,11},month]&&(1<=day<=30),Return[1]];(*平月天数不超过30*)
  14.     leap=0;(*是否润年,0不是,1是闰年*)
  15.     If[(Mod[year,4]==0&&Mod[year,100]!=0)||(Mod[year,400]==0),leap=1];(*判别闰年*)
  16.     If[(month==2)&&Or[leap==0&&(1<=day<=28),leap==1&&(1<=day<=29)],Return[1]];(*二月情况判别*)
  17.     Return[0](*其余情况一概返回错误0*)
  18. ]
  19. ddd=Select[ccc,fun[#]==1&];(*从这些素数中选择日期正确的日期*)
复制代码


最后结果2770个正确的日期都是素数
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2022-10-12 16:41:11 | 显示全部楼层
  1. from sympy import isprime
  2. import pandas as pd
  3. date_list = [d for d in [int(d) for d in pd.date_range('1900-1-1', '2023-12-31').strftime("%Y%m%d").tolist()] if isprime(d)]
  4. print(date_list,len(date_list))
复制代码

点评

nyy
这个年代,医生都会码代码!  发表于 2022-10-13 11:42
nyy
牛逼  发表于 2022-10-13 09:03
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2022-10-13 09:17:50 | 显示全部楼层
  1. Clear["Global`*"];(*Clear all variables*)
  2. aaa=DateRange[{1900,1,1},{2023,12,31}];(*生成这个时间段内的所有日期*)
  3. bbb=(#[[1]]*10000+#[[2]]*100+#[[3]])&/@aaa;(*映射得到日期的八位数*)
  4. ccc=Select[bbb,PrimeQ[#]&](*选择八位数是素数的*)
  5. ddd=Length[ccc](*得到2770个结果*)
复制代码


这个也可以得到所有的结果,如果你喜欢还可以写成一行,
但是我写成多行,因为多行好写注释,且容易懂!还好维护!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2022-10-13 16:20:23 | 显示全部楼层
  1. out=Select[(#[[1]]*10^4+#[[2]]*100+#[[3]])&/@DateRange[{1900,1,1},{2023,12,31}],PrimeQ[#]&]
复制代码


无耻的一行代码,我很讨厌写这样的代码,具体注释参考我楼上的代码

点评

Select[(#[[1]]*10^4 + #[[2]]*100 + #[[3]]) & /@ DateRange[{1900}, {2023}], PrimeQ[#] &] 还能短一些  发表于 2022-10-13 17:57
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2022-10-13 16:23:16 | 显示全部楼层
自己真愚蠢,忽略了mathematica自身也有日期计算函数,且他们的函数可靠度比我的高多了!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2022-10-14 10:15:46 | 显示全部楼层

Select[(#[[1]]*10^4 + #[[2]]*100 + #[[3]]) & /@ DateRange[{1900}, {2023}], PrimeQ[#] &] 还能短一些

你的这个代码有问题
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2022-10-15 00:12:30 | 显示全部楼层
本帖最后由 northwolves 于 2022-10-15 00:16 编辑
nyy 发表于 2022-10-14 10:15
Select[(#[[1]]*10^4 + #[[2]]*100 + #[[3]]) & /@ DateRange[{1900}, {2023}], PrimeQ[#] &] 还能短一些 ...

  1. a=Select[(#[[1]]*10^4+#[[2]]*100+#[[3]])&/@DateRange[{1900},{1902}],PrimeQ[#]&]
  2. b=Select[FromDigits[DatePlus[{1900},#],100]&/@Range[365*2],PrimeQ]
  3. c=Select[FromDigits[{#,#2,#3},100]&@@@DateRange[{1900},{1902}],PrimeQ]
  4. d=Select[Round[DateRange[{1900},{1902}]].{10000,100,1,0,0,0},PrimeQ]
  5. e=Select[DateRange[{1900},{1902}][[;;,;;3]].{10000,100,1},PrimeQ]
  6. f=Select[Take[DateRange[{1900},{1902}],;;,3].{10000,100,1},PrimeQ]
复制代码


感谢 wayne 和  chy 两位版主提供的代码,测试通过

点评

nyy
还是写成DateRange[{1900,1,1},{2023,12,31}]这样的代码可读性比较高,我喜欢这种  发表于 2022-10-17 10:44
nyy
DateRange[{1900},{1902}]的最后一个元素是{1902, 1, 1, 0, 0, 0.}  发表于 2022-10-17 10:42
nyy
DateRange[{1900},{1902}],似乎不包含 1902.1.2 1902.2.3这类日期吧????  发表于 2022-10-17 10:41
nyy
没记错的话,你的1902年,不包括1902.04.01这些日期  发表于 2022-10-17 08:26
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-5-27 16:50 , Processed in 0.049642 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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