#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct cell {
int c, d;
};
size_t width(const char *s) {
const char *p;
for (p = s; *p && *p == *s; p++) {}
return p - s;
}
size_t nop_width(const char *s) {
const char *p;
for (p = s; *p; p++) {
if (*p == '>' || *p == '<' || *p == '+' || *p == '-') break;
if (*p == '.' || *p == ',' || *p == '[' || *p == ']') break;
}
return p - s;
}
struct cell *find_square_bracket_right(struct cell *p) {
int depth = 0;
for (; p->c; p += p->d) {
if (p->c == '[') depth++;
else if (p->c == ']') {
if (depth == 0) break;
else depth--;
}
}
return p;
}
struct cell *init_square_brackets(struct cell *b) {
struct cell *p, *q;
for (p = b; p->c;) {
switch (p->c) {
case '[':
q = find_square_bracket_right(p + 1);
p->d = q - p + 1;
q->d = - (q - p);
case ']': p++; break;
default: p += p->d; break;
}
}
return b;
}
struct cell *scan(const char *s) {
size_t size
= strlen(s
), i
, j
, w
; struct cell
*cells
= malloc(sizeof (struct cell
) * (size
+ 1)); for (i = 0; i < size; i += cells[i].d) {
switch (s[i]) {
case '>': case '<': case '+': case '-':
for (w = width(s + i), j = 0; j < w; j++) {
cells[i + j].c = s[i + j];
cells[i + j].d = w - j;
}
break;
case '.': case ',': case '[': case ']':
cells[i].c = s[i];
cells[i].d = 1;
break;
default:
for (w = nop_width(s + i), j = 0; j < w; j++) {
cells[i + j].c = s[i + j];
cells[i + j].d = w - j;
}
break;
}
}
cells[i].c = '\0';
cells[i].d = 0;
return init_square_brackets(cells);
}
struct range {
char *begin, *end;
};
struct cell *f(struct cell *ip0, char *dp, struct range *range) {
register struct cell *ip;
for (ip = ip0; ip->c; ip += ip->c == '[' && *dp ? 1 : ip->d) {
switch (ip->c) {
case '>': if (range
->end
<= (dp
+= ip
->d
)) exit(1); break; case '<': if ((dp
-= ip
->d
) < range
->begin
) exit(1); break; case '+': *dp += ip->d; break;
case '-': *dp -= ip->d; break;
default: break;
}
}
return ip0;
}
void g(const char *s) {
char data[30000] = {0};
struct range range = {data, data + sizeof data};
free(f
(scan
(s
), data
, &range
)); }
int main() {
g("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.");
g("++++++++[>++++++++<-]>++.<++++++[>++++++++<-]>.<----[>++++<-]>-.++++++++.+++++.--------.+++++++++++++++.<----[>++++<-]>--.++++++++.");
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgpzdHJ1Y3QgY2VsbCB7CiAgaW50IGMsIGQ7Cn07CnNpemVfdCB3aWR0aChjb25zdCBjaGFyICpzKSB7CiAgY29uc3QgY2hhciAqcDsKICBmb3IgKHAgPSBzOyAqcCAmJiAqcCA9PSAqczsgcCsrKSB7fQogIHJldHVybiBwIC0gczsKfQpzaXplX3Qgbm9wX3dpZHRoKGNvbnN0IGNoYXIgKnMpIHsKICBjb25zdCBjaGFyICpwOwogIGZvciAocCA9IHM7ICpwOyBwKyspIHsKICAgIGlmICgqcCA9PSAnPicgfHwgKnAgPT0gJzwnIHx8ICpwID09ICcrJyB8fCAqcCA9PSAnLScpIGJyZWFrOwogICAgaWYgKCpwID09ICcuJyB8fCAqcCA9PSAnLCcgfHwgKnAgPT0gJ1snIHx8ICpwID09ICddJykgYnJlYWs7CiAgfQogIHJldHVybiBwIC0gczsKfQpzdHJ1Y3QgY2VsbCAqZmluZF9zcXVhcmVfYnJhY2tldF9yaWdodChzdHJ1Y3QgY2VsbCAqcCkgewogIGludCBkZXB0aCA9IDA7CiAgZm9yICg7IHAtPmM7IHAgKz0gcC0+ZCkgewogICAgaWYgKHAtPmMgPT0gJ1snKSBkZXB0aCsrOwogICAgZWxzZSBpZiAocC0+YyA9PSAnXScpIHsKICAgICAgaWYgKGRlcHRoID09IDApIGJyZWFrOwogICAgICBlbHNlIGRlcHRoLS07CiAgICB9CiAgfQogIHJldHVybiBwOwp9CnN0cnVjdCBjZWxsICppbml0X3NxdWFyZV9icmFja2V0cyhzdHJ1Y3QgY2VsbCAqYikgewogIHN0cnVjdCBjZWxsICpwLCAqcTsKICBmb3IgKHAgPSBiOyBwLT5jOykgewogICAgc3dpdGNoIChwLT5jKSB7CiAgICBjYXNlICdbJzoKICAgICAgcSA9IGZpbmRfc3F1YXJlX2JyYWNrZXRfcmlnaHQocCArIDEpOwogICAgICBwLT5kID0gcSAtIHAgKyAxOwogICAgICBxLT5kID0gLSAocSAtIHApOwogICAgY2FzZSAnXSc6IHArKzsgYnJlYWs7CiAgICBkZWZhdWx0OiBwICs9IHAtPmQ7IGJyZWFrOwogICAgfQogIH0KICByZXR1cm4gYjsKfQpzdHJ1Y3QgY2VsbCAqc2Nhbihjb25zdCBjaGFyICpzKSB7CiAgc2l6ZV90IHNpemUgPSBzdHJsZW4ocyksIGksIGosIHc7CiAgc3RydWN0IGNlbGwgKmNlbGxzID0gbWFsbG9jKHNpemVvZiAoc3RydWN0IGNlbGwpICogKHNpemUgKyAxKSk7CiAgZm9yIChpID0gMDsgaSA8IHNpemU7IGkgKz0gY2VsbHNbaV0uZCkgewogICAgc3dpdGNoIChzW2ldKSB7CiAgICBjYXNlICc+JzogY2FzZSAnPCc6IGNhc2UgJysnOiBjYXNlICctJzoKICAgICAgZm9yICh3ID0gd2lkdGgocyArIGkpLCBqID0gMDsgaiA8IHc7IGorKykgewogICAgICAgIGNlbGxzW2kgKyBqXS5jID0gc1tpICsgal07CiAgICAgICAgY2VsbHNbaSArIGpdLmQgPSB3IC0gajsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgJy4nOiBjYXNlICcsJzogY2FzZSAnWyc6IGNhc2UgJ10nOgogICAgICBjZWxsc1tpXS5jID0gc1tpXTsKICAgICAgY2VsbHNbaV0uZCA9IDE7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgZm9yICh3ID0gbm9wX3dpZHRoKHMgKyBpKSwgaiA9IDA7IGogPCB3OyBqKyspIHsKICAgICAgICBjZWxsc1tpICsgal0uYyA9IHNbaSArIGpdOwogICAgICAgIGNlbGxzW2kgKyBqXS5kID0gdyAtIGo7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICB9CiAgfQogIGNlbGxzW2ldLmMgPSAnXDAnOwogIGNlbGxzW2ldLmQgPSAwOwogIHJldHVybiBpbml0X3NxdWFyZV9icmFja2V0cyhjZWxscyk7Cn0Kc3RydWN0IHJhbmdlIHsKICBjaGFyICpiZWdpbiwgKmVuZDsKfTsKc3RydWN0IGNlbGwgKmYoc3RydWN0IGNlbGwgKmlwMCwgY2hhciAqZHAsIHN0cnVjdCByYW5nZSAqcmFuZ2UpIHsKICByZWdpc3RlciBzdHJ1Y3QgY2VsbCAqaXA7CiAgZm9yIChpcCA9IGlwMDsgaXAtPmM7IGlwICs9IGlwLT5jID09ICdbJyAmJiAqZHAgPyAxIDogaXAtPmQpIHsKICAgIHN3aXRjaCAoaXAtPmMpIHsKICAgIGNhc2UgJz4nOiBpZiAocmFuZ2UtPmVuZCA8PSAoZHAgKz0gaXAtPmQpKSBleGl0KDEpOyBicmVhazsKICAgIGNhc2UgJzwnOiBpZiAoKGRwIC09IGlwLT5kKSA8IHJhbmdlLT5iZWdpbikgZXhpdCgxKTsgYnJlYWs7CiAgICBjYXNlICcrJzogKmRwICs9IGlwLT5kOyBicmVhazsKICAgIGNhc2UgJy0nOiAqZHAgLT0gaXAtPmQ7IGJyZWFrOwogICAgY2FzZSAnLic6IHB1dGNoYXIoKmRwKTsgYnJlYWs7CiAgICBjYXNlICcsJzogKmRwID0gZ2V0Y2hhcigpOyBicmVhazsKICAgIGRlZmF1bHQ6IGJyZWFrOwogICAgfQogIH0KICByZXR1cm4gaXAwOwp9CnZvaWQgZyhjb25zdCBjaGFyICpzKSB7CiAgY2hhciBkYXRhWzMwMDAwXSA9IHswfTsKICBzdHJ1Y3QgcmFuZ2UgcmFuZ2UgPSB7ZGF0YSwgZGF0YSArIHNpemVvZiBkYXRhfTsKICBmcmVlKGYoc2NhbihzKSwgZGF0YSwgJnJhbmdlKSk7Cn0KaW50IG1haW4oKSB7CiAgZygiKysrKysrKytbPisrKytbPisrPisrKz4rKys+Kzw8PDwtXT4rPis+LT4+K1s8XTwtXT4+Lj4tLS0uKysrKysrKy4uKysrLj4+LjwtLjwuKysrLi0tLS0tLS4tLS0tLS0tLS4+PisuPisrLiIpOwogIGcoIisrKysrKysrWz4rKysrKysrKzwtXT4rKy48KysrKysrWz4rKysrKysrKzwtXT4uPC0tLS1bPisrKys8LV0+LS4rKysrKysrKy4rKysrKy4tLS0tLS0tLS4rKysrKysrKysrKysrKysuPC0tLS1bPisrKys8LV0+LS0uKysrKysrKysuIik7CiAgcmV0dXJuIDA7Cn0K