Project Euler Problem 32 (C++和Python)

100 篇文章 3 订阅
87 篇文章 1 订阅

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()
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
欧拉方法(Euler's method)是一种数值解决微分方程的方法,可以用来解决放射性衰变模型。放射性衰变是指放射性元素随时间的推移而发生变化,其中的衰变速率与现有放射性元素的数量成正比。 首先,我们需要定义微分方程的公式。根据放射性衰变模型,衰变速率(decay rate)可以用以下公式表示: decay_rate = -k * N 其中,k 是衰变常数,N 是现有放射性元素的数量。负号表示放射性元素数量会随时间的推移而减少。 然后,我们可以使用欧拉方法来近似地解决该微分方程。在一个时间间隔 h 内,放射性元素数量的变化可以用以下公式表示: N_new = N + h * decay_rate 在每个时间步长 h 中,我们可以根据上述公式计算新的放射性元素的数量。然后,将该数量作为下一个时间步长的初始值,重复这个过程直到达到我们所需的时间范围。 下面是使用 Python 代码实现该模型的一个简单示例: ```python import numpy as np import matplotlib.pyplot as plt def decay_model(N0, k, h, num_steps): N = [N0] # 初始化放射性元素的数量为 N0 for _ in range(num_steps): decay_rate = -k * N[-1] # 计算衰变速率 N_new = N[-1] + h * decay_rate # 计算新的放射性元素的数量 N.append(N_new) # 将新的数量添加到列表中 return N N0 = 1000 # 初始的放射性元素的数量 k = 0.01 # 衰变常数 h = 0.1 # 时间步长 num_steps = 100 # 进行模拟的时间步数 # 调用 decay_model 函数得到放射性元素的数量列表 N = decay_model(N0, k, h, num_steps) # 绘制放射性元素数量随时间变化的图像 t = np.arange(0, (num_steps + 1) * h, h) plt.plot(t, N) plt.xlabel('Time') plt.ylabel('Number of Radioactive Elements') plt.title('Decay Model') plt.show() ``` 通过运行上述代码,我们可以得到一个描述放射性衰变模型的图表。该图表显示了放射性元素数量随时间变化的曲线。这样,我们就使用欧拉方法用 Python 解决了放射性衰变问题。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值