diff --git a/aoc.h b/aoc.h index 66b28fa..8829c6c 100644 --- a/aoc.h +++ b/aoc.h @@ -3,7 +3,7 @@ #include -typedef int (*solution_cb)(void*); +typedef void (*solution_cb)(void*); typedef void* (*parse_cb)(char** lines, int count); typedef struct { int day; diff --git a/day1.c b/day1.c index 3a0ab90..f023194 100644 --- a/day1.c +++ b/day1.c @@ -46,7 +46,7 @@ static void *day1_parse(char **lines, int line_count) return data; } -static int day1_part1(void *p) +static void day1_part1(void *p) { Data *data = (Data*)p; int max_calories = 0; @@ -57,10 +57,10 @@ static int day1_part1(void *p) } max_calories = MAX(max_calories, calories); } - return max_calories; + printf("%d\n", max_calories); } -static int day1_part2(void *p) +static void day1_part2(void *p) { Data *data = (Data*)p; int max_calories1 = 0; @@ -82,7 +82,7 @@ static int day1_part2(void *p) max_calories3 = calories; } } - return max_calories1 + max_calories2 + max_calories3; + printf("%d\n", max_calories1 + max_calories2 + max_calories3); } ADD_SOLUTION(1, day1_parse, day1_part1, day1_part2); diff --git a/day2.c b/day2.c index 99e6600..941a20e 100644 --- a/day2.c +++ b/day2.c @@ -22,7 +22,7 @@ static void *day2_parse(char **lines, int line_count) return vec; } -static int day2_part1(void *p) +static void day2_part1(void *p) { Vec *rounds = p; int result = 0; @@ -49,10 +49,10 @@ static int day2_part1(void *p) result += 6; } } - return result; + printf("%d\n", result); } -static int day2_part2(void *p) +static void day2_part2(void *p) { Vec *data = p; int result = 0; @@ -81,7 +81,7 @@ static int day2_part2(void *p) result += 6; } } - return result; + printf("%d\n", result); } ADD_SOLUTION(2, day2_parse, day2_part1, day2_part2); diff --git a/day3.c b/day3.c index 4726c35..ab3e127 100644 --- a/day3.c +++ b/day3.c @@ -45,7 +45,7 @@ static int get_priority(char c) return 0; } -static int day3_part1(void *p) +static void day3_part1(void *p) { Vec *vec = p; int result = 0; @@ -59,10 +59,10 @@ static int day3_part1(void *p) fprintf(stderr, "Unknown common char at line: %zu\n", i+1); } } - return result; + printf("%d\n", result); } -static int day3_part2(void *p) +static void day3_part2(void *p) { Vec *vec = p; int result = 0; @@ -88,7 +88,7 @@ static int day3_part2(void *p) fprintf(stderr, "Unknown common char at line: %zu-%zu\n", i+1, i+3); } } - return result; + printf("%d\n", result); } ADD_SOLUTION(3, day3_parse, day3_part1, day3_part2); diff --git a/day4.c b/day4.c index eef4bcb..4e0a3dc 100644 --- a/day4.c +++ b/day4.c @@ -41,7 +41,7 @@ static void *day4_parse(char **lines, int line_count) return vec; } -static int day4_part1(void *p) +static void day4_part1(void *p) { Vec *vec = p; int result = 0; @@ -54,10 +54,10 @@ static int day4_part1(void *p) result++; } } - return result; + printf("%d\n", result); } -static int day4_part2(void *p) +static void day4_part2(void *p) { Vec *vec = p; int result = 0; @@ -71,7 +71,7 @@ static int day4_part2(void *p) result++; } } - return result; + printf("%d\n", result); } diff --git a/day5.c b/day5.c new file mode 100644 index 0000000..ab329d6 --- /dev/null +++ b/day5.c @@ -0,0 +1,165 @@ +#include +#include +#include +#include + +#include "aoc.h" +#include "vec.h" + +typedef struct { + int from, to, amount; +} Move; + +typedef struct { + Vec *towers; + Vec *moves; +} day5_Data; + +static Move* day5_parse_move(char *line) +{ + char* line_copy = strdup(line); + char* line_copy_original = line_copy; + strsep(&line_copy, " "); + char* amount = strsep(&line_copy, " "); + strsep(&line_copy, " "); + char* from = strsep(&line_copy, " "); + strsep(&line_copy, " "); + char* to = strsep(&line_copy, " "); + + Move *move = malloc(sizeof(Move)); + move->amount = atoi(amount); + move->from = atoi(from)-1; + move->to = atoi(to)-1; + free(line_copy); + return move; +} + +static void *day5_parse(char **lines, int line_count) +{ + int tower_count = 0; + int max_tower_height; + + for (int i = 0; i < line_count; i++) { + if (lines[i][0] == '\0') { + max_tower_height = i-1; + break; + } + + tower_count = MAX(tower_count, (strlen(lines[i])+1)/4); + } + + int move_count = line_count - max_tower_height - 2; + Vec *moves = vec_malloc(move_count); + for (int i = 0; i < move_count; i++) { + char *line = lines[max_tower_height+2+i]; + vec_push(moves, day5_parse_move(line)); + } + + Vec *towers = vec_malloc(tower_count); + for (int i = 0; i < tower_count; i++) { + char* tower = calloc(26, sizeof(char)); + vec_push(towers, tower); + } + for (int i = max_tower_height-1; i >= 0; i--) { + char* line = lines[i]; + int line_size = strlen(line); + for (int j = 0; j < tower_count; j++) { + int index = j*4 + 1; + if (index >= line_size) break; + if (line[index] == ' ') continue; + + char* tower = towers->data[j]; + tower[max_tower_height-i-1] = line[index]; + } + } + + day5_Data *data = malloc(sizeof(day5_Data)); + data->moves = moves; + data->towers = towers; + return data; +} + +static void do_move(char **towers, int *tower_sizes, int from, int to) +{ + int from_size = tower_sizes[from]; + int to_size = tower_sizes[to]; + towers[to][to_size] = towers[from][from_size-1]; + + tower_sizes[from]--; + tower_sizes[to]++; +} + +static void do_move_many(char **towers, int *tower_sizes, int from, int to, int amount) +{ + int from_size = tower_sizes[from]; + int to_size = tower_sizes[to]; + memcpy(towers[to] + to_size, towers[from] + from_size - amount, amount); + + tower_sizes[from] -= amount; + tower_sizes[to] += amount; +} + +static char* form_answer(char **towers, int tower_count, int *tower_sizes) +{ + char *answer = malloc(tower_count + 1); + answer[tower_count] = '\0'; + for (int i = 0; i < tower_count; i++) { + char *tower = towers[i]; + answer[i] = tower[tower_sizes[i]-1]; + } + return answer; +} + +static void day5_part1(void *p) +{ + day5_Data *data = p; + int tower_count = data->towers->count; + char *towers[tower_count]; + int tower_sizes[tower_count]; + for (int i = 0; i < tower_count; i++) { + towers[i] = calloc(26, sizeof(char)); + memcpy(towers[i], data->towers->data[i], 26); + + tower_sizes[i] = 0; + for (int j = 0; j < 26; j++) { + if (towers[i][j] == 0) break; + tower_sizes[i]++; + } + } + + for (int i = 0; i < data->moves->count; i++) { + Move *move = data->moves->data[i]; + for (int j = 0; j < move->amount; j++) { + do_move(towers, tower_sizes, move->from, move->to); + } + } + + printf("%s\n", form_answer(towers, tower_count, tower_sizes)); +} + +static void day5_part2(void *p) +{ + day5_Data *data = p; + int tower_count = data->towers->count; + char *towers[tower_count]; + int tower_sizes[tower_count]; + for (int i = 0; i < tower_count; i++) { + towers[i] = calloc(26, sizeof(char)); + memcpy(towers[i], data->towers->data[i], 26); + + tower_sizes[i] = 0; + for (int j = 0; j < 26; j++) { + if (towers[i][j] == 0) break; + tower_sizes[i]++; + } + } + + for (int i = 0; i < data->moves->count; i++) { + Move *move = data->moves->data[i]; + do_move_many(towers, tower_sizes, move->from, move->to, move->amount); + } + + printf("%s\n", form_answer(towers, tower_count, tower_sizes)); +} + +ADD_SOLUTION(5, day5_parse, day5_part1, day5_part2); diff --git a/main.c b/main.c index 26d7a56..5617f98 100644 --- a/main.c +++ b/main.c @@ -12,6 +12,7 @@ #include "day2.c" #include "day3.c" #include "day4.c" +#include "day5.c" Solution *find_solution(int day) { @@ -156,8 +157,10 @@ int main(int argc, char** argv) { void* parsed = solution->parse(lines, line_count); - printf("part1: %d\n", solution->part1(parsed)); - printf("part2: %d\n", solution->part2(parsed)); + printf("part1:\n"); + solution->part1(parsed); + printf("part2:\n"); + solution->part2(parsed); return 0; }