2020/19 (C): cleanup code
This commit is contained in:
@@ -39,36 +39,66 @@ static struct mesg {
|
|||||||
} mesg[MAX_MSG];
|
} mesg[MAX_MSG];
|
||||||
static int nrules, nmesg;
|
static int nrules, nmesg;
|
||||||
|
|
||||||
static void printall()
|
|
||||||
|
static int match(struct mesg *msg, int *pos, int rule)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < nrules; ++i) {
|
struct rule *r = rules + rule;
|
||||||
printf("rule %3d : ", i);
|
int found = 0, postmp, recurse = 0;
|
||||||
if (rules[i].type == CHR) {
|
|
||||||
printf("[%c]\n", rules[i].str);
|
if (r->type == CHR)
|
||||||
continue;
|
return rules[rule].str == msg->str[(*pos)++];
|
||||||
|
for (int side = 0; side < 2; ++side, recurse = 0, found = 0) {
|
||||||
|
if (r->sub.rule[side][0] == -1)
|
||||||
|
break;
|
||||||
|
postmp = *pos;
|
||||||
|
found = 1;
|
||||||
|
for (int sub = 0; sub < 3 && r->sub.rule[side][sub] >= 0; ++sub) {
|
||||||
|
if (*pos == msg->len)
|
||||||
|
return recurse;
|
||||||
|
recurse = r->sub.rule[side][sub] == rule;
|
||||||
|
if (!match(msg, pos, r->sub.rule[side][sub])) {
|
||||||
|
found = 0;
|
||||||
|
*pos = postmp; /* roll back */
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int j = 0; j < 3 && rules[i].sub.rule[0][j] != -1; ++j)
|
if (found)
|
||||||
printf("%d ", rules[i].sub.rule[0][j]);
|
break;
|
||||||
for (int j = 0; j < 3 && rules[i].sub.rule[1][j] != -1; ++j)
|
|
||||||
printf("%s%d ", j? "": "| ", rules[i].sub.rule[1][j]);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
for (int i = 0; i < nmesg; ++i) {
|
|
||||||
printf("%3d: len=%d %s\n", i, mesg[i].len, mesg[i].str);
|
|
||||||
}
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long part1()
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
for (int msg = 0, pos = 0; msg < nmesg; ++msg, pos = 0)
|
||||||
|
if (match(mesg + msg, &pos, 0))
|
||||||
|
ret += pos == mesg[msg].len;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long part2()
|
||||||
|
{
|
||||||
|
static const struct subrule new[2] = {
|
||||||
|
{{{42, -1, -1}, {42, 8, -1}}},
|
||||||
|
{{{42, 31, -1}, {42, 11, 31}}}
|
||||||
|
};
|
||||||
|
rules[8].sub = new[0];
|
||||||
|
rules[11].sub = new[1];
|
||||||
|
|
||||||
|
return part1();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* parse - parse input.
|
|
||||||
*/
|
|
||||||
static void parse()
|
static void parse()
|
||||||
{
|
{
|
||||||
size_t alloc;
|
size_t alloc;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
char *buf = NULL, *tok;
|
char *buf = NULL, *tok;
|
||||||
int rule;
|
int rule;
|
||||||
|
|
||||||
while ((len = getline(&buf, &alloc, stdin)) > 0) {
|
while ((len = getline(&buf, &alloc, stdin)) > 0) {
|
||||||
int or = 0, sub = 0;
|
int set = 0, sub = 0;
|
||||||
|
|
||||||
buf[--len] = 0;
|
buf[--len] = 0;
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
@@ -87,104 +117,23 @@ static void parse()
|
|||||||
case 'b':
|
case 'b':
|
||||||
rules[rule].type = CHR;
|
rules[rule].type = CHR;
|
||||||
rules[rule].str = *tok;
|
rules[rule].str = *tok;
|
||||||
goto nextline;
|
break;
|
||||||
case '|': /* second ruleset */
|
case '|': /* second ruleset */
|
||||||
or++;
|
set++;
|
||||||
sub = 0;
|
sub = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rules[rule].type = SUB;
|
rules[rule].type = SUB;
|
||||||
rules[rule].sub.rule[or][sub] = atoi(tok);
|
rules[rule].sub.rule[set][sub] = atoi(tok);
|
||||||
sub++;
|
sub++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nextline: ;
|
|
||||||
}
|
}
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match(struct mesg *msg, int *pos, int rule, int depth)
|
|
||||||
{
|
|
||||||
struct rule *r = rules+rule;
|
|
||||||
int found = 0, postmp, recurse = 0;
|
|
||||||
char *space = " ";
|
|
||||||
log_f(3, "%.*sstr=%s pos=%d rule=%d\n", depth * 2, space, msg->str,
|
|
||||||
*pos, rule);
|
|
||||||
if (r->type == CHR)
|
|
||||||
return rules[rule].str == msg->str[(*pos)++];
|
|
||||||
for (int side = 0; side < 2; ++side) {
|
|
||||||
if (r->sub.rule[side][0] == -1) {
|
|
||||||
found = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
postmp = *pos;
|
|
||||||
recurse = 0;
|
|
||||||
found = 1;
|
|
||||||
for (int sub = 0; sub < 3 && r->sub.rule[side][sub] >= 0; ++sub) {
|
|
||||||
if (*pos == msg->len)
|
|
||||||
return recurse;
|
|
||||||
if (r->sub.rule[side][sub] == rule) {
|
|
||||||
log(3, "recursing %d rule\n", rule);
|
|
||||||
recurse = 1;
|
|
||||||
}
|
|
||||||
if (!match(msg, pos, r->sub.rule[side][sub], depth + 1)) {
|
|
||||||
found = 0;
|
|
||||||
*pos = postmp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* check for exact length */
|
|
||||||
if (depth == 0 && msg->str[*pos]) {
|
|
||||||
log_f(3, "pos=%d len=%d chars remaining !\n", *pos, msg->len);
|
|
||||||
found = 0;
|
|
||||||
}
|
|
||||||
log_f(3, "%.*sstr=%s pos=%d rule=%d ret=%s\n",
|
|
||||||
depth * 2, space, msg->str+*pos, *pos, rule, found? "ok": "NOK");
|
|
||||||
return found; /* not reached */
|
|
||||||
}
|
|
||||||
|
|
||||||
static long part1()
|
|
||||||
{
|
|
||||||
int ok = 0, pos;
|
|
||||||
for (int msg = 0; msg < nmesg; ++msg) {
|
|
||||||
pos = 0;
|
|
||||||
if (match(mesg + msg, &pos, 0, 0)) {
|
|
||||||
log(2, "len=%d pos=%d %s: ok\n", mesg[msg].len, pos, mesg[msg].str);
|
|
||||||
ok++;
|
|
||||||
} else {
|
|
||||||
log(2, "len=%d pos=%d %s: NOK\n", mesg[msg].len, pos, mesg[msg].str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static long part2()
|
|
||||||
{
|
|
||||||
static const struct subrule new[2] = {
|
|
||||||
{{{42, -1, -1}, {42, 8, -1}}},
|
|
||||||
{{{42, 31, -1}, {42, 11, 31}}}
|
|
||||||
};
|
|
||||||
rules[8].sub = new[0];
|
|
||||||
rules[11].sub = new[1];
|
|
||||||
|
|
||||||
int ok = 0, pos;
|
|
||||||
for (int msg = 0; msg < nmesg; ++msg) {
|
|
||||||
pos = 0;
|
|
||||||
if (match(mesg + msg, &pos, 0, 0)) {
|
|
||||||
log(2, "len=%d pos=%d %s: ok\n", mesg[msg].len, pos, mesg[msg].str);
|
|
||||||
ok++;
|
|
||||||
} else {
|
|
||||||
log(2, "len=%d pos=%d %s: NOK\n", mesg[msg].len, pos, mesg[msg].str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int usage(char *prg)
|
static int usage(char *prg)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s [-d debug_level] [-p part]\n", prg);
|
fprintf(stderr, "Usage: %s [-d debug_level] [-p part]\n", prg);
|
||||||
@@ -212,6 +161,5 @@ int main(ac, av)
|
|||||||
|
|
||||||
parse();
|
parse();
|
||||||
printf("%s : res=%ld\n", *av, part == 1? part1(): part2());
|
printf("%s : res=%ld\n", *av, part == 1? part1(): part2());
|
||||||
//printall();
|
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user