Project Euler Poblem 55 (C++和Python)

100 篇文章 3 订阅
87 篇文章 1 订阅
本文探讨了Lychrel数的概念,这些数在反转并相加的过程中永远不会形成回文数。通过C++和Python代码实现,我们计算了10000以下的Lychrel数的数量,展示了如何判断一个数是否为Lychrel数,并验证了特定数如349的迭代过程。
摘要由CSDN通过智能技术生成

Problem 55 : Lychrel numbers

If we take 47, reverse and add, 47 + 74 = 121, which is palindromic.

Not all numbers produce palindromes so quickly. For example,

349 + 943 = 1292,
1292 + 2921 = 4213
4213 + 3124 = 7337

That is, 349 took three iterations to arrive at a palindrome.

Although no one has proved it yet, it is thought that some numbers, like 196, never produce a palindrome. A number that never forms a palindrome through the reverse and add process is called a Lychrel number. Due to the theoretical nature of these numbers, and for the purpose of this problem, we shall assume that a number is Lychrel until proven otherwise. In addition you are given that for every number below ten-thousand, it will either (i) become a palindrome in less than fifty iterations, or, (ii) no one, with all the computing power that exists, has managed so far to map it to a palindrome. In fact, 10677 is the first number to be shown to require over fifty iterations before producing a palindrome: 4668731596684224866951378664 (53 iterations, 28-digits).

Surprisingly, there are palindromic numbers that are themselves Lychrel numbers; the first example is 4994.

How many Lychrel numbers are there below ten-thousand?

NOTE: Wording was modified slightly on 24 April 2007 to emphasise the theoretical nature of Lychrel numbers.

C++ 代码

#include <iostream>
#include <vector>
#include <cassert>

using namespace std;

class PE0055
{
public:
    bool checkPalindromeNumber(int number, int iteration);
    int getNumOfLychrelNumbers(int max);

private:
    vector<int> getDigits(int number);
    vector<int> reverseAndAddDigits(vector<int>& num_digits_vec);
    bool checkLychrelNumber(int number, int max_iterations);
    bool checkPalindrome(vector<int>digits_vec);
};

vector<int> PE0055::getDigits(int number)
{
    vector<int> num_digit_vec;

    while(number> 0)
    {
        num_digit_vec.push_back(number%10);
        number /= 10; 
    }

    return num_digit_vec;
}

vector<int> PE0055::reverseAndAddDigits(vector<int>& num_digits_vec)
{
    vector<int> reverse_num_digits_vec;
    
    reverse_num_digits_vec.assign(num_digits_vec.rbegin(), num_digits_vec.rend());

    int size = num_digits_vec.size();
    vector<int> sum_digits_vec(size);
    int decade_flag = 0;

    for(int i=0; i<size; i++)
    {
        sum_digits_vec[i] += num_digits_vec[i] + reverse_num_digits_vec[i];
        decade_flag = sum_digits_vec[i]/10;
        sum_digits_vec[i] %= 10;
        if (i+1<size)
        {
            sum_digits_vec[i+1] += decade_flag;
        }
    }

    if (decade_flag == 1)
    {
        sum_digits_vec.push_back(1);
    }
  
    return sum_digits_vec; 
}

bool PE0055::checkPalindrome(vector<int> digits_vec)
{
    int size=digits_vec.size();

    for(int i = 0; i<size/2; i++)
    {
        if(digits_vec[i] != digits_vec[size-1-i])
        {
            return false;
        }
    }

    return true;
}
    
bool PE0055::checkPalindromeNumber(int number, int iteration)
{
    vector<int> num_digits_vec;
    vector<int> sum_digits_vec;
    
    num_digits_vec = getDigits(number);
    
    for (int n=1; n<=iteration; n++) 
    {
        sum_digits_vec = reverseAndAddDigits(num_digits_vec);
        if (true == checkPalindrome(sum_digits_vec))
        {
            return true;
        }
        num_digits_vec = sum_digits_vec;
    }

    return false;
}

bool PE0055::checkLychrelNumber(int number, int max_iterations=50)
{
    vector<int> num_digits_vec;
    vector<int> sum_digits_vec;
    
    num_digits_vec = getDigits(number);
    
    for (int iteration=1; iteration<=max_iterations; iteration++) 
    {
        sum_digits_vec = reverseAndAddDigits(num_digits_vec);
        if (true == checkPalindrome(sum_digits_vec))
        {
            return false;
        }
        num_digits_vec = sum_digits_vec;
    }

    return true;
}

int PE0055::getNumOfLychrelNumbers(int max)
{
    int NumOfLychrel = 0;
    for (int n=1; n<max; n++)
    {
        if(true == checkLychrelNumber(n))
        {
            NumOfLychrel++;
        }
    }

    return NumOfLychrel;
}

int main()
{
    PE0055 pe0055;

    assert(true == pe0055.checkPalindromeNumber(349, 3));

    cout << "There are " << pe0055.getNumOfLychrelNumbers(10000);
    cout << " Lychrel numbers below ten-thousand" << endl;

    return 0;
} 

Python 代码

def checkPalindrome(product):
    return str(product) == str(product)[::-1]
    
def checkPalindromeNumber(number, iterations):
    for iteration in range(1, iterations+1):
        reverse_number = int(str(number)[::-1])
        number += reverse_number
        if True == checkPalindrome(number):
            return True
    return False

def checkLychrelNumber(number, iterations=50):
    for iteration in range(1, iterations+1):
        reverse_number = int(str(number)[::-1])
        number += reverse_number
        if True == checkPalindrome(number):
            return False
    return True

def getNumOfLychrelNumbers(max):
    return sum (True == checkLychrelNumber(n) for n in range (1, max+1))

def main():
    assert True == checkPalindromeNumber(349, 3)

    print("There are", getNumOfLychrelNumbers(10000),end='');
    print(" Lychrel numbers below ten-thousand")
    
if  __name__ == '__main__':
    main()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值