1. 程式人生 > >Project Euler Poblem 55 (C++和Python)

Project Euler Poblem 55 (C++和Python)

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()