Project Euler Problem 32 (C++和Python)

本文探讨了泛数字乘积的概念,即乘数、被乘数和乘积共同组成使用所有1到9数字各一次的9位数。通过C++和Python代码实现,找出所有满足条件的乘积并求和,验证了特定泛数字乘积的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem 32 : Pandigital products

We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital.

The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.

Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.

HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.

C++ source code

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <ctime>
#include <cassert>

using namespace std;

class PE0032
{
private:
    set<int> m_products_s;

    bool checkNumberDigits(int number);
    vector<int> getDigits(int number);
    vector<int> Intersection(vector<int>& v1, vector<int>& v2, vector<int>& v3);
    void  getPandigitalProducts();

public:
    bool checkPandigital(int multiplicand, int multiplier, int product);
    int PE0032::getSumOfProducts();
};

bool PE0032::checkNumberDigits(int number)
{
    set<int> digits_s;
    int i = 0;

    while(number>0)
    {
        if (0 == number%10)
        {
            return false;
        }
        else
        {
            digits_s.insert(number%10);
            number /= 10;
            i++;
        }
    }

    if (i !=  digits_s.size())
    {
        return false;
    }
    else
    {
        return true;
    }
}

vector<int> PE0032::getDigits(int number)
{
    vector<int>digits_v;

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

    return digits_v;
}

vector<int> PE0032::Intersection(vector<int>& v1, vector<int>& v2, vector<int>& v3)
{
    vector<int>::iterator iter;

    for(iter=v1.begin(); iter!=v1.end(); iter++)
    {
        v3.push_back(*iter);
    }

    for(iter=v2.begin(); iter!=v2.end(); iter++)
    {
        v3.push_back(*iter);
    }

    sort(v3.begin(), v3.end());  

    return v3;
}

int PE0032::getSumOfProducts()
{
    getPandigitalProducts();

    set<int>::iterator iter;
    int sum = 0;

    for(iter=m_products_s.begin(); iter!=m_products_s.end(); iter++)
    {
        sum += *iter;
    }

    return sum;
}

bool PE0032::checkPandigital(int multiplicand, int multiplier, int product)
{
    vector<int> multiplicand_v = getDigits(multiplicand);
    vector<int> multiplier_v   = getDigits(multiplier);
    vector<int> product_v      = getDigits(product);

    vector<int> res = Intersection(multiplicand_v, multiplier_v, product_v);

    if (res.size() != 9)
    {
        return false;
    }

    for(int i=1; i<=9; i++)
    {
        if (res[i-1] != i)
        {
            return false;
        }
    }

    return true;
}

void PE0032::getPandigitalProducts()
{
    for(int multiplier=2; multiplier<2000; multiplier++)
    {
        if (false == checkNumberDigits(multiplier))
        {
            continue;
        }

        for(int multiplicand=1; 
            multiplicand<multiplier && multiplicand<9876/multiplier; 
            multiplicand++)
        {
            if (false == checkNumberDigits(multiplicand))
            {
                continue;
            }

            // 9876    =  4  * 2351
            // 9876    = 54  * 213
            int product = multiplicand * multiplier;

            if (false == checkNumberDigits(product))
            {
                continue;
            }

            if (true == checkPandigital(multiplicand, multiplier, product))
            {
#ifdef UNIT_TEST
                cout << product << " = " <<  multiplicand << " x "<<multiplier<<endl;
#endif
                m_products_s.insert(product);
            }
        }
    }

#ifdef UNIT_TEST
    copy(m_products_s.begin(), m_products_s.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
#endif
}

int main()
{
    clock_t start = clock();

    PE0032 pe0032;

    assert(true == pe0032.checkPandigital(39, 186, 7254));

    cout << "The sum of all products whose multiplicand/multiplier/product " << endl;
    cout << "identity can be written as a 1 through 9 pandigital is " ;
    cout << pe0032.getSumOfProducts() << endl;

    clock_t finish = clock();
    double duration = (double)(finish - start) / CLOCKS_PER_SEC;
    cout << "C/C++ running time: " << duration << " seconds" << endl;

    return 0;
}

Python source code

def checkPandigital(s, d=9):
    """ 
    check whether digits string is pandigital 
    s: digits string. d: number of digits (default 9) 
    """
    return len(s)==d and not '1234567890'[:d].strip(s)
    
def checkPandigitalProduct(multiplicand, multiplier, product):
    s = str(multiplicand)+str(multiplier)+str(product)
    return checkPandigital(s) 
    
def checkNumberDigits(number):
    """
    if number contains digit 0 or duplicated digits, return False
    """
    s = str(number)        # 4076   -> '4076'
    digits = list(set(s))  # '4066' -> ['4','0',6']
    if len(digits) != len(s) or '0' in digits: # ['4','0','6']
        return False
    return True

def getPandigitalProducts():
    """
    get all Pandigital Products and put them into set products_s
    """
    products_s = set()

    for multiplier in range(2, 2000):
        if False == checkNumberDigits(multiplier):
            continue

        multiplicand = 1 
        while multiplicand < multiplier and multiplicand < 9876/multiplier: 
            if False == checkNumberDigits(multiplicand):
                multiplicand += 1
                continue

            product = multiplicand * multiplier  # 9876 = 54 * 213 

            if False == checkNumberDigits(product):
                multiplicand += 1
                continue

            if True == checkPandigitalProduct(multiplicand, multiplier, product):
                #print(product,"=",multiplicand,"x",multiplier)
                products_s.add(product)

            multiplicand += 1
    return products_s

def getSumOfProducts():
    products_s = getPandigitalProducts()
    return sum(products_s)
    
def main():
    assert True == checkPandigitalProduct(39, 186, 7254)

    print("The sum of all products whose multiplicand/multiplier/product")
    print("identity can be written as a 1 through 9 pandigital is",getSumOfProducts())

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值