Project Euler Problem 49 (C++和Python)

Problem 49 : Prime permutations

The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases by 3330, is unusual in two ways: (i) each of the three terms are prime, and, (ii) each of the 4-digit numbers are permutations of one another.

There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property, but there is one other 4-digit increasing sequence.

What 12-digit number do you form by concatenating the three terms in this sequence?

C++ source code

#include <iostream>
#include <vector>
#include <set>
#include <iterator>
#include <cmath>      // sqrt()
#include <cassert>    // assert()
#include <ctime>      // clock()

using namespace std;

class PE0049
{
private:
    bool checkPrime(int number);
    set<int> getDigits(int number);
    bool checkArithmeticSequence(int term1, int term2, int term3);

public:
    vector<int> findArithmeticSequence(int range_start, int range_end);
};

bool PE0049::checkPrime(int number)
{
    double squareRoot=sqrt((double)number);

    if (number%2 == 0 && number!=2)
    {
        return false;
    }

    for(int i=3;i<=(int)squareRoot;i+=2)  // 3, 5, 7, ...(int)squareRoot
    {
        if (number % i == 0)
        {
            return false;
        }
    }

    return true;
}

set<int> PE0049::getDigits(int number)
{
    set<int> digits;

    while(number > 0) 
    {
        digits.insert(number%10); 
        number /= 10; 
    }
    
    return digits;
}


bool PE0049::checkArithmeticSequence(int term1, int term2, int term3)
{
    if (true == checkPrime(term2) && true == checkPrime(term3))
    {    
        set<int> term1Digits = getDigits(term1);
        set<int> term2Digits = getDigits(term2);
        
        if (term1Digits == term2Digits) 
        {
            set<int> term3Digits = getDigits(term3);
            
            if (term2Digits == term3Digits)
            {
                return true;
            }
        }
    }

    return false;
}

vector<int> PE0049::findArithmeticSequence(int range_start, int range_end)
{
    // The first arithmetic sequence, 1487, 4817, 8147, 
    int arithmeticSequenceArray[] = {1487, 4817, 8147};
    vector<int> arithmeticSequence_vec;
    arithmeticSequence_vec.assign(arithmeticSequenceArray, 
        arithmeticSequenceArray+sizeof(arithmeticSequenceArray)/sizeof(int));
    // vector<int> arithmeticSequence_vec = {1487, 4817, 8147}; // C++11

    vector<int> arithmeticSequence;
    bool foundFirstSequence = false;
    int term1, term2, term3; 

    for(int n=range_start; n<range_end; n++)
    {
        if (false == checkPrime(n))
        {
            continue;
        }
        term1 = n;
        term2 = term1 + 3330;
        term3 = term2 + 3330;

        if (true == checkArithmeticSequence(term1, term2, term3))
        {
            arithmeticSequence.push_back(term1);
            arithmeticSequence.push_back(term2);
            arithmeticSequence.push_back(term3);    
            
            if (false == foundFirstSequence && 
                arithmeticSequence_vec == arithmeticSequence)
            {
                arithmeticSequence.clear();// first sequence,1487,4817,8147
                foundFirstSequence = true;
            }
            else
            {
                break;       // the second arithmetic sequence is found
            }
        }
    }

    return arithmeticSequence;
}
    
int main()
{
    // There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes,
    // so let's search from 1000 to 9999
    vector<int> resultArray;
    PE0049 pe0049;

    resultArray = pe0049.findArithmeticSequence(1000, 9999);
    
    cout << "The 12-digit number is ";  
    copy(resultArray.begin(), resultArray.end(), ostream_iterator<int>(cout));
    cout << " by concatenating the three terms in this sequence." << endl;

    return 0;
}

Python source code

def checkPrime(number):
    """
    check whether number is a prime
    """
    if number%2 == 0 and number!=2 or number < 2:
        return False

    for i in range(3, int(number**0.5)+1, 2):  # 3, 5, 7, ...(int)squareRoot\
        if number % i == 0:
            return False

    return True

def checkarithmeticSequence_list(term1, term2, term3):
    """
    check whether term1, term2 and term3 can made up of an arithmetic sequence
    """
    if True == checkPrime(term2) and True == checkPrime(term3):
        if set(list(str(term1))) == set(list(str(term2))) and\
           set(list(str(term1))) == set(list(str(term3))): 
            return True
    return False

def findArithmeticSequence_list(range_start, range_end):
    """
    find arithmetic sequence from range_start to range_end
    """
    firstArithmeticSequence_list = ['1487', '4817', '8147']

    arithmeticSequence_list, foundFirstSequence = [], False

    for n in range(range_start, range_end):
        if False == checkPrime(n):
            continue

        term1, term2, term3 = n, n+3330, n+6660 

        if True == checkarithmeticSequence_list(term1, term2, term3):
            arithmeticSequence_list.append(str(term1))
            arithmeticSequence_list.append(str(term2))
            arithmeticSequence_list.append(str(term3))    
            
            if firstArithmeticSequence_list == arithmeticSequence_list and \
               False == foundFirstSequence:
                arithmeticSequence_list.clear() # clear first sequence
                foundFirstSequence = True
            else:
                break       # the second arithmetic sequence is found
    
    return "".join(arithmeticSequence_list)
        
def main():
    print("The 12-digit number is",findArithmeticSequence_list(1000,9999),\
          "by concatenating the three terms in this sequence.")

if  __name__ == '__main__':
    main()
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值