#include "aoc.h" #include namespace aoc2020 { static int numbers[1000] = {0}; static int get_number(const char* p) { int d{0}; while (*p >= '0' && *p <= '9') { d = d * 10 + *p - '0'; p++; } return d; } bool check25(int i, int* weak) { std::set si; for (int x = i - 25; x < i; x++) { si.insert(numbers[x]); } for (int x = i - 25; x < i; x++) { int y = numbers[i] - numbers[x]; if (si.find(y) != si.end()) { return true; } } *weak = numbers[i]; return false; } bool check_contiguous(int i, int* end, int target) { if (target == 0) { *end = i; return true; } if (target < 0) { return false; } return check_contiguous(i + 1, end, target - numbers[i]); } static void minmax(int x, int y, int* min, int* max) { for(int i = x; i < y; i++) { if (*min > numbers[i]) { *min = numbers[i]; } if (*max < numbers[i]) { *max = numbers[i]; } } } std::pair day9(line_view file) { int i{0}; per_line(file, [&i](line_view lv){ numbers[i++] = get_number(lv.line); return true; }); int weak{0}; int pos{0}; for (int i = 25; i < 1000; i++) { if (!check25(i, &weak)) { pos = i; break; } } int e{0}; int min{INT32_MAX}, max{INT32_MIN}; for (int i = 0; i < pos; i++) { if (check_contiguous(i, &e, weak)) { minmax(i, e, &min, &max); } } return {weak, min + max}; } }