Question
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 1^{st} digit, d_2 be the 2^{nd} digit, and so on. In this way, we note the following:
\begin{aligned} d_2d_3d_4 & =406 \text{ is divisible by 2} \\ d_3d_4d_5 & =063 \text{ is divisible by 3} \\ d_4d_5d_6 & =635 \text{ is divisible by 5} \\ d_5d_6d_7 & =357 \text{ is divisible by 7} \\ d_6d_7d_8 & =572 \text{ is divisible by 11} \\ d_7d_8d_9 & =728 \text{ is divisible by 13} \\ d_8d_9d_{10} & =289 \text{ is divisible by 17} \end{aligned}
Find the sum of all 0 to 9 pandigital numbers with this property.
Haskell
import Data.List (nub)
expand :: Int -> String -> [String]
"" = [s | n <- [100..999], n `rem` x == 0, let s = show n, s == nub s]
expand x = [c:s | c <- ['0'..'9'], c `notElem` s, (read (c:take 2 s)) `rem` x == 0]
expand x s
candidates :: [String]
= inner [17, 13, 11, 7, 5, 3, 2, 1] [""] where
candidates = acc
inner [] acc :xs) acc = inner xs $ concatMap (expand x) acc
inner (x
main :: IO ()
= print $ sum $ map read candidates main
$ ghc -O2 -o pandigital-substrings pandigital-substrings.hs
$ time ./pandigital-substrings
real 0m0.003s
user 0m0.000s
sys 0m0.003s
Python
#!/usr/bin/env python
from itertools import *
def has_property(digits):
= [1,2,3,5,7,11,13,17]
primes for i in range(1, len(digits)-2):
if not int(''.join(digits[i:i+3])) % primes[i] == 0:
return False
return True
def convert_list_to_int(l):
return int(''.join(str(i) for i in l))
def main():
= permutations((str(i) for i in range(10)))
pandigitals print(sum(convert_list_to_int(p) for p in pandigitals if has_property(p)))
if __name__ == "__main__":
main()
$ time python3 pandigital-substrings.py
real 0m6.723s
user 0m6.723s
sys 0m0.000s
Ruby
#!/usr/bin/env ruby
= [1,2,3,5,7,11,13,17]
primes puts ('0'..'9').to_a.permutation.select { |digits|
1..7).all? { |i|
([i..i+2].join('').to_i % primes[i] == 0
digits}
}.map { |digits| digits.join('').to_i }.reduce(:+)
$ time ruby pandigital-substrings.rb
real 0m6.471s
user 0m6.470s
sys 0m0.000s