用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]

心得体会:

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

猜你喜欢

转载自blog.csdn.net/sygoodman/article/details/124672539