Project Euler Problem 43 Solution

Project Euler Problem 43 Solution

Sub-string divisibility

by {BetaProjects} | Project Euler & HackerRank

Project Euler Problem 43 Statement

The number, 1406357289, is a 0 to 9 pandigital number because it is made up of each of the digits 0 to 9 in some order, but it also has a rather interesting sub-string divisibility property.

Let d1 be the 1st digit, d2 be the 2nd digit, and so on. In this way, we note the following:

Find the sum of all 0 to 9 pandigital numbers with this property.

Solution

There are only 9 x 9! (3,265,920) possible 0-9 ten-digit pandigital numbers. Simply generate the possibilities and check each three-digit section to be divisible by the appropriate prime number. But even on a fast computer this method may take too long to run.

We can make some observations to reduce the number of possibilities. Keep in mind we are dealing with 3 digit numbers that must have unique digits in order to qualify as part of a 0-9 pandigital ten-digit number.

Some observations

Observation 1: If d4d5d6 must be divisible by 5 then:
d6 = {0, 5}.

Observation 2: d6d7d8 must to be divisible by 11 and, according to Obs. 1, has to start with a {0, 5}. Well, it can’t start with 0 as that would yield non-unique digits {011, 022, ..., 099}, so it has to start with 5: d6 = 5.
d6d7d8 = {506, 517, 528, 539, 561, 572, 583, 594}

Since this is a closed ended problem a simple brute force search works very well. The observations are used to help minimize the search range.

HackerRank version

HackerRank extends the requirement from jhust 0-9 pandigital numbers to 0-3 to 0-9 pandigital numbers.

Python Source Code

from itertools import permutations
N = int(input("Number of pandigital digits 3-9? "))
q = [(1,2),(2,3),(3,5),(4,7),(5,11),(6,13),(7,17)]
s = 0
for p in permutations('0123456789'[:N+1]):
    if N>6 and p[5]!='5': continue
    if all(not int(''.join(p[px:px+3])) % pn for px,pn in q[:N-2]):
        s+= int(''.join(p))
print("Sum of all",N,"digit pandigital numbers with the sub-string divisibility property", s)	

Last Word

You could continue to make observations that would reduce the search space. Here are a few:

Observation 3: d7d8d9 must be divisible by 13, begin with {06, 17, 28, 39, 61, 72, 83, 94} by Obs. 2, contain no 5s and have only unique digits:
d7d8d9 = {286 390 728 832}

Observation 4: d8d9d10 must be divisible by 17, begin with {28, 32, 86, 90} by Obs. 3, contain no 5s and have only unique digits:
d8d9d10 = {289, 867, 901}

Observation 5: d5d6d7 must be divisible by 7, end with {52, 53, 57, 58} by Obs. 2 & 3 and have only unique digits:
d5d6d7 = {357, 952}

We have reduced our possibilities for the last 6 digits using our 5 observations to:
d5d6d7d8d9d10 = {357289, 952867}

Observation 6: d3d4d5 must be divisible by 3, not contain {2, 5, 7, 8} since they have been place, end in {3, 9}, have all unique digits and an even middle number:
d3d4d5 = {063, 309, 603}

This forces d1d2 to {14, 41}

Our final set is: {1406357289, 1430952867, 1460357289, 4106357289, 4130952867, 4160357289}