python卡布列克常数

问题描述

对于任意一个4位数n,进行如下的运算:
1.将组成该4位数的4个数字由大到小排列,形成由这4个数字构成的最大的4位数。
2.将组成该4位数的4个数字由小到大排列,形成由这4个数字构成的最小的4位数(如果4个数中含有0,则得到的数不足4位)。
3.求这两个数的差,得到一个新的4位数(高位0保留),这称为对n进行了一次卡布列克运算。存在这样一个规律:对一个各位数字不全相同的4位数重复进行若干次卡布列克运算,最后得到的结果总是6174,这种数被称为卡布列克数,请用python编程证明此规律。

        这个问题的本质就是:现有一个4位数number,求出number中4个数字构成的最大的4位数max_number和number中4个数字构成的最小的4位数min_number。使用max_number减去min_number得到sub_number,查看sub_number是否等于6174。如果sub_number不等于6174,则把sub_number当成number来重复上面的过程,直到sub_number等于6174。为了防止出现sub_number等于0而变成死循环的情况,在sub_number等于0时也需要结束运算。

求4个数字构成的最大4位数

        我们可以把这个4位数转换为一个字符串,每次从字符串中找出最大的数字放到一个新字符串中,再去除字符串中最大的数字。如此循环4次即可得到最大4位数的新字符串,再把这个新字符串转换为整型,就得到了最大4位数。代码如下:

def max_number(number: int):
    """
    生成number中的4个数字组成的最大4位数
    
    :param number: 一个整数
    :return: 最大4为数
    """
    s_number = str(number).zfill(4)  # 把整数转换为字符串,用zfill处理一下字符串,当number不足4位时,在前面添0补齐
    r_number = ''  # 定义一个新字符串
    for i in range(4):  # 循环4次
        r_number += max(s_number)  # 使用max找出字符串中最大的数字,放到新字符串中
        s_number = s_number.replace(max(s_number), '', 1)  # 把字符串中最大的数字替换为空字符,防止有重复数字,只替换一个
    return int(r_number)  # 返回最大4为数

求4个数字构成的最小4位数

        我们可以把这个4位数转换为一个字符串,每次从字符串中找出最小的数字放到一个新字符串中,再去除字符串中最小的数字。如此循环4次即可得到最小4位数的新字符串,再把这个新字符串转换为整型,就得到了最小4位数。代码如下:

def min_number(number: int):
    """
    生成number中的4个数字组成的最小4位数

    :param number: 一个整数
    :return: 最小4为数
    """
    s_number = str(number).zfill(4)  # 把整数转换为字符串,用zfill处理一下字符串,当number不足4位时,在前面添0补齐
    r_number = ''  # 定义一个新字符串
    for i in range(4):  # 循环4次
        r_number += min(s_number)  # 使用min找出字符串中最小的数字,放到新字符串中
        s_number = s_number.replace(min(s_number), '', 1)  # 把字符串中最小的数字替换为空字符,防止有重复数字,只替换一个
    return int(r_number)  # 返回最小4为数

做卡布列克运算

        现有一个4位数number各位数字不全相同,在一个循环中,使用max_number函数求出number的最大4位数b_number,使用min_number函数求出number的最小4位数l_number。判断b_number减去l_number的结果是否等于6174或0,如果不等于6174或0,把结果赋值给number重复上面的步骤(循环),如果等于6174或0结束循环。代码如下:

def cableck_constant(number: int):
    """
    卡布列克常数
    
    :param number: 一个4位正整数
    :return: 
    """
    if type(number) != int:  # 检查number的类型是不是整型
        raise TypeError('number is not int')  # 不是则整型抛出类型错误
    if number < 1000 or number > 9999:  # 检查number的值是不是4位数
        raise ValueError('number range [1000, 9999]')  # 不是则抛出值错误
    while number != 6174 and number != 0:  # 当number等于6174或0时结束循环
        l_number = min_number(number)  # 求出最小4位数
        b_number = max_number(number)  # 求出最大4位数
        number = b_number - l_number  # 把最大4位数和最小4位数的差赋值给number
        print(f'{b_number} - {l_number:4} = {number}')  # 打印一下计算过程

完整代码

        把上面3个函数合起来就能得到完整代码:

def min_number(number: int):
    """
    生成number中的4个数字组成的最小4位数

    :param number: 一个整数
    :return: 最小4为数
    """
    s_number = str(number).zfill(4)  # 把整数转换为字符串,用zfill处理一下字符串,当number不足4位时,在前面添0补齐
    r_number = ''  # 定义一个新字符串
    for i in range(4):  # 循环4次
        r_number += min(s_number)  # 使用min找出字符串中最小的数字,放到新字符串中
        s_number = s_number.replace(min(s_number), '', 1)  # 把字符串中最小的数字替换为空字符,防止有重复数字,只替换一个
    return int(r_number)  # 返回最小4为数


def max_number(number: int):
    """
    生成number中的4个数字组成的最大4位数

    :param number: 一个整数
    :return: 最大4为数
    """
    s_number = str(number).zfill(4)  # 把整数转换为字符串,用zfill处理一下字符串,当number不足4位时,在前面添0补齐
    r_number = ''  # 定义一个新字符串
    for i in range(4):  # 循环4次
        r_number += max(s_number)  # 使用max找出字符串中最大的数字,放到新字符串中
        s_number = s_number.replace(max(s_number), '', 1)  # 把字符串中最大的数字替换为空字符,防止有重复数字,只替换一个
    return int(r_number)  # 返回最大4为数


def cableck_constant(number: int):
    """
    卡布列克常数

    :param number: 一个4位正整数
    :return:
    """
    if type(number) != int:  # 检查number的类型是不是整型
        raise TypeError('number is not int')  # 不是则整型抛出类型错误
    if number < 1000 or number > 9999:  # 检查number的值是不是4位数
        raise ValueError('number range [1000, 9999]')  # 不是则抛出值错误
    while number != 6174 and number != 0:  # 当number等于6174或0时结束循环
        l_number = min_number(number)  # 求出最小4位数
        b_number = max_number(number)  # 求出最大4位数
        number = b_number - l_number  # 把最大4位数和最小4位数的差赋值给number
        print(f'{b_number} - {l_number:4} = {number}')  # 打印一下计算过程


cableck_constant(1234)

执行结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值