thomas_2023/day_3/aoc2023p1.c
2023-12-04 21:54:45 -05:00

159 lines
3.8 KiB
C

#define BREAK_MY_SHIT
#ifdef BREAK_MY_SHIT
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/ctype.h>
MODULE_LICENSE("Proprietary and Confidential; All Rights Reserved");
MODULE_AUTHOR("Urmomlel");
MODULE_DESCRIPTION("Vanguard Anticheat");
MODULE_VERSION("-6.9");
#else
#include <stdio.h>
#include <ctype.h>
#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