python圆周率测试

利用python测试圆周率是否包含所有6位数密码,及其首次出现的位数

先使用y-cruncher生成圆周率的前2500万位,数据保存在txt文件中,文件大小24MB,修改文件只保留小数点后的数字,接下来就可以对数据进行测试。

1,最直接的办法查找

index()函数可返回开始的索引值,即首次出现的位数,代码如下:

pi_file = r'E:\测试\Pi-25000000.txt'  # 读取文件
with open(pi_file, 'r') as f:
    pi = f.read()
    #print(len(pi))

password_dict = {}  # 字典保存,密码-首次出现位数
for num in range(1000000):  # 所有6位数字密码
    key = ('%06d' % num)
    password_dict[key] = pi.index(key)
    if num % 100000 == 0:  # 查看进度
        print(key)

save_file = r'E:\测试\Pi-password.txt'  # 保存路径
with open(save_file, 'w') as f:
    for key, value in password_dict.items():
        f.write('%s:%s\n' % (key, value))
测试结果:

000000-999999一共100万种密码都在圆周率前2500万位中出现,最后出现的密码是569540,位数14118306(从0开始计数)


密码:首次出现的位数(从0开始计数)

不过代码运行比较慢,圆周率2500万位查找100万种密码,共耗时1059秒。

2,改进代码分段查找

这是由于不断使用index()函数对2500万位数字从左向右查找,重复查找过多,因此可以从数字中查找密码,这样每6位数字只需查找一次,改进代码如下:

pi_file = r'E:\测试\Pi-25000000.txt'  # 读取文件
with open(pi_file, 'r') as f:
    pi = f.read()

password_dict = {}  # 字典保存,密码-首次出现位数,初始位数设为-1
for num in range(1000000):  # 所有6位数字密码
    password_dict['%06d' % num] = -1


k = 100*10000  # 分段查找,每段设置位数
n_max = len(pi) // k  # 防止死循环,最好整除
n = 1
    
while -1 in password_dict.values() and n <= n_max:
    for i in range((n-1)*k, n*k):
        password = pi[i:i+6]
        if password_dict[password] == -1:
            password_dict[password] = i
        elif i < password_dict[password]:
            password_dict[password] = i
    n = n + 1

save_file = r'E:\测试\Pi-password.txt'  # 保存路径
with open(save_file, 'w') as f:
    for key, value in password_dict.items():
        f.write('%s:%s\n' % (key, value))
测试结果是一样的,不过运行速度大幅提高,改进代码仅耗时8.5秒,相差120倍。

3,测试是否包含日期

既然6位数密码都在圆周率的前2500万位中,那么接下来测试一下1921年至2020年所有日期是否也在其中。

按照惯例,先用最直接的办法查找,不过index()函数未找到会报错,改为find()函数查找,代码如下:

pi_file = r'E:\测试\Pi-25000000.txt'  # 读取文件
with open(pi_file, 'r') as f:
    pi = f.read()

birthday_dict = {}  # 生日字典
mmdd = []
for m in range(1, 13):
    for d in range(1, 32):
        mmdd.append('%02d%02d' % (m, d))
temp = ['0229', '0230', '0231', '0431', '0631', '0931', '1131']
for i in temp:
    mmdd.remove(i)
# 直接查找
for year in range(1921, 2021):
    for md in mmdd:
        yyyymmdd = str(year) + md
        birthday_dict[yyyymmdd] = pi.find(yyyymmdd)
    if (year % 4) == 0:
        yyyymmdd = str(year) + '0229'
        birthday_dict[yyyymmdd] = pi.find(yyyymmdd)
    print(year)
   
save_file = r'E:\测试\Pi-birthday.txt'  # 保存路径
with open(save_file, 'w') as f:
    for key, value in birthday_dict.items():
        f.write('%s:%s\n' % (key, value))
测试结果:

1921年至2020年一共36525天只有8020天在圆周率前2500万位中出现,最先出现的日期是20190914,位数243,最后出现的日期是19660505,位数24999789(从0开始计数)


日期:首次出现的位数(从0开始计数)

直接查找自然很慢,耗时731秒,按照之前的方法进行改进,改进代码如下:

# 分段查找
for year in range(1921, 2021):
    for md in mmdd:
        birthday_dict[str(year) + md] = -1
    if (year % 4) == 0:
        birthday_dict[str(year) + '0229'] = -1

k = 100*10000
n_max = len(pi) // k  # 防止死循环,最好整除
n = 1

while -1 in birthday_dict.values() and n <= n_max:
    for i in range((n-1)*k, n*k):
        birthday = pi[i:i+8]
        if birthday in birthday_dict:  # 判断是否为待查找日期
            if birthday_dict[birthday] == -1:
                birthday_dict[birthday] = i
            elif i < birthday_dict[birthday]:
                birthday_dict[birthday] = i
    n = n + 1
改进代码仅耗时4.3秒,相差170倍。

既然2500万位没有测试出所有日期出现的位数,那么再试试看1亿位,结果一共36525天有23163天出现了,最后出现的日期是19640421,位数99995337(从0开始计数)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356