#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 #include "input.h" // #include "hint.h" // Skip over all non numeric characters // Return index of first numeric character found int find_int(const char *line) { int i = 0; for(; *line; ++line) { if(isdigit(*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; } // Search around an int for "components" // x x x x x x x // x [start n n n end] x <-- y // x x x x x x x // x is searched area // [start n end] is where the "part number" is // Return 1 if found int search_component(int y, int start, int end) { int left = start - 1; int right = end + 1; int top = y - 1; int bottom = y + 1; // Spot check the immediate left and right characters if(left >= 0 && input[y][left] != '.') return 1; if(right < input_width && input[y][right] != '.') return 1; // Check top row // We can clamp left and right now if(left < 0) left = 0; if(right >= input_width) right = input_width - 1; // Check top row if it is valid if(top > 0) { for(int i = left; i <= right; i++) if(input[top][i] != '.') return 1; } // Check bottom row if it is valid if(bottom < input_height) { for(int i = left; i <= right; i++) if(input[bottom][i] != '.') return 1; } return 0; } static int __init aoc_start(void) { printk(KERN_INFO "aoc_start\n"); int part_number_count = 0; for(int y = 0; y < input_height; y++) { const char *line = input[y]; int head = 0; while(1) { // Find a number printk("line[head] %s\n", &line[head]); int skipped = find_int(&line[head]); printk("skipped %d\n", skipped); if(skipped == -1) break; head += skipped; // Save start index so we can pass it to search later int start = head; // Read the int int number = 0; printk("line[start] %s\n", &line[head]); int number_num_chars = get_int(&line[head], &number); if(number_num_chars < 0) { printk("Bad shit happened\n"); return -1; } head += number_num_chars; printk("number %d\n", number); printk("n_number %d\n", number_num_chars); printk("context:\n"); if(y-1 > 0) printk("%s\n", input[y-1]); printk("%s\n", input[y]); if(y+1 < input_height) printk("%s\n", input[y+1]); int valid = search_component(y, start, head - 1); printk("valid %d\n", valid); if(valid) part_number_count += number; } printk("\n"); } printk("Part number count: %d\n", part_number_count); 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