Project Euler Problem #38:

Problem #38 is one of the many problems on Project Euler that requires permutations of the digits 1-9, also known as pandigitals. The question reads:

Project Euler Problem 38: Pandigital multiples
Take the number 192 and multiply it by each of 1, 2, and 3:

192 × 1 = 192
192 × 2 = 384
192 × 3 = 576

By concatenating each product we get the 1 to 9 pandigital, 192384576. We will call 192384576 the concatenated product of 192 and (1,2,3)

The same can be achieved by starting with 9 and multiplying by 1, 2, 3, 4, and 5, giving the pandigital, 918273645, which is the concatenated product of 9 and (1,2,3,4,5).

What is the largest 1 to 9 pandigital 9-digit number that can be formed as the concatenated product of an integer with (1,2, ... , n) where n > 1?

You can probably guess that my solution to this problem will involve brute force. However, there is a way to make the brute force more efficient with information in the problem.

Solution #1: Brute Force Approach

Using the fact that 918273645 is a pandigital number with this property, we know that the largest pandigital number must be larger than 918273645. Thus, the number that generates the largest pandigital number should be greater than a prefix of 918273645. If it has 2 digits, it should be greater than or equal to 91. If it has 3 digits, it should be greater than or equal to 918. Continuing with this reasoning, we only have to check numbers between each prefix and the next smallest power of 10. Here is an implementation of this method in Python 2.7:

 '''
 Author: Walker Kroubalkian
 Brute Force Approach to Project Euler Problem #38
 '''
 
 import time
 from collections import Counter
 
 def pandigital(n):
     a = str(n)
     c = 2
     while(len(a)<9):
         a+=str(n*c)
         c+=1
     if(len(a)!=9):
         return -1
     if Counter(a) == Counter("123456789"):
         return int(a)
     return -1
 
 def projectEulerProblemThirtyEight(maxKnown):
     c = 2
     temp = maxKnown
     while(c<=4):
         start = int(str(maxKnown)[0:c]) + 1
         while(start<10**c):
             v = pandigital(start)
             if(v>temp):
                 temp = v
             start+=1
         c+=1
     return temp
 
 start = time.time()
 print projectEulerProblemThirtyEight(918273645)
 print ("--- %s seconds ---" % (time.time()-start))

 '''
 Prints
 
 932718654
 --- 0.00893306732178 seconds ---

 for input of n = 918273645
 ''' 

As shown above, brute force iteration can be fairly efficient if you put a bit of thought into using it.

Thanks for reading!

Published by Walker Kroubalkian

My name is Walker Kroubalkian. I really enjoy math, computer science, and hiking.

Leave a comment

Design a site like this with WordPress.com
Get started