Bill Blogs in C#

Bill Wagner discusses C#, LINQ, and other items of interest

Euler Problem 4: Finding Palindrome numbers

The fourth Euler problem asks you to find the largest palindrome number that is the product of two three digit numbers. For example, the number 919 is a palindrome: it's the same forward and backwards.

To solve this problem, we need to find the product of all combinations of three digit numbers. Well, if you remember your probability, this is a combinatorial problem. Order doesn't matter. That limits the number of combinations.

Next, we need to find palindromes. A little string conversion makes that simple. You can convert the number to a string, then see if the string is equal to its reverse. Strangely, there isn't a method in System.String that can reverse a string. But, there is a Reverse() extension method that's in scope.

Well, let's look at the code:

    1 static void Main(string[] args)

    2 {

    3     var allProducts = from x in Enumerable.Range(100, 900)

    4                       from y in Enumerable.Range(100, 900)

    5                       where x <= y

    6                       let product = x * y

    7                       orderby product descending

    8                       select new { x, y, product };

    9 

   10     var palindrome = (from n in allProducts

   11                        let chars = n.product.ToString()

   12                        let reverse = new string(chars.Reverse().ToArray())

   13                        where chars == reverse

   14                        select n).First();

   15     Console.WriteLine("{0}, {1} => {2}", palindrome.x, palindrome.y,

   16         palindrome.product);

   17 

   18 }

 

The first query is to generate all products of three digit numbers. Notice that the where clause removes permutations that are the same as two numbers. For example, 251*126 would have already been computed from 126*251. Next, notice the 'let' clause. That assigns a local variable in the query expression so that you don't have to compute the product more than once. While we're at it, we order the values by the products in descending order.

The next query finds the palindromes from all those products. As I said earlier, I do this by converting the product to a string, then comparing the string to its reverse. As with the earlier query, I use the let clause to cache some local results and avoid recomputing values.

You'll need to run the code yourself to see the answer.

Published Sunday, April 06, 2008 10:37 PM by wwagner
Filed under: , ,

Comments

# re: Euler Problem 4: Finding Palindrome numbers@ Monday, April 07, 2008 12:49 PM

>> Enumerable.Range(100, 900)

Shouldn't those be Enumerable.Range(100, 999)

??

# re: Euler Problem 4: Finding Palindrome numbers@ Monday, April 07, 2008 5:22 PM

Cool little algorithm. Something interesting to add to it might be finding the first number of the reverse-then-add* series to produce the palindrome. I imagine that would be significantly harder, though!

* note: I think this is also called the 196-algorithm. It's the algorithm where you take a number A, reverse it to make B, then add A and B together. This algorithm is known to produce a palindrome for most numbers very quickly. 196 was the first number found (I believe) for which it does not produce a palindrome, as far as we can tell, ever. I say as far as we can tell, because I don't believe it has even been inductively shown yet; we just haven't been able to find the end of the series, if there is one!

by Kyle

# re: Euler Problem 4: Finding Palindrome numbers@ Monday, April 07, 2008 5:24 PM

Whoops, forgot to mention that you keep doing the reverse then add part and it'll eventually converge (for most numbers).

by Kyle

# re: Euler Problem 4: Finding Palindrome numbers@ Monday, April 07, 2008 6:38 PM

On the way home tonight, I realized that it's impossible to reverse engineer the reverse-then-add algorithm effectively (due to it basically not being a 1-to-1 function). Hence, strike my comments!

by Kyle

# re: Euler Problem 4: Finding Palindrome numbers@ Monday, April 07, 2008 8:49 PM

Very elegant code. I especially like "orderby product descending".

BTW, shouldn't the ranges go to 999?

by Joe

# re: Euler Problem 4: Finding Palindrome numbers@ Monday, April 07, 2008 9:37 PM

A couple folks asked if the Enumerable.Range() call should be Enumerable.Range(100,999) rather than Enumerable.Range(100,900.

The second parameter on the API is the number of elements, not the ending value. So, to get values from 100 through 999, it's (100,900), not (100,999). Oh well.

by wwagner