days 1 and 2
This commit is contained in:
commit
99a2a4f996
|
@ -0,0 +1,2 @@
|
||||||
|
bin
|
||||||
|
input
|
|
@ -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
|
|
@ -0,0 +1,78 @@
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
|
@ -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
|
|
@ -0,0 +1,215 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
|
@ -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()
|
|
@ -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()
|
Loading…
Reference in New Issue