#define BREAK_MY_SHIT #ifdef BREAK_MY_SHIT #include /* Needed by all modules */ #include /* Needed for KERN_INFO */ #include /* Needed for the macros */ #include MODULE_LICENSE("Proprietary and Confidential; All Rights Reserved"); MODULE_AUTHOR("Urmomlel"); MODULE_DESCRIPTION("Vanguard Anticheat"); MODULE_VERSION("-6.9"); #else #include #include #define __init #define __exit #define KERN_INFO #define printk printf #endif #define printd printk #include "input.h" // #include "hint.h" // Return index of first gear found int find_gear(const char *line) { int i = 0; for(; *line; ++line) { if(*line == '*') return i; i++; } return -1; } // Convert string to int, return digits consumed int get_int(const char *line, int *num_out) { int i = 0; *num_out = 0; // Handle the edge case that will never happen (tm) if(!isdigit(*line)) return -1; for(; *line; ++line,++i) { if(!isdigit(*line)) break; *num_out *= 10; *num_out += *line - 0x30; } return i; } int find_number_start(const char *line, int start) { printd("find_number_start\n"); for(; start >= 0; start--) { printd("%c", line[start]); if(!isdigit(line[start])) return start + 1; } printd("start %d\n", start); // Fucking edge cases if(start == -1) return 0; return -1; } // Check for a digit, now with bounds checks int has_digit(int y, int x) { if(x < 0 || x >= input_width) return 0; if(y < 0 || y >= input_height) return 0; return isdigit(input[y][x]); } // Search around a gear for numbers // xxxxx // xxxgx <-- y // xxxxx // x is searched area // g is where the "gear" is // Return 1 if found int search_numbers(int y, int x) { // *Technically* 6 are possible int numbers[6] = {0}; int num_results = 0; // Define some vars for my sanity int top = y - 1; int bot = y + 1; int left = x - 1; int right = x + 1; // Check direct top and bottom to avoid further checks on those rows int top_has = has_digit(top, x); int bot_has = has_digit(bot, x); if(top_has) { printd("top %d\n", x); int real_start = find_number_start(input[top], x); get_int(&input[top][real_start], &numbers[num_results++]); } else { if(has_digit(top, left)) { printd("top left %d\n", left); int real_start = find_number_start(input[top], left); printd("top real %d\n", real_start); printd("top real %s\n", &input[top][real_start]); get_int(&input[top][real_start], &numbers[num_results++]); } if(has_digit(top, right)) { printd("top right %d\n", right); int real_start = find_number_start(input[top], right); get_int(&input[top][real_start], &numbers[num_results++]); } } if(bot_has) { int real_start = find_number_start(input[bot], x); printd("bot %d\n", x); printd("bot real %d\n", real_start); printd("bot real %s\n", &input[bot][real_start]); get_int(&input[bot][real_start], &numbers[num_results++]); } else { if(has_digit(bot, left)) { printd("bot left %d\n", left); int real_start = find_number_start(input[bot], left); get_int(&input[bot][real_start], &numbers[num_results++]); } if(has_digit(bot, right)) { printd("bot right %d\n", right); int real_start = find_number_start(input[bot], right); get_int(&input[bot][real_start], &numbers[num_results++]); } } // Check sides if(has_digit(y, left)) { int real_start = find_number_start(input[y], left); get_int(&input[y][real_start], &numbers[num_results++]); } if(has_digit(y, right)) { get_int(&input[y][right], &numbers[num_results++]); } printd("Found %d numbers\n", num_results); for(int i = 0; i < num_results; i++) { printd("%d: %d\n", i, numbers[i]); } if(num_results == 2) return numbers[0] * numbers[1]; return 0; } static int __init aoc_start(void) { printk(KERN_INFO "aoc_start\n"); int ratio_sum = 0; for(int y = 0; y < input_height; y++) { const char *line = input[y]; int head = 0; while(1) { // Find a number int skipped = find_gear(&line[head]); if(skipped == -1) break; head += skipped; // Save hear index so we can pass it to search later int gear = head; // Skip past gear head++; printk("asdlkasjdlkasd %d\n", y); printd("context:\n"); if(y-1 >= 0) printd("%s\n", input[y-1]); printd("%s\n", input[y]); if(y+1 < input_height) printd("%s\n", input[y+1]); int ratio = search_numbers(y, gear); printk("ratio %d\n", ratio); if(ratio > 0) ratio_sum += ratio; } printk("\n"); } printk("Sum of ratios: %d\n", ratio_sum); return 0; } static void __exit aoc_end(void) { printk(KERN_INFO "aoc_end\n"); } #ifdef BREAK_MY_SHIT module_init(aoc_start); module_exit(aoc_end); #else int main() { aoc_start(); aoc_end(); } #endif