#include #include #include #include #include "../../lib/aoc.h" typedef struct Rule { int first; int last; } Rule; typedef struct Rules { Rule rule[1200]; int length; } Rules; typedef struct Update { int page[100]; int length; } Update; bool valid_rule(Rule *rule, Update *update) { int first = -1, last = -1; for (int i = 0; i < update->length; i++) { if (rule->first == update->page[i]) first = i; if (rule->last == update->page[i]) last = i; if (first != -1 && last != -1) return first < last; } return true; } bool valid_update(Rules *rules, Update *update) { for (int i = 0; i < rules->length; i++) { if (!valid_rule(&(rules->rule[i]), update)) return false; } return true; } int middle_page_number(Update *update) { return update->page[update->length / 2]; } void reorder_update(Rules *rules, Update *update) { bool dirty = true; while (dirty) { dirty = false; for (int i = 0; i < update->length - 1; i++) { for (int j = 0; j < rules->length; j++) { Rule rule = rules->rule[j]; if (update->page[i] == rule.last && update->page[i + 1] == rule.first) { dirty = true; update->page[i] = rule.first; update->page[i + 1] = rule.last; break; } } } } } int main() { char *line; int sum = 0; int reorder_sum = 0; Rules rules; int first, last; Update update; char *update_element; bool scanning_rules = true; while ((line = aoc_read_line()) != NULL) { if (scanning_rules) { if (strlen(line) == 0) scanning_rules = false; else { sscanf(line, "%d|%d", &first, &last); rules.rule[rules.length].first = first; rules.rule[rules.length].last = last; rules.length++; } } else { update.length = 0; update_element = strtok(line, ","); while(update_element != NULL) { update.page[update.length++] = atoi(update_element); update_element = strtok(NULL, ","); } if (valid_update(&rules, &update)) sum += middle_page_number(&update); else { reorder_update(&rules, &update); reorder_sum += middle_page_number(&update); } } } printf("Part 1: %d\n", sum); printf("Part 2: %d\n", reorder_sum); aoc_free(); return 0; }