ok, take #2 now that I've (hopefully) got my addition straight.
It looks like the key here is to do a translation from radix-2 math to radix-3 math with some kind of state machine.
Let's say the input after k bits is some binary decimal. We don't know whether the input has terminated yet or not. Therefore let's say the input number is some number x[k] + an unknown number between 0 and 2-k-1. This interval is either completely outside of the Cantor Set (in which case we return 0), or it is possibly inside the Cantor Set, in which case we continue. Now to figure out if that's codeable as a state machine....
...this seems fiendishly difficult, never mind the code golf aspects of it. I have a rough outline of how to approach, coding a pair of Cantor Set boundaries (e.g. [1/3,2/3] or [1/9,2/9]) as a pair of integers scaled by a number M = 2k3j, and the current input interval as a pair of integers scaled by M, but the numbers seem to be getting larger and larger, so it doesn't seem to lend itself to a finite state machine as far as I can tell. :/
very rough algorithm, in javascript-y pseudocode, no attempt at code size minimization:
var j = 0; // power of 3 we scale to
var k = 0; // power of 2 we scale to
var x0=0, x1=1; // ends of an interval within cantor-set after stage j
var i0=0, i1=1; // ends of the interval containing the input number
// These intervals are [x0,x1] (closed) and [i0,i1) (half-open)
while (1)
{
b = get_input_bit(); // (0 or 1), or -1 if input has terminated
if (b == -1)
break;
++k;
if (b == 0) // lower half of previous interval
{
i1 = i0+i1;
i0 <<= 1;
}
else // upper half of previous interval
{
i0 = i0+i1;
i1 <<= 1;
}
x0 <<= 1;
x1 <<= 1;
if (i1 <= x0 || i0 > x1)
{
// Possible Cantor interval and input interval are disjoint...
// the entire input interval is outside the Cantor set.
// Stop and return debugging info.
return {inSet: false, i0:i0,i1:i1,x0:x0,x1:x1,j:j,k:k};
}
// Now to compare input interval with Cantor interval.
if ((i1-i0)*3 < (x1-x0))
{ // If input interval is less than 1/3 size of Cantor interval,
// it can overlap at most 1 subinterval.
// Figure out which one.
//scale up by a factor of 3
++j;
i1 *= 3;
i0 *= 3;
yB = 2*x1+x0;
yA = 2*x0+x1;
// middle third of the cantor interval = [yA,yB]
if (i1 <= yB)
{
// input interval excludes right third of Cantor interval,
// so make the left third our new Cantor interval
x0 = 3*x0;
x1 = yA;
}
else if (i0 > yA)
{
// input interval excludes left third of Cantor interval,
// so make the right third our new Cantor interval
x0 = yB;
x1 = 3*x1;
}
else
{
throw("Algorithm error, I made a horrible mistake");
}
// now shift everything over (this algorithm uses relative integers,
// and does not rely on absolute integers)
x0 -= i0;
x1 -= i0;
i1 -= i0;
i0 = 0;
}
}
// OK, now the input has terminated, and we have to figure out whether
// the input can be expressed as an infinitely repeating series of 0's or 2's
// in ternary.
// Left as an exercise to the reader, it's late and I have to get to sleep.... 8/
return {inSet: true, i0:i0,i1:i1,x0:x0,x1:x1,j:j,k:k};
I think I have the "return false" case covered... sigh.