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:
- d2d3d4=406 is divisible by 2
- d3d4d5=063 is divisible by 3
- d4d5d6=635 is divisible by 5
- d5d6d7=357 is divisible by 7
- d6d7d8=572 is divisible by 11
- d7d8d9=728 is divisible by 13
- d8d9d10=289 is divisible by 17
Find the sum of all 0 to 9 pandigital numbers with this property.
let rec distribute e = function |  -> [[e]] | x::xs' as xs -> (e::xs)::[for xs in distribute e xs' -> x::xs] let rec permute = function |  -> [] | e::xs -> List.collect (distribute e) (permute xs) // generate the 0 to 9 pandigitals let numbers = permute [0..9] |> List.map (fun l -> l |> List.map string |> List.reduce (+)) // the corresponding prime divisors and digits let primes = [2; 3; 5; 7; 11; 13; 17] let ns = [2..10] |> Seq.windowed 3 |> Seq.toList // returns the number retrieved from taking the digits at the supplied positions let d ns (numberStr:string) = int(ns |> Array.map (fun n -> numberStr.[n-1].ToString()) |> Array.reduce (+)) // predicate which identifies pandigital numbers with the desired property let predicate number = List.forall2 (fun n p -> (d n number) % p = 0) ns primes let answer = numbers |> List.filter predicate |> List.sumBy int64
One thing you might notice in the creation of the permutations of all 0 to 9 pandigital numbers is the use of (+) in the List.reduce function call. This is actually just the shortened form of:
List.reduce (fun acc item –> acc + item)
Another List function of interest here is the List.forAll2 function, which tests if all corresponding elements in both lists satisfy the given predicate pairwise. In this case, I’m using it to pair up the digits list ([[2;3;4]; [3;4;5];…]) with the primes list ([2;3;5;..17]) to test if a given number has the desired property as described in the problem brief.
We arrive at the answer by simply adding up all the pandigital numbers which matches the predicate condition.
I specialise in rapidly transitioning teams to serverless and building production-ready services on AWS.
Are you struggling with serverless or need guidance on best practices? Do you want someone to review your architecture and help you avoid costly mistakes down the line? Whatever the case, I’m here to help.
Check out my new course, Complete Guide to AWS Step Functions. In this course, we’ll cover everything you need to know to use AWS Step Functions service effectively. Including basic concepts, HTTP and event triggers, activities, callbacks, nested workflows, design patterns and best practices.
Here is a complete list of all my posts on serverless and AWS Lambda. In the meantime, here are a few of my most popular blog posts.
- Lambda optimization tip – enable HTTP keep-alive
- You are thinking about serverless costs all wrong
- Many faced threats to Serverless security
- We can do better than percentile latencies
- I’m afraid you’re thinking about AWS Lambda cold starts all wrong
- Yubl’s road to Serverless
- AWS Lambda – should you have few monolithic functions or many single-purposed functions?
- AWS Lambda – compare coldstart time with different languages, memory and code sizes
- Guys, we’re doing pagination wrong