Finding Digit Strings In Powers Of Two
September 24, 2013
[ I told you in a previous exercise that I was having internet connectivity issues at home. It took three weeks, but a repairman from the local telephone company finally found that, during repairs on the soffit underneath my roof overhang, the roofer nailed through a board with a nail that was too long, so it penetrated the board and the telephone cable that was nailed to the other side of the board. As the temperature and humidity changed during the day, sometimes the nail made contact with two ends of the same conductor, and everything worked properly, but sometimes the nail made contact with two different conductors, causing a short circuit and preventing the telephone from working. At the same time, my wifi router developed some kind of internal problem, also intermittent. I have now replaced both the wire and the router and everything seems to be working. The problems were hard to solve because both of them were intermittent. ]
Today’s problem comes from one or another of the competitive programming sites, I’m not sure which:
Search every power of two below 210000 and return the index of the first power of two in which a target string appears. For instance, if the target is 42, the correct answer is 19 because 219 = 524288, in which the target 42 appears as the third and fourth digits, and no smaller power of two contains the string 42.
Your task is to write the search program described above. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
Rather easy in Python. The functions returns -1 of no index is found.
I rather like Haskell’s
Maybe
.Graham: The corresponding idiom in Scheme is to return an empty list ‘() for Nothing and a non-empty list containing the value ‘(x) for Just. Those two return values are easy to distinguish by the null? and pair? predicates, and since both are lists there is no issue of type mis-match as there would be if you returned say an integer for the value x or the boolean #f for Nothing.
Paul and Graham: I think for both of you it would be quicker to build your list of powers of two by repeatedly multiplying by two, as the suggested solution does, rather than exponentiating at each step.
Indeed it is slower to use 2**i for each step. Here a version where the string representations for all powers arecalculated first (costs a little time).
Fair enough!
I like the Scheme idiom and the Python version of returning -1 (or even throwing an exception,
if the setting is right). I’m just recently somewhat enamored with Haskell’s types, though; they
make the meaning of the code clear to me in a way that these idioms don’t, I guess.
//Using Java
Double[] pow = new Double[1000];
private void calculatePOW()
{
for(int i=0;i<1000;i++)
pow[i] = Math.pow(2,i);
}
public int searchinPOW(int x)
{
int index = -1;
for(int i=0;i<pow.length;i++)
{
double power = pow[i];
if(String.valueOf(power).contains(String.valueOf(x)))
{
index = i;
break;
}
}
return index;
}
Forgive my formatting !!
In Racket:
Here is a C# solution with caching.
I used a suffix trie to store the number sequences (without the compression the your usual suffix trie has).
The numbers are stored implicitly as indexes in the children.
I also annotated the minimum base-two exponent that can reach each node in the suffix tree.
So if a digit sequence has been seen before, its O(n) performance (n = amount of digits).