栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

用python实现卡普雷卡尔黑洞(重排求差黑洞)的计算

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

用python实现卡普雷卡尔黑洞(重排求差黑洞)的计算

目录

一、问题的由来

二、卡普雷卡尔黑洞描述

三、问题解决

1、解决思路

2、解决过程

(1)将输入的数字为数字列表

(2)生成最大数和最小数

(3)确定结束时机

(4)主程序部分

(5)逐步改进1(5位数以上的实现过程)

(6)逐步改进2(2位数的处理)

(7)主程序完善

3、完整代码

4、输出结果

(1)两位数

(2)三位数

(3)四位数

(4)五位数

(5)六位数

(6)七位数

(7)八位数

(8)九位数

(9)十位数

心得体会:


一、问题的由来

近期由于疫情原因,女儿在家学习,她们教材中涉及一个黑洞的知识点,教学中利用笔算进行2位数和3位数的计算。基于此,想知道更多位数是否仍存有黑洞问题,就查询了相关问题,并用python解决了这个问题。

二、卡普雷卡尔黑洞描述

拿四位数举例,它的算法如下:

取任意一个4位数(4个数字均为同一个数的,以及三个数字相同,另外一个数与这个数相差1,如1112,,6566等除外),将该数的4个数字重新组合,形成可能的最大数和可能的最小数,再将两者之间的差求出来;对此差值重复同样过程,最后你总是至达卡普雷卡尔黑洞6174,到达这个黑洞最多需要14个步骤。

例如:

大数:取这4个数字能构成的最大数,本例为:4321;

小数:取这4个数字能构成的最小数,本例为:1234;

差:求出大数与小数之差,本例为:4321-1234=3087;

重复:对新数3087按以上算法求得新数为:8730-0378=8352;

重复:对新数8352按以上算法求得新数为:8532-2358=6174;

结论:对任何只要不是4位数字全相同的4位数,按上述算法,不超过9次计算,最终结果都无法逃出6174黑洞;

三、问题解决

1、解决思路

(1)程序接收输入的数字,要求每位都不同

(2)将输入的数字分解为列表

(3)将列表中的数字生成最大数和最小数

(4)再次分解为列表,求出最大最小值,重复操作

(5)直到得到的数不变化或位数变少为止

2、解决过程

(1)将输入的数字为数字列表
#将一个整数拆分为一个列表返回
#方法,先转化为字符串,读出后转变类型并写入列表
def split_number(number):
    list_number = []
    str_number = str(number)
    for item in str_number:
        list_number.append(int(item))
    return list_number

为加强代码的可重复利用,将这部分的功能做成函数,输入是输入的数,返回值是数的列表。

方法是将输入数转化为字符串,通过循环逐个读出,并将其转化为整数存入list_number列表中。

(2)生成最大数和最小数

根据上面产生的列表,得到组成的最大数和最小数。

#根据列表生成整数,并返回最大值最小值
def list_to_number(list_numbers):
    list_numbers.sort()
    max_number_int = 0
    min_number_int = 0
    for index in range(0, len(list_numbers)):  #从循环的时候并不包括len(list_numbers)这个数,这个要注意,即”包头不包尾“
        max_number_int += list_numbers[index]*(10**index)
        min_number_int += list_numbers[index]*(10**(len(list_numbers)-index-1))
    return max_number_int, min_number_int

输入是list_numbers的数字列表,返回max_number_int, min_number_int两个值。

实现方法是将列表进行排序,并根据需要的位数乘以10的相应次方。

(3)确定结束时机

首先以3位和4位数进行编程,判断依据是将生成过程中的最大值保留到变量中,与新的最大值进行比较,如果相等则表示陷入循环,退出

    #方法是最大值与经过变化后最大值一样,陷入循环
        #用于存放最大值,用于比较退出
        use_max_num = 0
        #获取最大值最小值
        maxnum,minnum = list_to_number(list_number01)
        # 循环产生计算过程
        while maxnum != use_max_num:
            #输出计算过程
            print("{0} - {1} = {2}".format(maxnum,minnum,maxnum-minnum))
            use_max_num = maxnum
            list_number = split_number(maxnum - minnum)
            maxnum,minnum = list_to_number(list_number)
        print("{0}位数的数字黑洞为{1}".format(len(list_number01),maxnum-minnum))

过程中注释比较清楚,不过多的做注解。

(4)主程序部分
 #提示按要求输入整数
    print("请输入一个2-10位的整数,要求每一位的数字不同!例如134")
    input_number = input()

    # 分解数据,生成列表
    list_number01 = split_number(input_number)

(5)逐步改进1(5位数以上的实现过程)

5位以上仍以上面的方法进行判断,发现无法实现,会陷入不断的进行中,不能达到停止的条件,经查阅资料后发现,后面的黑洞是一组数而不是一个数,因此上面的解决思路不能解决现在问题,需要新的解决思路。

 #五位以上的数字黑洞会陷入到几个数的组合循环
        #思路,循环,将结果写入一个列表,在结果重复时,加入新的列表,同时设置变量值控制,如果重复超过2次,循环结束
        result_list = []   #写入结果值
        hole_list = []   #写入循环的结果,即为黑洞值

        maxnum, minnum = list_to_number(list_number01)

        while True:
            # 输出计算过程
            print("{0} - {1} = {2}".format(maxnum, minnum, maxnum - minnum))
            result_list.append(maxnum-minnum)    #将结果添加到结果列表中
            list_number = split_number(maxnum - minnum)   #将结果值再进行数字列表
            maxnum, minnum = list_to_number(list_number)   #返回最大值和最小值
            if result_list.count(maxnum-minnum) == 2:     #如果结果值中出现两次,写入黑洞列表
                hole_list.append(maxnum-minnum)
            elif result_list.count(maxnum - minnum) > 2:    #如果结果值中出现三次,退出循环
                break
        print("{0}位数的数字黑洞是:{1}".format(len(list_number01), hole_list))

代码解析:

①黑洞值的序列是用于后面的显示用的

②利用结果的重复数来找到黑洞的列表

③重复3次时结束循环

(6)逐步改进2(2位数的处理)

通过试验2位数的方法也不适用于3位数的计算方法,因此改进代码如下:

#方法是两位变成1位数时进入黑洞
        len_number = 2
        holenum = 0
        maxnum, minnum = list_to_number(list_number01)
        while len_number == 2:
            # 输出计算过程
            print("{0} - {1} = {2}".format(maxnum, minnum, maxnum - minnum))
            holenum = maxnum - minnum
            list_number = split_number(maxnum - minnum)
            len_number = len(list_number)
            maxnum, minnum = list_to_number(list_number)
        print("2位数的数字黑洞为{0}".format(holenum))

思路是当两位数变成一位数时,循环结束。实现过程是利用数字列表的len()决定的。而黑洞的修士值的显示由于直接显示maxnum - minnum会显示后一次的值,即为0,因此在最后次运行前将数字值提前保存,解决了显示不对问题。

(7)主程序完善

完成了输入长度的判断,后发现5位以上的程序完全可以实现的3、4位的功能。因此删除了此部分分代码。

3、完整代码
"""程序用于演示重排求差黑洞
程序输入一个每位都不同的数,程序会按照下面进行演算:
将输入的数字分解为三个不同的数,生成最大的数和最小的数,然后最大数减去最小的数,
将得出的数进行重复操作,直到得到的数不再变化或位数变少为止
依次输出每组的计算
"""

#将一个整数拆分为一个列表返回
#(方法,先转化为字符串,读出后转变类型并写入列表)
def split_number(number):
    list_number = []
    str_number = str(number)
    for item in str_number:
        list_number.append(int(item))
    return list_number


#根据列表生成整数,并返回最大值最小值
def list_to_number(list_numbers):
    list_numbers.sort()
    max_number_int = 0
    min_number_int = 0
    for index in range(0, len(list_numbers)):  #从循环的时候并不包括len(list_numbers)这个数,这个要注意,即”包头不包尾“
        max_number_int += list_numbers[index]*(10**index)
        min_number_int += list_numbers[index]*(10**(len(list_numbers)-index-1))
    return max_number_int, min_number_int


def main():
    #提示按要求输入整数
    print("请输入一个2-10位的整数,要求每一位的数字不同!例如134")
    input_number = input()

    # 分解数据,生成列表
    list_number01 = split_number(input_number)

    #根据输入的位数进行不同方式的处理
    if len(list_number01) <= 1:
        print("您输入的位数不够,请重新输入!")
        main()
    elif len(list_number01) <= 2:
        #方法是两位变成1位数时进入黑洞
        len_number = 2
        holenum = 0
        maxnum, minnum = list_to_number(list_number01)
        while len_number == 2:
            # 输出计算过程
            print("{0} - {1} = {2}".format(maxnum, minnum, maxnum - minnum))
            holenum = maxnum - minnum
            list_number = split_number(maxnum - minnum)
            len_number = len(list_number)
            maxnum, minnum = list_to_number(list_number)
        print("2位数的数字黑洞为{0}".format(holenum))

   
    elif len(list_number01) <= 10:
        #五位以上的数字黑洞会陷入到几个数的组合循环
        #思路,循环,将结果写入一个列表,在结果重复时,加入新的列表,同时设置变量值控制,如果重复超过2次,循环结束
        result_list = []   #写入结果值
        hole_list = []   #写入循环的结果,即为黑洞值

        maxnum, minnum = list_to_number(list_number01)

        while True:
            # 输出计算过程
            print("{0} - {1} = {2}".format(maxnum, minnum, maxnum - minnum))
            result_list.append(maxnum-minnum)    #将结果添加到结果列表中
            list_number = split_number(maxnum - minnum)   #将结果值再进行数字列表
            maxnum, minnum = list_to_number(list_number)   #返回最大值和最小值
            if result_list.count(maxnum-minnum) == 2:     #如果结果值中出现两次,写入黑洞列表
                hole_list.append(maxnum-minnum)
            elif result_list.count(maxnum - minnum) > 2:    #如果结果值中出现三次,退出循环
                break
        print("{0}位数的数字黑洞是:{1}".format(len(list_number01), hole_list))
    else:
        print("你输入的位数超过10位,不符合要求!,请重新输入!")
        main()


main()

4、输出结果

(1)两位数

请输入一个2-10位的整数,要求每一位的数字不同!例如134
29
92 - 29 = 63
63 - 36 = 27
72 - 27 = 45
54 - 45 = 9
2位数的数字黑洞为9

(2)三位数

请输入一个2-10位的整数,要求每一位的数字不同!例如134
123
321 - 123 = 198
981 - 189 = 792
972 - 279 = 693
963 - 369 = 594
954 - 459 = 495
954 - 459 = 495
954 - 459 = 495
3位数的数字黑洞是:[495]

(3)四位数

请输入一个2-10位的整数,要求每一位的数字不同!例如134
1234
4321 - 1234 = 3087
8730 - 378 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
7641 - 1467 = 6174
4位数的数字黑洞是:[6174]

(4)五位数

请输入一个2-10位的整数,要求每一位的数字不同!例如134
12345
54321 - 12345 = 41976
97641 - 14679 = 82962
98622 - 22689 = 75933
97533 - 33579 = 63954
96543 - 34569 = 61974
97641 - 14679 = 82962
98622 - 22689 = 75933
97533 - 33579 = 63954
96543 - 34569 = 61974
97641 - 14679 = 82962
98622 - 22689 = 75933
97533 - 33579 = 63954
96543 - 34569 = 61974
5位数的数字黑洞是:[82962, 75933, 63954, 61974]

(5)六位数

请输入一个2-10位的整数,要求每一位的数字不同!例如134
123456
654321 - 123456 = 530865
865530 - 35568 = 829962
998622 - 226899 = 771723
777321 - 123777 = 653544
655443 - 344556 = 310887
887310 - 13788 = 873522
875322 - 223578 = 651744
765441 - 144567 = 620874
876420 - 24678 = 851742
875421 - 124578 = 750843
875430 - 34578 = 840852
885420 - 24588 = 860832
886320 - 23688 = 862632
866322 - 223668 = 642654
665442 - 244566 = 420876
876420 - 24678 = 851742
875421 - 124578 = 750843
875430 - 34578 = 840852
885420 - 24588 = 860832
886320 - 23688 = 862632
866322 - 223668 = 642654
665442 - 244566 = 420876
876420 - 24678 = 851742
875421 - 124578 = 750843
875430 - 34578 = 840852
885420 - 24588 = 860832
886320 - 23688 = 862632
866322 - 223668 = 642654
665442 - 244566 = 420876
6位数的数字黑洞是:[851742, 750843, 840852, 860832, 862632, 642654, 420876]

进程已结束,退出代码0

(6)七位数

请输入一个2-10位的整数,要求每一位的数字不同!例如134
1234567
7654321 - 1234567 = 6419754
9765441 - 1445679 = 8319762
9876321 - 1236789 = 8639532
9865332 - 2335689 = 7529643
9765432 - 2345679 = 7419753
9775431 - 1345779 = 8429652
9865422 - 2245689 = 7619733
9776331 - 1336779 = 8439552
9855432 - 2345589 = 7509843
9875430 - 345789 = 9529641
9965421 - 1245699 = 8719722
9877221 - 1227789 = 8649432
9864432 - 2344689 = 7519743
9775431 - 1345779 = 8429652
9865422 - 2245689 = 7619733
9776331 - 1336779 = 8439552
9855432 - 2345589 = 7509843
9875430 - 345789 = 9529641
9965421 - 1245699 = 8719722
9877221 - 1227789 = 8649432
9864432 - 2344689 = 7519743
9775431 - 1345779 = 8429652
9865422 - 2245689 = 7619733
9776331 - 1336779 = 8439552
9855432 - 2345589 = 7509843
9875430 - 345789 = 9529641
9965421 - 1245699 = 8719722
9877221 - 1227789 = 8649432
9864432 - 2344689 = 7519743
7位数的数字黑洞是:[8429652, 7619733, 8439552, 7509843, 9529641, 8719722, 8649432, 7519743]

(7)八位数

请输入一个2-10位的整数,要求每一位的数字不同!例如134
12345678
87654321 - 12345678 = 75308643
87654330 - 3345678 = 84308652
88654320 - 2345688 = 86308632
88663320 - 2336688 = 86326632
86663322 - 22336668 = 64326654
66654432 - 23445666 = 43208766
87664320 - 2346678 = 85317642
87654321 - 12345678 = 75308643
87654330 - 3345678 = 84308652
88654320 - 2345688 = 86308632
88663320 - 2336688 = 86326632
86663322 - 22336668 = 64326654
66654432 - 23445666 = 43208766
87664320 - 2346678 = 85317642
87654321 - 12345678 = 75308643
87654330 - 3345678 = 84308652
88654320 - 2345688 = 86308632
88663320 - 2336688 = 86326632
86663322 - 22336668 = 64326654
66654432 - 23445666 = 43208766
87664320 - 2346678 = 85317642
8位数的数字黑洞是:[75308643, 84308652, 86308632, 86326632, 64326654, 43208766, 85317642]

(8)九位数

963852074
987654320 - 23456789 = 964197531
997654311 - 113456799 = 884197512
988754211 - 112457889 = 876296322
987663222 - 222366789 = 765296433
976654332 - 233456679 = 743197653
977654331 - 133456779 = 844197552
987554421 - 124455789 = 863098632
988663320 - 23366889 = 965296431
996654321 - 123456699 = 873197622
987763221 - 122367789 = 865395432
986554332 - 233455689 = 753098643
987654330 - 33456789 = 954197541
997554411 - 114455799 = 883098612
988863210 - 12368889 = 976494321
997644321 - 123446799 = 874197522
987754221 - 122457789 = 865296432
986654322 - 223456689 = 763197633
977663331 - 133366779 = 844296552
986554422 - 224455689 = 762098733
987763320 - 23367789 = 964395531
996554331 - 133455699 = 863098632
988663320 - 23366889 = 965296431
996654321 - 123456699 = 873197622
987763221 - 122367789 = 865395432
986554332 - 233455689 = 753098643
987654330 - 33456789 = 954197541
997554411 - 114455799 = 883098612
988863210 - 12368889 = 976494321
997644321 - 123446799 = 874197522
987754221 - 122457789 = 865296432
986654322 - 223456689 = 763197633
977663331 - 133366779 = 844296552
986554422 - 224455689 = 762098733
987763320 - 23367789 = 964395531
996554331 - 133455699 = 863098632
988663320 - 23366889 = 965296431
996654321 - 123456699 = 873197622
987763221 - 122367789 = 865395432
986554332 - 233455689 = 753098643
987654330 - 33456789 = 954197541
997554411 - 114455799 = 883098612
988863210 - 12368889 = 976494321
997644321 - 123446799 = 874197522
987754221 - 122457789 = 865296432
986654322 - 223456689 = 763197633
977663331 - 133366779 = 844296552
986554422 - 224455689 = 762098733
987763320 - 23367789 = 964395531
9位数的数字黑洞是:[863098632, 965296431, 873197622, 865395432, 753098643, 954197541, 883098612, 976494321, 874197522, 865296432, 763197633, 844296552, 762098733, 964395531]
或者:

请输入一个2-10位的整数,要求每一位的数字不同!例如134

123489765
987654321 - 123456789 = 864197532
987654321 - 123456789 = 864197532
987654321 - 123456789 = 864197532
9位数的数字黑洞是:[864197532]

(9)十位数

请输入一个2-10位的整数,要求每一位的数字不同!例如134
9638520741
9876543210 - 123456789 = 9753086421
9876543210 - 123456789 = 9753086421
9876543210 - 123456789 = 9753086421
10位数的数字黑洞是:[9753086421]

心得体会:

利用编程计算研究数学问题是一个一举两得的好事情,可以多方面得到锻炼,下面还会解决相关问题,有兴趣的可以加好友一起学习啊!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/870134.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号