Yan Cui
I help clients go faster for less using serverless technologies.
This article is brought to you by
Don’t reinvent the patterns. Catalyst gives you consistent APIs for messaging, data, and workflow with key microservice patterns like circuit-breakers and retries for free.
Problem
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 x 99.
Find the largest palindrome made from the product of two 3-digit numbers.
Solution
open System.Linq let isPalindromic n = let charArray = n.ToString().ToCharArray() let revCharArray = Array.rev charArray charArray.SequenceEqual(revCharArray) let numbers = [100..999] let products = numbers |> List.collect (fun x -> numbers |> List.map (fun y -> x * y)) let maxPalindromic = products |> Seq.filter isPalindromic |> Seq.max
In my solution above, I first built a function to check whether a given number is palindromic by comparing the original and reversed char array representing the number and see if they’re the same, i.e. 9009 is represented by the char array [‘9′;’0′;’0′;’9’], and the reversed array is still [‘9′;’0′;’0′;’9’].
Notice how I used the Array.rev function in the isPalindromic function, it returns a new array with all the elements in reverse order. Another thing you might have noticed in this function is that I used the Enumerable.SequenceEqual Linq extension method to compare the two arrays, as I’ve mentioned before, with F# being a first class citizens of the .Net family you’re free to use whatever CLR library of your choice.
The rest of the solution might be relatively straight forward, however, you might be wondering what the List.collect function does. Like the List.map function, it applies a function to each element in the list, except that each element produces a list and all these lists are concatenated into a final list.
Now let’s see how the two differs, say we have a list of numbers from 1 to 10, and I want to find out the Cartesian product of the list multiplied by itself, i.e. 1 * 1, 1 * 2, … 1 * 10, 2 * 1, 2 * 2… 10 * 10:
let numbers = [1..10] // List.map returns an array of array containing results of 1 * [1..10], 2 * [1..10], etc. numbers |> List.map (fun x -> numbers |> List.map(fun y -> x * y));; val it : int list list = [[1; 2; 3; 4; 5; 6; 7; 8; 9; 10]; [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]; [3; 6; 9; 12; 15; 18; 21; 24; 27; 30]; [4; 8; 12; 16; 20; 24; 28; 32; 36; 40]; [5; 10; 15; 20; 25; 30; 35; 40; 45; 50]; [6; 12; 18; 24; 30; 36; 42; 48; 54; 60]; [7; 14; 21; 28; 35; 42; 49; 56; 63; 70]; [8; 16; 24; 32; 40; 48; 56; 64; 72; 80]; [9; 18; 27; 36; 45; 54; 63; 72; 81; 90]; [10; 20; 30; 40; 50; 60; 70; 80; 90; 100]] // List.collect returns a 1-dimensional array instead numbers |> List.collect (fun x -> numbers |> List.map (fun y -> x * y));; val it : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 2; 4; 6; 8; 10; 12; 14; 16; 18; 20; 3; 6; 9; 12; 15; 18; 21; 24; 27; 30; 4; 8; 12; 16; 20; 24; 28; 32; 36; 40; 5; 10; 15; 20; 25; 30; 35; 40; 45; 50; 6; 12; 18; 24; 30; 36; 42; 48; 54; 60; 7; 14; 21; 28; 35; 42; 49; 56; 63; 70; 8; 16; 24; 32; 40; 48; 56; 64; 72; 80; 9; 18; 27; 36; 45; 54; 63; 72; 81; 90; 10; 20; 30; 40; 50; 60; 70; 80; 90; 100]
Whenever you’re ready, here are 3 ways I can help you:
- Production-Ready Serverless: Join 20+ AWS Heroes & Community Builders and 1000+ other students in levelling up your serverless game. This is your one-stop shop for quickly levelling up your serverless skills.
- I help clients launch product ideas, improve their development processes and upskill their teams. If you’d like to work together, then let’s get in touch.
- Join my community on Discord, ask questions, and join the discussion on all things AWS and Serverless.
Pingback: Project Euler — Problem 36 Solution | theburningmonk.com
my solution:
let reverseNumber n =
let rec loop acc = function
|0 -> acc
|x -> loop (acc * 10 + x % 10) (x/10)
loop 0 n
let isPalindrome = function
| x when x = reverseNumber x -> true
| _ -> false
let max =[for a in 100 .. 999 do
for b in 100 .. 999 do yield a*b]
|> Seq.filter (fun x -> isPalindrome x)
|> Seq.max