136 lines
4.3 KiB
C
136 lines
4.3 KiB
C
|
#include <linux/module.h>
|
||
|
#include <linux/init.h>
|
||
|
#include <linux/fs.h>
|
||
|
|
||
|
#define MODULE_NAME "aoc2023d3p1"
|
||
|
MODULE_AUTHOR("logan2611");
|
||
|
MODULE_LICENSE("Dual MIT/GPL");
|
||
|
MODULE_DESCRIPTION("Advent of Code 2023 Day 3 Part 1 (The Linux Kernel Module)");
|
||
|
MODULE_VERSION("0.1");
|
||
|
|
||
|
const int length = 140; // Number of lines
|
||
|
//const int length = 10; // Number of lines
|
||
|
const int width = length + 1; // Width of lines (including newline, carriage return or null terminator)
|
||
|
|
||
|
// Parameter that specifies the input file
|
||
|
static char *path = "/tmp/input";
|
||
|
module_param(path, charp, S_IRUGO);
|
||
|
MODULE_PARM_DESC(path, "The path to the data input.");
|
||
|
|
||
|
static ssize_t read_input(struct file *file, loff_t pos, size_t n, char *buffer) {
|
||
|
ssize_t bytes_read;
|
||
|
|
||
|
bytes_read = kernel_read(file, buffer, n, &pos);
|
||
|
if (bytes_read < 0) {
|
||
|
pr_err("%s: Error reading file: %zd\n", MODULE_NAME, bytes_read);
|
||
|
}
|
||
|
|
||
|
return bytes_read;
|
||
|
}
|
||
|
|
||
|
static int find_numbers(char *top, char *middle, char *bottom) {
|
||
|
int beginning = -1;
|
||
|
int end = -1;
|
||
|
int sum = 0;
|
||
|
|
||
|
for(int i = 0; i < width; i++) {
|
||
|
if(i < end+1) continue;
|
||
|
if(middle[i] >= 48 && middle[i] <= 57) {
|
||
|
beginning = i-1;
|
||
|
end = i-1;
|
||
|
//pr_info("%s: %d\n", MODULE_NAME, i);
|
||
|
|
||
|
if(beginning < 0) {
|
||
|
beginning = 0;
|
||
|
}
|
||
|
|
||
|
for(int j = 0; j <= 4; j++) {
|
||
|
if(middle[i+j] < 48 || middle[i+j] > 57) {
|
||
|
end = i+j;
|
||
|
|
||
|
char numstr[8] = {0};
|
||
|
memcpy(numstr, middle + i, j);
|
||
|
|
||
|
int ret = 0;
|
||
|
int err = 0;
|
||
|
err = kstrtoint(numstr, 10, &ret);
|
||
|
if (ret < 0) {
|
||
|
pr_err("%s: Failed to convert string to number: \"%d\"\n", MODULE_NAME, err);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//pr_info("%s: %d %d %d\n", MODULE_NAME, ret, i, end);
|
||
|
for(int k = 0; k <= end - beginning; k++) {
|
||
|
//pr_info("%s: Checking position %d\n", MODULE_NAME, beginning+k);
|
||
|
|
||
|
char topcheck = top[beginning+k];
|
||
|
char middlecheck = middle[beginning+k];
|
||
|
char bottomcheck = bottom[beginning+k];
|
||
|
|
||
|
if( (((topcheck >= 33 && topcheck <= 47) || (topcheck >= 58 && topcheck <= 64)) && topcheck != '.') ||
|
||
|
(((middlecheck >= 33 && middlecheck <= 47) || (middlecheck >= 58 && middlecheck <= 64)) && middlecheck != '.') ||
|
||
|
(((bottomcheck >= 33 && bottomcheck <= 47) || (bottomcheck >= 58 && bottomcheck <= 64)) && bottomcheck != '.'))
|
||
|
{
|
||
|
pr_info("%s: ADJACENT %d\n", MODULE_NAME, ret);
|
||
|
sum += ret;
|
||
|
break;
|
||
|
} else {
|
||
|
//pr_info("%s: %d, %d and %d are not symbols\n", MODULE_NAME, topcheck, middlecheck, bottomcheck);
|
||
|
};
|
||
|
} // End Check for symbols loop
|
||
|
break;
|
||
|
} // End Check for numbers loop
|
||
|
} // End find tail of number
|
||
|
} // End If number is found
|
||
|
} // End Find numbers loop
|
||
|
return sum;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
static int __init test_init(void) {
|
||
|
struct file *f;
|
||
|
|
||
|
pr_info("%s: Module loaded\n", MODULE_NAME);
|
||
|
|
||
|
f = filp_open(path, O_RDONLY, 0);
|
||
|
if(IS_ERR(f)) {
|
||
|
pr_err("%s: Failed to open %s\n", MODULE_NAME, path);
|
||
|
return PTR_ERR(f);
|
||
|
}
|
||
|
|
||
|
char buf[3][width+1];
|
||
|
memset(buf, 0, sizeof(buf));
|
||
|
|
||
|
read_input(f, 0, width, buf[2]);
|
||
|
|
||
|
int sum = 0;
|
||
|
|
||
|
for(int line = 1; line <= length; line++) {
|
||
|
pr_info("%s: %s", MODULE_NAME, buf[2]);
|
||
|
|
||
|
memcpy(buf[0], buf[1], sizeof(buf[0]));
|
||
|
memcpy(buf[1], buf[2], sizeof(buf[1]));
|
||
|
|
||
|
if(length - line > 0) {
|
||
|
read_input(f, line*width, length, buf[2]);
|
||
|
} else {
|
||
|
memset(buf[2], 0, sizeof(buf[2]));
|
||
|
}
|
||
|
|
||
|
sum += find_numbers(buf[0], buf[1], buf[2]);
|
||
|
}
|
||
|
|
||
|
filp_close(f, NULL);
|
||
|
|
||
|
pr_info("%s: %d\n", MODULE_NAME, sum);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void __exit test_exit(void) {
|
||
|
pr_info("%s: Module unloaded\n", MODULE_NAME);
|
||
|
}
|
||
|
|
||
|
module_init(test_init);
|
||
|
module_exit(test_exit);
|