Cでやってみました。
2ビット見て判断するというアルゴリズムです。
00: 右にも左にも横線がない -> 下の段に移動するだけ
11: 右と左に横線がある -> 横断しているだけなので下に移動するだけ
01: 右に横線がある -> 0にぶつかるまで右に移動して下の段に移動する
10: 左に横線がある -> 0にぶつかるまで左に移動して下の段に移動する
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NCOLS 9
#define NROWS 4
void str2a(const char *s, unsigned char *a)
{
*a = 0;
do {
if (*s >= '0' && *s <= '9')
*a = (*a << 4) + *s - '0';
else if (*s >= 'a' && *s <= 'f')
*a = (*a << 4) + *s - 'a' + 10;
else
*++a = 0;
} while (*s++ != '\0');
}
int solve(const char *s)
{
unsigned char a[NROWS];
int row, col;
int i, r, v;
str2a(s, a);
r = 0;
for (i = 0; i < NCOLS; i++) {
col = i;
for (row = 0; row < NROWS; row++) {
v = 0;
if (col < NCOLS - 1)
v |= ((a[row] >> col) & 1) << 1;
if (col > 0)
v |= (a[row] >> (col - 1)) & 1;
if (v == 1) {
while (col > 0 && ((a[row] >> (col - 1)) & 1))
col--;
} else if (v == 2) {
while (col < NCOLS && ((a[row] >> col) & 1))
col++;
}
}
r += pow(10, col) * (NCOLS - i - 1);
}
return r;
}
void test(const char *in, const char *out)
{
int r, e;
r = solve(in);
e = atoi(out);
printf("%s %09d(%09d) %s\n", in, e, r, r == e ? "ok" : "ng");
}
int main(void)
{
...snip...
return 0;
}