Problem 40 : Champernowne’s constant
An irrational decimal fraction is created by concatenating the positive integers:
0.123456789101112131415161718192021…
It can be seen that the 12th digit of the fractional part is 1.
If dn represents the nth digit of the fractional part, find the value of the following expression.
d1 × d10 × d100 × d1000 × d10000 × d100000 × d1000000
C++ source code
#include <iostream>
#include <cmath>
#include <cassert>
#include <ctime>
using namespace std;
// #define UNIT_TEST
class PE0040
{
private:
static const int MAX = 1000000;
int m_digits[10];
int getDigits(int number);
public:
int findValueOfExpression();
};
int PE0040::getDigits(int number)
{
int numOfDigits = 0;
while(number> 0)
{
m_digits[numOfDigits++] = number%10;
number /= 10;
}
return numOfDigits;
}
int PE0040::findValueOfExpression()
{
int numOfDigits;
int numOfFractionDigits = 0;
short *irrationalDecimalFractionDigits = new short[MAX+1];
for(int number=1; numOfFractionDigits<=MAX; number++)
{
numOfDigits = getDigits(number);
for(int i=numOfDigits-1; i>=0 && numOfFractionDigits<=MAX; i--)
{
irrationalDecimalFractionDigits[numOfFractionDigits++] = m_digits[i];
}
}
assert (1 == irrationalDecimalFractionDigits[11]); //12th
int index;
int product = 1;
for(int exp = 0; exp<7; exp++)
{
index = (int)pow(10.0, exp); // 10^0, 10^1, 10^2, 10^3, 10^4, 10^5, 10^6
#ifdef UNIT_TEST
cout << "d" << index << " : " << irrationalDecimalFractionDigits[index-1]<<endl;
#endif
product *= irrationalDecimalFractionDigits[index-1];
}
delete [] irrationalDecimalFractionDigits;
return product;
}
int main()
{
clock_t start = clock();
PE0040 pe0040;
cout << "d1 x d10 x d100 x d1000 x d10000 x d100000 x d1000000 = ";
cout << pe0040.findValueOfExpression() << endl;
clock_t finish = clock();
double duration = (double)(finish - start) / CLOCKS_PER_SEC;
cout << "C/C++ application running time: " << duration << " seconds" << endl;
return 0;
}
Python source code
def concatenatePositiveIntegersToString(max):
"""
concatenate positive integers and return digits string
which length is more than max
string s looks like '.123456789101112131415161718192021'
"""
n, s = 1, '.'
while len(s) <= max:
s += str(n)
n += 1
return s
def calculateValueOfExpression(max):
"""
calculate value of expression:
d1 x d10 x d100 x d1000 x d10000 x d100000 x d1000000
"""
s = concatenatePositiveIntegersToString(max)
assert 1 == int(s[12])
product = 1
for exp in range(0, 7):
index = int(pow(10.0, exp)) #10^0, 10^1, 10^2, 10^3, 10^4, 10^5, 10^6
product *= int(s[index])
return product
def main():
print("d1 x d10 x d100 x d1000 x d10000 x d100000 x d1000000 = ",\
calculateValueOfExpression(10**6))
if __name__ == '__main__':
main()