1
\$\begingroup\$

I've cobbled together as best I could an answer using the format found here provided. I lack full understanding of how the LINQ query works and don't want to use it without understanding well the how and why of what's occurring.

Regarding NumberIsAPalindrome, I tried to use number.ToString().Reverse().ToString() but was unable to achieve the results I expected, so I reverted to a for...loop. Is this achievable?

class PalindromNumber
{
    public string GetPalindromeNumber(int maxNumber = 999)
    {
        var query = from first in ThreeDigitNumbers()
                    from second in ThreeDigitNumbers()
                    let product = first * second
                    where NumberIsAPalindrome(product)
                    select product;
        return query.Max().ToString();
    }

    public int[] ThreeDigitNumbers()
    {
        int[] numberArray = new int[900];
        for (int i = 0; i < numberArray.Length; i++)
        {
            numberArray[i] = 999 - i;
        }
        return numberArray;
    }

    public bool NumberIsAPalindrome(int number)
    {
        int reversedValue=0;
        string stringNumber = number.ToString();
        for (int i= stringNumber.Length-1; i >= 0; i--)
        {
            reversedValue += (int.Parse(stringNumber[i].ToString()) * (int)Math.Pow(10,i) );
        }
        return number == reversedValue;
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ I reverted to a for...loop. Is this achievable? I thought you tested it? \$\endgroup\$
    – t3chb0t
    Apr 25 '17 at 6:23
  • \$\begingroup\$ My comment about "Is this achievable?" refers to number.ToString().Reverse().ToString(). It does seem a bit confusing looking at that part now. \$\endgroup\$
    – IvenBach
    Apr 25 '17 at 15:45
1
\$\begingroup\$

You were on the right track starting with number.ToString(). However, you don't need to duplicate the string, just check whether the value at each index is the same as the value at the index the same distance from the other end:

bool IsPalindrome(int number)
{
    string num = number.ToString();
    for (int i = 0, j = num.Length - 1; i < num.Length / 2; i++, j--)
    {
        if (num[i] != num[j])
        {
            return false;
        }
    }
    return true;
}
\$\endgroup\$
0
\$\begingroup\$
    public string GetPalindromeNumber(int maxNumber = 999)

Where is maxNumber used?


    public int[] ThreeDigitNumbers()
    {
        int[] numberArray = new int[900];
        for (int i = 0; i < numberArray.Length; i++)
        {
            numberArray[i] = 999 - i;
        }
        return numberArray;
    }

The calling code doesn't care that it's an array, so coding to the interface rather than the implementation means that it should return IEnumerable<int> instead of int[].

You could make this quite a bit shorter in one of two ways. The first option, since the calling code doesn't care about the order of the numbers it returns, is

    public IEnumerable<int> ThreeDigitNumbers() => Enumerable.Range(100, 900);

The second option, if the calling code did care about the order, would be to effectively implement Enumerable.Range with a negative increment:

    public IEnumerable<int> ThreeDigitNumbers()
    {
        for (int i = 999; i > 99; i--) yield return i;
    }

Both of these shorter versions are lazy, which isn't particularly important in this case but will give big memory savings if you try to scale it up. (Time would still be an issue...)


I tried to use number.ToString().Reverse().ToString() but was unable to achieve the results I expected

Indeed, string.Reverse() gives an IEnumerable<char> with no special override of ToString(). The most LINQy way of naïvely reversing a string is new string(str.Reverse().ToArray()), but as mentioned before there are various subtleties.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.