# Number palindrome checker

My daughter, nine, recently had some homework looking at number palindromes. Part of the assignment was to take a number, reverse it, add the two together and repeat until she got a palindrome and to do this for several different numbers.

While helping her with this it struck me it'd be a nice simple idea for a computer program. She & I have messed about in Scratch a bit, but this sounded like a nice problem to do in a more commercial language. Thought I could write it and then show her how it worked.

So I did. It turned out to be not quite as child-friendly as I'd imagined.

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace CheckNumberPalindrome
{
class Program
{
static void Main(string[] args)
{
string rollingSum;
int iterations = 1;

if(IsNumeric(args[0]) == false)
{
Console.WriteLine("You did not enter a numeric value");
}

rollingSum = RecurseUntilPalindrome(args[0], ref iterations);
Console.WriteLine(string.Format("The final palindrome is {0}, which took {1} steps.", rollingSum, iterations));
}

private static bool IsNumeric(string s)
{
long result;
return Int64.TryParse(s, out result);
}

private static string RecurseUntilPalindrome(string s, ref int iterations)
{
long rollingSum = AddToPalindrome(s);

if(IsPalindrome(rollingSum.ToString()))
{
return rollingSum.ToString();
}

iterations++;
return RecurseUntilPalindrome(rollingSum.ToString(), ref iterations);
}

private static long AddToPalindrome(string s)
{
string reversedString = ReverseString(s);
long result = Convert.ToInt64(s) + Convert.ToInt64(reversedString);
Console.WriteLine(string.Format("Adding {0} to {1} = {2}", s, reversedString, result));
return result;
}

private static string ReverseString(string s)
{
char[] charArray = s.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}

private static bool IsPalindrome(string s)
{
return s.SequenceEqual(ReverseString(s));
}
}
}


There are two questions here:

1. How could I make this better or cleaner or more efficient or any of the other things that CR does so well?

2. What could I do (beside hiding some of the functions in pre-compiled code elsewhere) to make this more child-friendly, or better for teaching/explaining some basic code concepts?

• FWIW, Console.WriteLine has an overload that takes a format string and an array of objects so you don't need to use string.Format. – RobH Mar 16 '15 at 14:38

Overall your code looks very nice, readable and maintainable. I only have a few remarks:

• Input validation:
if(IsNumeric(args[0]) == false)
{
Console.WriteLine("You did not enter a numeric value");
}
rollingSum = RecurseUntilPalindrome(args[0], ref iterations);


Why continue the program when the input is invalid (not numeric)? Check for a numeric value and only continue if the input is a number:

if(IsNumeric(args[0]))
{
//Continue here...
}
else
{
Console.WriteLine("You didn't enter a valid number!");
}

• Format in Console.WriteLine:

Following line:

Console.WriteLine(string.Format("The final palindrome is {0}, which took {1} steps.", rollingSum, iterations));


can be rewritten as:

Console.WriteLine("The final palindrome is {0}, which took {1} steps.", rollingSum, iterations);


No need to call the String.Format.

• Check for palindrome:

While writing previous points I found that there had to be an easier way to achieve the same result. There are numerous ways to check for a palindrome. For numbers you can also use this method:

public static bool IsPalindrome(Int64 input)
{
Int64 reverse = 0;
var temp = input;

while (temp != 0)
{
var rem = temp % 10;
reverse = reverse * 10 + rem;
temp /= 10;
}

return reverse == input;
}


When using this method, there's no need for creating strings and arrays and again conversions to numbers. Your entire code can be written as follows:

Int64 startNumber;
var steps = 1;
var input = args[0];

if (Int64.TryParse(input, out startNumber))
{
Int64 reversed;

while(!IsPalindrome(startNumber, out reversed))
{
steps++;
var temp = startNumber + reversed;
Console.WriteLine("Adding {0} to {1} = {2}", reversed, startNumber, temp);
startNumber = temp;
}

Console.WriteLine("The final palindrome is {0}, which took {1} steps.", startNumber, steps);
}
else
{
Console.WriteLine("You didn't enter a valid number!");
}

• Nice, thanks. I went with comparing against a reverse string because I thought it would be easier to explain than how the maths works. Pretty silly of me to do recursion rather than a while loop, though - the latter is much easier to explain, too! – Bob Tway Mar 16 '15 at 16:18
• It's not illogical to use recursion but I try to avoid it when a simple loop can solve the problem. And I understand that 'reversing a string' is easier to explain to a 9-year old than the piece of math. Kudos for your daughter though for trying/willing to understand this matter! :) – Abbas Mar 16 '15 at 20:27

This may help with your second point about code concepts:

How about addressing the special case for when the user enters a palindrome? It looks to me like you are assuming the entered number will not be a palindrome and you automatically add to it (calling RecurseUntilPalindrome). How about adding an initial check to account for that case? I think it would go along well with your numerical value input check (I consider invalid user input as a sort of special case as well).

To address your first point, I think your code looks pretty clean as is! Really easy to follow.

• Thanks. A good thought - perhaps I'll take her through the code and then, if she's interested, help her put together the extra validation you're suggesting. – Bob Tway Mar 16 '15 at 14:35