# EulerProblem043

# Sub-string divisibility (Euler Problem 43)¶

Back to overview.

https://projecteuler.net/problem=43

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 $d_1$ be the 1st digit, $d_2$ be the 2nd digit, and so on. In this way, we note the following:

$d_2d_3d_4$=406 is divisible by 2

$d_3d_4d_5$=063 is divisible by 3

$d_4d_5d_6$=635 is divisible by 5

$d_5d_6d_7=357$ is divisible by 7

$d_6d_7d_8=572$ is divisible by 11

$d_7d_8d_9=728$ is divisible by 13

$d_8d_9d_{10} =289$ is divisible by 17

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

We write a function that tests for the sub-string divisibility property. Then we simply brute force.

In [14]:

    def is_sub_string_divisible(s):
        s = "".join(s)
        if int(s[1:4]) % 2 != 0:
            return False
        if int(s[2:5]) % 3 != 0:
            return False
        if int(s[3:6]) % 5 != 0:
            return False
        if int(s[4:7]) % 7 != 0:
            return False
        if int(s[5:8]) % 11 != 0:
            return False
        if int(s[6:9]) % 13 != 0:
            return False
        if int(s[7:10]) % 17 != 0:
            return False
        return True

    assert(is_sub_string_divisible("1406357289"))
    assert(is_sub_string_divisible("1406357298") ==  False)

In [15]:

    import itertools

    s = sum([int("".join(p)) for p in itertools.permutations("0123456789") if is_sub_string_divisible(p)])

In [17]:

    print(s)
    assert(s == 16695334890)

    16695334890

I just want to write my own permutations functions to see that I am able to do it quickly. We pick each element once and combine it with the permutations for the remaining items:

In [32]:

    def permutations(items):
        items = list(items)
        if not items:
            return [[]]
        perms = []
        for item in items:
            items_new = list(items)
            items_new.remove(item)
            permutations_new = permutations(items_new)
            for perm in permutations_new:
                perms.append([item] + perm)
        return perms

    assert(permutations([]) == [[]])
    assert(permutations([1]) == [[1]])
    assert(permutations([1,2]) == [[1,2], [2,1]])
    assert(permutations([1,2,3]) == [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]])

In [ ]: