The quick and dirty code I wrote was
#include
#include
class s {
private:
char indx;
char ondx;
char v[10];
public:
bool done;
unsigned long long count;
s(void) {
indx = '\0';
ondx = '\0';
done = false;
count= 0UL;
}
void put (char c) {
v[indx++] = c;
indx = indx % 10;
}
char get (void) {
char c = v[ondx++];
ondx = ondx %10;
return c;
}
char peek (void) {
return v[ondx];
}
bool isEmpty (void) {
return indx == ondx;
}
};
s context[100];
// the two functions "nextItem" and "doCount" call each other recursively.
bool nextItem (char& c, int level);
// count number of consecutive instances of v from level below
// return count as a character in 'c'; save v with msb set. and
// character which terminated count in context.
void doCount (char& c, char v, int level) {
bool r = false;
s& x = context[level];
c = '1';
x.put (v + 0X80);
while (!x.done) {
char t;
x.done = nextItem (t, level - 1);
if (t == v) {
c++;
}
else {
// count is complete so we need to put the terminating value
// in the buffer, value we are counting is already there
x.put (t);
break;
}
}
}
// return in 'c' the next character from the specified level
// signal done if that character is the last.
// there are two special cases:
// 1) level = 0, the single character '1' is returned and done is signalled
// 2) There are no characters held in the context (this must be the first entry)
// Otherwise there are one or two characters in the context. If the next character
// held in the context ha the msb set, the count has already been returned so the
// character should be returned. Otherwise the character is the terminating character
// from the last count and more repetitions (if any) must be counted, after which the
// count is returned. When the lower level has signalled done, then when the last
// character is returned also signal done.
// Count the number of characters returned and when the last character is returned and
// done s signalled, report the level and the total.
bool nextItem (char& c, int level) {
s& x = context[level];
bool r = false;
if (!x.isEmpty()) {
// more ready to output
char v = x.get();
c = v & 0X7F;
if (v & 0X80) {
r = x.isEmpty();
}
else {
// this is the next value and we need to count any more
doCount (c, v, level);
}
}
else if (level == 0) {
// at the lowest level the seed is a single '1'
c