From 99a2a4f996e3d2edc06c9f58e6ec9f42d4e4f251 Mon Sep 17 00:00:00 2001 From: yequari Date: Sun, 3 Dec 2023 08:34:59 -0700 Subject: [PATCH] days 1 and 2 --- .gitignore | 2 + day1/Makefile | 8 ++ day1/part1.c | 78 ++++++++++++++++++ day1/part2.c | 136 +++++++++++++++++++++++++++++++ day2/Makefile | 8 ++ day2/part1.c | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++ day2/part1.py | 63 +++++++++++++++ day2/part2.py | 62 +++++++++++++++ 8 files changed, 572 insertions(+) create mode 100644 .gitignore create mode 100644 day1/Makefile create mode 100644 day1/part1.c create mode 100644 day1/part2.c create mode 100644 day2/Makefile create mode 100644 day2/part1.c create mode 100644 day2/part1.py create mode 100644 day2/part2.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0902326 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bin +input diff --git a/day1/Makefile b/day1/Makefile new file mode 100644 index 0000000..93738bc --- /dev/null +++ b/day1/Makefile @@ -0,0 +1,8 @@ +part1: part1.c + gcc -Wall -g -o bin/part1 part1.c +part2: part2.c + gcc -Wall -g -o bin/part2 part2.c + +.PHONY: clean +clean: + rm part1 part2 diff --git a/day1/part1.c b/day1/part1.c new file mode 100644 index 0000000..37eb825 --- /dev/null +++ b/day1/part1.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include + +/* + * Each line of the input file contains a string with a mix of letters and digits + * Each line's "calibration value" is a single two digit number, made up of the first and last + * digit found in the string + * Print out the sum of all the calibration values. + */ + +char buffer[2048]; + +void read_line(char* linebuf, FILE* file) +{ + char* str = fgets(linebuf, 2048, file); + if (feof(file)) + { + return; + } + if (str == NULL) + { + fprintf(stderr, "Fgets error"); + linebuf[0] = '\0'; + } +} + +void extract_digits(char* str, char *first, char *last) +{ + char *p,*q,*r; + p = str; + while (*p != '\0' && !isdigit(*p)) + p++; // find first digit + *first = *last = *p; + q = p; + while (*q != '\0') // find digits until end of string + { + q++; + if (isdigit(*q)) + { + *last = *q; + } + } +} + +long convert_chars(char first, char last) +{ + char num[3] = { first, last, '\0' }; + return strtoul(num, NULL, 10); +} + +int main(int argc, char *argv[]) +{ + FILE* input = fopen("input", "r"); + if (input == NULL) + { + fprintf(stderr, "error opening file"); + return EXIT_FAILURE; + } + long sum = 0; + char first, last; + + while(true) + { + read_line(buffer, input); + if (feof(input)) + break; + extract_digits(buffer, &first, &last); + long value = convert_chars(first, last); + printf("%ld\t%s", value, buffer); + sum += value; + } + + printf("%ld", sum); + return EXIT_SUCCESS; +} diff --git a/day1/part2.c b/day1/part2.c new file mode 100644 index 0000000..721eea1 --- /dev/null +++ b/day1/part2.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include +#include + +/* + * Each line of the input file contains a string with a mix of letters and digits + * Each line's "calibration value" is a single two digit number, made up of the first and last + * digit found in the string + * Print out the sum of all the calibration values. + */ + +char buffer[2048]; + +void read_line(char* linebuf, FILE* file) +{ + char* str = fgets(linebuf, 2048, file); + if (feof(file)) + { + return; + } + if (str == NULL) + { + fprintf(stderr, "Fgets error"); + linebuf[0] = '\0'; + } +} + +bool parse_digit(const char* str, char* result, int* n) +{ + char* nums[] = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}; + int numslen[] = {3, 3, 5, 4, 4, 3, 5, 5, 4}; + char numschar[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'}; + for (int i = 0; i < 9; i++) + { + if(strncmp(str, nums[i], numslen[i]) == 0) + { + *result = numschar[i]; + *n = numslen[i]; + return true; + } + } + return false; +} + +void extract_digits(char* str, char *first, char *last) +{ + char *p,*q; + p = str; + int n; + bool found = false; + while (*p != '\0' && !found) + { + switch(*p) + { + case 'o': + case 't': + case 'f': + case 's': + case 'e': + case 'n': + if(parse_digit(p, first, &n)) + { + found = true; + break; + } + default: + if (isdigit(*p)) + { + *first = *p; + found = true; + } + else + p++; + } + } + q = p; + *last = *first; + while (*q != '\0') // find next digit + { + switch(*q) + { + case 'o': + case 't': + case 'f': + case 's': + case 'e': + case 'n': + if(parse_digit(q, last, &n)) + { + q++; + break; + } + default: + if (isdigit(*q)) + { + *last = *q; + } + q++; + } + } +} + +long convert_chars(char first, char last) +{ + char num[3] = { first, last, '\0' }; + return strtoul(num, NULL, 10); +} + +int main(int argc, char *argv[]) +{ + FILE* input = fopen("input", "r"); + if (input == NULL) + { + fprintf(stderr, "error opening file"); + return EXIT_FAILURE; + } + long sum = 0; + char first, last; + + while(true) + { + read_line(buffer, input); + if (feof(input)) + break; + extract_digits(buffer, &first, &last); + long value = convert_chars(first, last); + printf("%ld\t%c\t%c\t%s", value, first, last, buffer); + sum += value; + } + + printf("%ld", sum); + return EXIT_SUCCESS; +} diff --git a/day2/Makefile b/day2/Makefile new file mode 100644 index 0000000..93738bc --- /dev/null +++ b/day2/Makefile @@ -0,0 +1,8 @@ +part1: part1.c + gcc -Wall -g -o bin/part1 part1.c +part2: part2.c + gcc -Wall -g -o bin/part2 part2.c + +.PHONY: clean +clean: + rm part1 part2 diff --git a/day2/part1.c b/day2/part1.c new file mode 100644 index 0000000..e27b86c --- /dev/null +++ b/day2/part1.c @@ -0,0 +1,215 @@ +#include +#include +#include +#include +#include + +typedef struct elfgame { + long number; + struct elfgame_play *plays; + struct elfgame *next; +} elfgame; + +typedef struct elfgame_play { + long red, blue, green; + struct elfgame_play *next; +} elfgame_play; + +elfgame *first_game; + +void read_line(char* linebuf, FILE* file) +{ + char* str = fgets(linebuf, 2048, file); + if (feof(file)) + { + return; + } + if (str == NULL) + { + fprintf(stderr, "Fgets error"); + linebuf[0] = '\0'; + } +} + +long get_gamenum(char* line) +{ + regex_t regex; + char pattern[] = "Game ([0-9]+):.*"; + regmatch_t pmatch[2]; + if (regcomp(®ex, pattern, REG_EXTENDED)) + { + fprintf(stderr, "error compiling regex"); + return -1; + } + int rc = regexec(®ex, line, 2, pmatch, 0); + if (rc) + { + char buf[2048]; + regerror(rc, ®ex, buf, 2048); + fprintf(stderr, "error execing regex"); + return -1; + } + return strtoul(line + pmatch[1].rm_so, NULL, 10); +} + +elfgame_play *parse_play(char *line, int offset) +{ + regex_t regex; + regmatch_t pmatch[3]; + char pattern[] = "([0-9]+)[[:space:]](red|green|blue);?"; + char *s = line; + elfgame_play *p = malloc(sizeof(elfgame_play)); + if (p == NULL) + { + fprintf(stderr, "OOM"); + return NULL; + } + p->red = p->blue = p->green = 0; + if (regcomp(®ex, pattern, REG_EXTENDED)) + { + fprintf(stderr, "error compiling regex"); + return NULL; + } + for (int i = 0; ; i++) + { + if (regexec(®ex, s, 3, pmatch, 0)) + break; + if (s >= line + offset) + break; + long count = strtoul(s + pmatch[1].rm_so, NULL, 10); + if (strncmp(s + pmatch[2].rm_so, "red", 3) == 0) + { + p->red += count; + } + if (strncmp(s + pmatch[2].rm_so, "blue", 4) == 0) + { + p->blue += count; + } + if (strncmp(s + pmatch[2].rm_so, "green", 5) == 0) + { + p->green += count; + } + s += pmatch[0].rm_eo; + } + regfree(®ex); + return p; +} + +elfgame_play *parse_plays(char* line, int offset) +{ + regex_t regex; + regmatch_t pmatch[3]; + char pattern[] = "([0-9]+)[[:space:]](red|blue|green)"; + char *s = line; + elfgame_play *first = malloc(sizeof(elfgame_play)); + if (first == NULL) + { + fprintf(stderr, "OOM"); + return NULL; + } + elfgame_play *cur = first; + if (regcomp(®ex, pattern, REG_EXTENDED)) + { + fprintf(stderr, "error compiling regex"); + return NULL; + } + for (int i = 0; ; i++) + { + if (regexec(®ex, s, 3, pmatch, 0)) + break; + if (s > line + offset) + break; + elfgame_play *p = malloc(sizeof(elfgame_play)); + if (p == NULL) + { + fprintf(stderr, "OOM"); + return NULL; + } + p->red = p->blue = p->green = 0; + long count = strtoul(s + pmatch[1].rm_so, NULL, 10); + if (strncmp(s + pmatch[2].rm_so, "red", 3) == 0) + { + p->red += count; + } + if (strncmp(s + pmatch[2].rm_so, "blue", 4) == 0) + { + p->blue += count; + } + if (strncmp(s + pmatch[2].rm_so, "green", 5) == 0) + { + p->green += count; + } + cur->next = p; + cur = cur->next; + s += pmatch[0].rm_eo; + } + return first; +} + +elfgame *parse_game(char* line) +{ + regex_t regex; + regmatch_t pmatch[4]; + char pattern[] = "(([0-9]+)[[:space:]](red|blue|green),?[[:space:]]?)+;?"; + if (regcomp(®ex, pattern, REG_EXTENDED)) + { + fprintf(stderr, "error compiling regex"); + return NULL; + } + char *s = line; + elfgame *g = malloc(sizeof(elfgame)); + if (g == NULL) + { + return NULL; + } + g->number = get_gamenum(line); + elfgame_play *dummy = malloc(sizeof(elfgame_play)); + if (dummy == NULL) + { + return NULL; + } + dummy->red = dummy->green = dummy->blue = 0; + elfgame_play *cur = dummy; + g->plays = dummy; + for (int i = 0; ; i++) + { + if(regexec(®ex, s, 4, pmatch, 0)) + break; + cur->next = parse_play(line, pmatch[0].rm_eo); + cur = cur->next; + s += pmatch[0].rm_eo; + } + regfree(®ex); + return g; +} + +int main(int argc, char *argv[]) +{ + char buffer[2048]; + FILE* input = fopen("input", "r"); + if (input == NULL) + { + fprintf(stderr, "error opening file"); + return EXIT_FAILURE; + } + long sum = 0; + first_game = malloc(sizeof(elfgame)); + if (first_game == NULL) + { + fprintf(stderr, "OOM"); + return EXIT_FAILURE; + } + elfgame *cur = first_game; + while(true) + { + read_line(buffer, input); + if (feof(input)) + break; + elfgame *g = parse_game(buffer); + cur->next = g; + cur = cur->next; + } + + printf("%ld", sum); + return EXIT_SUCCESS; +} diff --git a/day2/part1.py b/day2/part1.py new file mode 100644 index 0000000..ca1f29f --- /dev/null +++ b/day2/part1.py @@ -0,0 +1,63 @@ +import re + + +class Game: + def __init__(self, id, r=0, b=0, g=0): + self.id = id + self.red = r + self.blue = b + self.green = g + + def __str__(self): + return f'game: {self.id}, max_red={self.red}, max_blue={self.blue}, max_green={self.green}' + + +game_pattern = re.compile(r'Game ([0-9]+):\s(.*)') +play_pattern = re.compile(r'([0-9]+)\s(red|green|blue)') +total_red = 12 +total_blue = 14 +total_green = 13 + + +def parse_game(line): + m = game_pattern.search(line) + plays = m.groups()[1].split('; ') + game = Game(int(m.groups()[0])) + for play in plays: + counts = play.split(', ') + for c in counts: + r = b = g = 0 + pm = play_pattern.search(c) + if pm.groups()[1] == 'red': + r = int(pm.groups()[0]) + if pm.groups()[1] == 'blue': + b = int(pm.groups()[0]) + if pm.groups()[1] == 'green': + g = int(pm.groups()[0]) + + game.red = max(game.red, r) + game.blue = max(game.blue, b) + game.green = max(game.green, g) + return game + + +def main(): + games = [] + with open('input', 'r') as f: + while True: + line = f.readline() + if not line: + break + games.append(parse_game(line)) + + sum = 0 + for g in games: + if g.red > total_red or g.blue > total_blue or g.green > total_green: + continue + sum += g.id + print(sum) + + + +if __name__ == '__main__': + main() diff --git a/day2/part2.py b/day2/part2.py new file mode 100644 index 0000000..49134c9 --- /dev/null +++ b/day2/part2.py @@ -0,0 +1,62 @@ +import re + + +class Game: + def __init__(self, id, r=0, b=0, g=0): + self.id = id + self.red = r + self.blue = b + self.green = g + + def __str__(self): + return f'game: {self.id}, max_red={self.red}, max_blue={self.blue}, max_green={self.green}' + + +game_pattern = re.compile(r'Game ([0-9]+):\s(.*)') +play_pattern = re.compile(r'([0-9]+)\s(red|green|blue)') +total_red = 12 +total_blue = 14 +total_green = 13 + + +def parse_game(line): + m = game_pattern.search(line) + plays = m.groups()[1].split('; ') + game = Game(int(m.groups()[0])) + for play in plays: + counts = play.split(', ') + for c in counts: + r = b = g = 0 + pm = play_pattern.search(c) + if pm.groups()[1] == 'red': + r = int(pm.groups()[0]) + if pm.groups()[1] == 'blue': + b = int(pm.groups()[0]) + if pm.groups()[1] == 'green': + g = int(pm.groups()[0]) + + game.red = max(game.red, r) + game.blue = max(game.blue, b) + game.green = max(game.green, g) + return game + + +def main(): + games = [] + with open('input', 'r') as f: + while True: + line = f.readline() + if not line: + break + games.append(parse_game(line)) + + sum = 0 + for g in games: + power = g.red * g.blue * g.green + sum += power + print(sum) + + + +if __name__ == '__main__': + main()