HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMajor

Project Euler Problem #4 - Palindromic number

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
problemnumberprojecteulerpalindromic

Problem

The problem is as follows:


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.

Using Project Euler to stretch my C# learning, I solved problem #4 with the code below. I ran this in a console app to get the answer. How can I improve my code?

class PalindromNumber
{
    public string GetPalindromeNumber(int maxNumber = 999)
    {
        bool breakOut = false;
        int test=0;
        int left = 0;
        int right = 0;
        int biggestNumber = 0;
        string returnString=string.Empty;
        for (left=maxNumber; left >= 0; left--)
        {
            for(right=maxNumber; right >= 0; right--)
            {
                test = left * right;

                string testNumberAsString = Convert.ToString(test);
                string reverse = string.Empty;
                for (int index = testNumberAsString.Length; index > 0; index--)
                {
                    reverse += testNumberAsString[index-1];
                }

                breakOut = (testNumberAsString == reverse && Convert.ToString(left).Length == 3 && Convert.ToString(right).Length == 3);

                if (breakOut )
                {
                    break;
                }
            }

            if (test>biggestNumber)
            {
                biggestNumber = test;
                returnString = $"Palindrome: {test}, Left: {left}, Right: {right}";
            }
        }

        return returnString;
    }
}

Solution

The other answers are all giving you different ways to reorganize your loops. They're all not bad in their own way, but the better solution in C# is to not write any loops in the first place.

Your program could be written like this:

static void Main()
{
    var query = from first in ThreeDigitNumbers()
                from second in ThreeDigitNumbers()
                let product = first * second
                where IsPalindromicNumber(product)
                select product;
    Console.WriteLine(query.Max());
}


Notice how every part of this program reads like the specification of the problem. The problem is "give the maximum of the palindromic numbers that are formed as the product of two three-digit numbers", and clearly that's what this program does.

Writing helper methods IsPalindromicNumber and ThreeDigitNumbers is left as an exercise.

Now, once that program is written and correct, then is the time to start asking questions about whether it is sufficiently fast, and so on. We could notice for instance that we check both 113 x 115 and 115 x 113, even though they obviously have the same result. So we could then modify the query to

from second in ThreeDigitNumbersGreaterThan(first)


and then write that helper method. And so on.

(Exercise: Notice how introducing an optimization can introduce a bug if you're not careful. What bug did I just suggest that you write?)

But the takeaway here is write your program so that it looks like the specification. The specification does not say "write a bunch of loops". It says "find the maximum..." so there should be a call to Max in there somewhere. Write small methods that each do one thing well, and do exactly what they say on the tin.

Code Snippets

static void Main()
{
    var query = from first in ThreeDigitNumbers()
                from second in ThreeDigitNumbers()
                let product = first * second
                where IsPalindromicNumber(product)
                select product;
    Console.WriteLine(query.Max());
}
from second in ThreeDigitNumbersGreaterThan(first)

Context

StackExchange Code Review Q#161172, answer score: 32

Revisions (0)

No revisions yet.