


If ‘N’ = 7,
Then we start with the integer 7 and replace it with (7 * 7) = 49.
The new number is 49, we replace it with (4 * 4) + (9 * 9) = 97.
We replace this new number 97 with (9 * 9) + (7 * 7) = 130.
We replace this new number 130 with (1 * 1) + (3 * 3) + (0 * 0) = 10.
We replace this new number 10 with (1 * 1) + (0 * 0) = 1.
Therefore, the original number 7 is a good number.
The first line contains a single integer ‘T’ denoting the number of test cases, then each test case follows:
The first line of each test case contains a single integer ‘N’, denoting the input number.
For each test case, print “true” if the number is a good number, else print “false”.
Output for each test case will be printed in a separate line.
You are not required to print anything; it has already been taken care of. Just implement the function.
1 ≤ ‘T’ ≤ 10
1 ≤ N ≤ 10000
Time limit: 1 sec
Intuitively one may figure out that for a number that is not good we will get a loop, that is we will start generating a number that was generated earlier, and thereafter we will get stuck in this infinite loop and won’t be able to reach 1.
But is this condition enough, the answer to that is YES!
One may argue that a condition might be possible where the given number is not good and will generate infinitely many numbers as a loop won’t exist, but this will never happen, let us discuss why: Let’s start with a claim that an upper bound must exist on the range of the number for a loop to exist (just to avoid infinitely many numbers being generated), let that upper bound number be ‘U’ for a while, and let the function d(U) denote the number of digits in the U, if all the numbers in U are equal to 9 then one may get the next number is equal to 81 * d(U), one may also easily conclude that 81 * d(U) < 100 * d(U). Therefore, the number of digits in this new number which is equal to d(81*d(U)) will be less than d(100*d(U)), we can simplify this to conclude that number of digits in the new number will be less than 2 + d(U), in the best case when all the digits of this new number are equal to 9 then the maximum possible value of this new number will be 9 * ( 2 + d(U) ) which is clearly less than the value of U, therefore, we can conclude that an upper bound U will always exist and a number which is not a good number will have a cycle.
We can now use a simple hash-set to keep the track of numbers we have already generated. And in future, if we regenerate this number then we can say that an infinite loop exists and return “false”. Else we will reach the number 1 and return “true” in that case.
Intuitively one may figure out that for a number that is not good we will get a loop, that is we will start generating a number that was generated earlier, and thereafter we will get stuck in this infinite loop and won’t be able to reach 1.
But is this condition enough, the answer to that is YES!
One may argue that a condition might be possible where the given number is not good and will generate infinitely many numbers as a loop won’t exist, but this will never happen, let us discuss why: Let’s start with a claim that an upper bound must exist on the range of the number for a loop to exist (just to avoid infinitely many numbers being generated), let that upper bound number be ‘U’ for a while, and let the function d(U) denote the number of digits in the U, if all the numbers in U are equal to 9 then one may get the next number is equal to 81 * d(U), one may also easily conclude that 81 * d(U) < 100 * d(U). Therefore, the number of digits in this new number which is equal to d(81*d(U)) will be less than d(100*d(U)), we can simplify this to conclude that number of digits in the new number will be less than 2 + d(U), in the best case when all the digits of this new number are equal to 9 then the maximum possible value of this new number will be 9 * ( 2 + d(U) ) which is clearly less than the value of U, therefore, we can conclude that an upper bound U will always exist and a number which is not a good number will have a cycle.
We can now use some cycle finding algorithm to find if a loop exists, Floyd's Cycle-Finding Algorithm is a commonly used algorithm where we consider two pointers, a slow pointer which takes one step at a time and a fast pointer which takes two steps at a time, and according to this algorithm if a cycle exists then both the slow and fast pointers point to the same element after some finite iterations, you may read about this algorithm or you may just try the above-discussed logic to take an intuition of it. The benefit of using this method is that we now no longer need extra space to store all the generated elements in a hash-set.