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