The Puzzle: A 3 digit number is added to another 3 digit number giving a sum. The sum is a 4 digit number.
All the 10 digits are unique, that is, we use all digits from 0 to 9.
Find the smallest such numbers.
This puzzle comes from here.
The starting point to this puzzle is very similar to our last puzzle.
let digits (i:int) =
i.ToString().ToCharArray() |> Array.map (fun c -> (int) c - (int)'0')
let uniqueDigits (arr:'a[]) =
let mutable result = true
let last = arr.Length - 1
for i = 0 to (last - 1) do
for j = i+1 to last do
if arr.[i] = arr.[j] then result <- false
result
let candidates = seq { 123 .. 987 }
We start with helper utilities to check if all the digits in a number are unique.
All the possible three-digit numbers are candidates for the two numbers we are adding.
let uniqueDigits1 num = digits num |> uniqueDigits
let uniqueDigits2 fst snd =
let fst, snd = digits fst, digits snd
Array.append fst snd |> uniqueDigits
let uniqueDigits3 fst snd thd =
let fst, snd, thd = digits fst, digits snd, digits thd
Array.append fst snd |> Array.append thd |> uniqueDigits
let numCand = candidates |> Seq.filter uniqueDigits1
let search() = seq {
for fst in numCand do
for snd in numCand do
let res = fst + snd
if res > 1000 && uniqueDigits3 fst snd res
then yield (fst, snd, res)
}
let ans = search() |> Seq.head
Functions uniqueDigits1, uniqueDigits2 and uniqueDigits3 tell us whether the provided one, two and three arguments all have unique digits amongst them. We put the digits from the argument numbers into one big array and check if all elements of the array are unique.
Once that is done, it is pretty easy to get all the answers in search(). Since the numbers in numCand are sorted, the first result in the sequence is the smallest answer.