Skip to content

Commit

Permalink
day 19: constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeladler committed Dec 26, 2023
1 parent 301ea6b commit e1dcd8e
Showing 1 changed file with 41 additions and 18 deletions.
59 changes: 41 additions & 18 deletions src/day19/solve.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,28 +111,54 @@ static inline void interval_negate_rule(interval_t *interval, rule_t *rule) {
}
}

static inline constraint_t constraint_apply_rule(constraint_t constraint, rule_t *r) {
static inline constraint_t constraint_apply_rule(constraint_t constraint, rule_t *rule) {
constraint_t result = constraint;
switch (r->variable) {
case 'x': interval_apply_rule(&result.x, r); break;
case 'm': interval_apply_rule(&result.m, r); break;
case 'a': interval_apply_rule(&result.a, r); break;
case 's': interval_apply_rule(&result.s, r); break;
switch (rule->variable) {
case 'x': interval_apply_rule(&result.x, rule); break;
case 'm': interval_apply_rule(&result.m, rule); break;
case 'a': interval_apply_rule(&result.a, rule); break;
case 's': interval_apply_rule(&result.s, rule); break;
}
return result;
}

static inline constraint_t constraint_negate_rule(constraint_t constraint, rule_t *r) {
static inline constraint_t constraint_negate_rule(constraint_t constraint, rule_t *rule) {
constraint_t result = constraint;
switch (r->variable) {
case 'x': interval_negate_rule(&result.x, r); break;
case 'm': interval_negate_rule(&result.m, r); break;
case 'a': interval_negate_rule(&result.a, r); break;
case 's': interval_negate_rule(&result.s, r); break;
switch (rule->variable) {
case 'x': interval_negate_rule(&result.x, rule); break;
case 'm': interval_negate_rule(&result.m, rule); break;
case 'a': interval_negate_rule(&result.a, rule); break;
case 's': interval_negate_rule(&result.s, rule); break;
}
return result;
}

static inline void process_path(int path[], int path_idx, ust_workflow_t *workflows, CharSlice99 *id_to_name,
constraint_t c) {
log_debug(">> found new path to destination:");
CharSlice99 from = id_to_name[path[0]];
for (int i = 1; i < path_idx; i++) {
log_debug("constraints: %d <= x <= %d, %d <= m <= %d, %d <= a <= %d, %d <= s <= %d", c.x.lower, c.x.upper,
c.m.lower, c.m.upper, c.a.lower, c.a.upper, c.s.lower, c.s.upper);
CharSlice99 to = id_to_name[path[i]];
log_debug("%.*s -> %.*s", from.len, from.ptr, to.len, to.ptr);
workflow_t *wf = &ust_workflow_t_find(workflows, (workflow_t){.name = to})->key;
for (int i = 0; i < wf->rule_count; i++) {
rule_t *rule = &wf->rule[i];
if (CharSlice99_primitive_eq(rule->destination, from)) {
c = constraint_apply_rule(c, rule);
// TODO: there might also be some other rule which matches
break;
} else {
c = constraint_negate_rule(c, rule);
}
}
from = to;
}
log_debug("constraints: %d <= x <= %d, %d <= m <= %d, %d <= a <= %d, %d <= s <= %d", c.x.lower, c.x.upper,
c.m.lower, c.m.upper, c.a.lower, c.a.upper, c.s.lower, c.s.upper);
}

static void find_all_paths(graph_t *graph, int current, int destination, bool visited[], int path[], int *path_idx,
ust_workflow_t *workflows, CharSlice99 *id_to_name) {
// mark the current node and store it in path[]
Expand All @@ -141,12 +167,9 @@ static void find_all_paths(graph_t *graph, int current, int destination, bool vi
*path_idx = *path_idx + 1;

if (current == destination) {
log_debug(">> found new path to destination:");
for (int i = 0; i < *path_idx; i++) {
int id = path[i];
CharSlice99 name = id_to_name[id];
log_debug("%.*s", name.len, name.ptr);
}
interval_t initial = {.lower = 0, .upper = 4000};
constraint_t constraint = {.x = initial, .m = initial, .a = initial, .s = initial};
process_path(path, *path_idx, workflows, id_to_name, constraint);
} else {
adj_list_t *lst = &graph->adj[current];
for (int i = 0; i < lst->neighbor_count; i++) {
Expand Down

0 comments on commit e1dcd8e

Please sign in to comment.