Project Euler – Problem 4 (Haskell vs C#)

In: C#|Functional Programming|Haskell

16 Jun 2011

Learning a new programming language is perhaps one of the most rewarding experiences. You can learn about how another language performs a task, if it seems simpler how does this compare to your current language?

Problem 4 from Project Euler goes something like the folowing.

A palindromic number reads the same both ways.

The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.

Find the largest palindrome made from the product of two 3-digit numbers.

Haskell

1
2
3
4
5
6
7
8
9
10
11
12
13
module Main where
 
main = putStrLn output
output = show result
 
largestpalindrome :: Int
largestpalindrome = maximum [ p | i <- [100..999],
                           j <- [i..999],
                           let p = i * j,
                           let t = show p,
                           t == reverse t]
 
result = largestpalindrome

I almost missed this part in the actual question “A palindromic number reads the same both ways”. So a number is a palindrome if its string representation is equal to its reversed string representation.

The solution in Haskell relies on Generators and List Comprehension. In this case we’re generating a list of numbers using sequences, and then filtering that list by the numbers which read the same back to front.

In the above case you can read the function as follows.

Select the largest number from
the product of 2 3 digit numbers
where string of the product is equal to the reverse of the string of product

Based on that algorithm, here’s the c# version using linq

C# using Linq

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
static void Main()
{		
	Console.WriteLine(
		string.Format("Largest Palindrome of the product of 3 digit numbers is: {0}", 
			Palindrome(ThreeDigitProducts()).Max())
		);
	Console.ReadKey();
}
 
private static IEnumerable<int> ThreeDigitProducts()
{
	return from i in Sequence(100, 999)
		 from j in Sequence(i, 999)
		 select i*j;				   				   
}
 
private static IEnumerable<int> Palindrome(IEnumerable<int> seedProducts)
{
	return from p in seedProducts
	       where p.ToString() == new string (p.ToString().Reverse().ToArray())
	       select p;
}
 
private static IEnumerable<int> Sequence(int from, int to)
{
	return Enumerable.Range(from, to).Where(x => x < to);
}

I have to say that I was quite surprised at how easy it was to generate near functional syntax in c# using linq.

Comments?

Comment Form

About Justin

justin

Justin is a Senior Software Engineer living in Brisbane. A Polyglot Developer proficient in multiple programming languages including [C#, C/C++, Java, Android, Ruby..]. He's currently taking an active interest in Teaching Kids to Code, Functional Programming, Robotics, 3D Printers, RC Quad-Copters and Augmented Reality.

About This Blog

Software Engineering is an art form, a tricky art form that takes as much raw talent as it does technical know how. I'll be posting articles on professional tips and tricks, dos and donts, and tutorials.

profile for Justin Shield on Stack Exchange, a network of free, community-driven Q&A sites

Photostream

  • What I look for in a senior software engineer Justin Shield: […] I’m not going to list the design patterns that you’ll need, I’ve already [...]
  • Justin: Hi Ross, I do actually like Umbraco, it provides some nice abilities for creating websites that I [...]
  • Justin: Hi GordonBGood, Thanks for taking the time in replying. You're absolutely correct, it is turners s [...]
  • Ross Gallagher: Hi Justin, I'm a fellow Aussi looking to use Umbraco to create a simple website. I have downloaded [...]
  • GordonBGood: This is the "Turner Sieve" which **IS NOT** the Sieve of Eratosthenes (SoE) neither by algorithm nor [...]