Good, so it's weird. I have an algorithm for finding the maximum possible numerical palindrome, which consists of two factors, each of which has K-digits.
The method I use to find the highest allowed palindrome is to look at the maximum possible palindrome for a set of numbers (i.e. if k = 3, the maximum is 999999, then 998899, etc.). Then I check to see if this palindrome has two K-digit factors.
For debugging, I thought it would be nice to print on the console all the palindromes that I checked (to make sure that I get them. To my surprise, adding
Console.WriteLine(palindrome.ToString());
for each iteration of the palindrome search, my runtime of the whole 10 seconds was deleted from ~ 24 to ~ 14.
To check, I ran the program several times, then commented out the Console command and executed it several times, and each time it was shorter using the Console command.
It just seems strange, any ideas?
Here's the source if someone wants to hit him:
static double GetHighestPalindromeBench(int k) { //Because the result of k == 1 is a known quantity, and results in aberrant behavior in the algorithm, handle as separate case if (k == 1) { return 9; } ///////////////////////////////////// //These variables will be used in HasKDigitFactors(), no need to reprocess them each time the function is called double kTotalSpace = 10; for (int i = 1; i < k; i++) { kTotalSpace *= 10; } double digitConstant = kTotalSpace; //digitConstant is used in HasKDigits() to determine if a factor has the right number of digits double kFloor = kTotalSpace / 10; //kFloor is the lowest number that has k digits (eg k = 5, kFloor = 10000) double digitConstantFloor = kFloor - digitConstant; //also used in HasKDigits() kTotalSpace--; //kTotalSpace is the highest number that has k digits (eg k = 5, kTotalSpace = 99999) ///////////////////////////////////////// double totalSpace = 10; double halfSpace = 10; int reversionConstant = k; for (int i = 1; i < k * 2; i++) { totalSpace *= 10; } double floor = totalSpace / 100; totalSpace--; for (int i = 1; i < k; i++) { halfSpace *= 10; } double halfSpaceFloor = halfSpace / 10; //10000 double halfSpaceStart = halfSpace - 1; //99999 for (double i = halfSpaceStart; i > halfSpaceFloor; i--) { double value = i; double palindrome = i; //First generate the full palindrome for (int j = 0; j < reversionConstant; j++) { int digit = (int)value % 10; palindrome = palindrome * 10 + digit; value = value / 10; } Console.WriteLine(palindrome.ToString()); //palindrome should be ready //Now we check the factors of the palindrome to see if they match k //We only need to check possible factors between our k floor and ceiling, other factors do not solve if (HasKDigitFactors(palindrome, kTotalSpace, digitConstant, kFloor, digitConstantFloor)) { return palindrome; } } return 0; } static bool HasKDigitFactors(double palindrome, double totalSpace, double digitConstant, double floor, double digitConstantFloor) { for (double i = floor; i <= totalSpace; i++) { if (palindrome % i == 0) { double factor = palindrome / i; if (HasKDigits(factor, digitConstant, digitConstantFloor)) { return true; } } } return false; } static bool HasKDigits(double value, double digitConstant, double digitConstantFloor) { //if (Math.Floor(Math.Log10(value) + 1) == k) //{ // return true; //} if (value - digitConstant > digitConstantFloor && value - digitConstant < 0) { return true; } return false; }
Note that I have a Math.Floor operation in HasKDigits. It all started when I tried to determine if the digit check operation was faster than the Math.Floor operation. Thanks!
EDIT: function call
I use StopWatch to measure processing time. I also used a physical stopwatch to check StopWatch results.
Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); double palindrome = GetHighestPalindromeBench(6); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}:{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); Console.WriteLine(); Console.WriteLine(palindrome.ToString()); Console.WriteLine(); Console.WriteLine(elapsedTime);