A tough question

Jim Little jiml@inconnect.com
Fri, 11 Jun 1999 00:15:43 -0600


Tunesters,

I've got a problem that you might be interested in.  I think I've solved
it, but I think it's a fairly common problem, so you might know a better
way or see a flaw in my reasoning.  Besides, it's a fun challenge.

The challenge is to create an algorithm:

input: a string of decimal digits representing an integer
outputs: a string of binary digits representing the same integer
example: Given '42', return '101010'.

The catch: The input string can be arbitrary length.  So you can't just
convert the string to a 32-bit (or 64-bit, or 128-bit, etc) integer and
read off the bits.

I think I've got a solution which is O(n) for memory and O(n log n) for
CPU.  Here it is: (stop reading now if you want to try to solve it
yourself)

Tril: You never really explained your 'shift' technique.  I'd like to
hear about that if you don't mind.



[spoiler space]



















The key is to use the standard algorithm for converting decimal to
binary, but to make it operate as a string algorithm, not as a numeric
algorithm.  So here it is:

0. Start with empty output string.
1. Look at the right-most character in the input string.
2. If it is in {1, 3, 5, 7, 9}:
   2a2. Add a '1' to the front of the output string.
   2a1. Convert 1->0, 3->2, 5->4, 7->6, 9->8.
Else it is in {0, 2, 4, 6, 8}:
   2b1. Add a '0' to the front of the output string.
3. Perform "Divide" algorithm on input string.
5. If input string is '0', stop.  Else go to step 1.

The "Divide" algorithm:
Constraint: The right-most character of the string must be in {0, 2, 4,
6, 8}.

1. Look at the right-most character of the string.
2. If it is in {0, 2, 4, 6, 8}:
   2a1. Convert 0->0, 2->1, 4->2, 6->3, 8->4.
Else it is in {1, 3, 5, 7, 9}:
   2b1. Convert 1->0, 3->1, 5->3, 7->5, 9->7.
   2b2. Convert next character to right: 4->9, 3->8, 2->7, 1->6, 0->5.
3. Look at next character to the left.
4. If there is such a character, go to step 2.  Else stop.

Jim