diff --git a/c/2015/1/problem.c b/c/2015/1/problem.c index aca8867..a272714 100644 --- a/c/2015/1/problem.c +++ b/c/2015/1/problem.c @@ -1,26 +1,31 @@ #include +#include "../../lib/aoc.h" + int main() { - FILE* input = fopen("../data/2015/1/input.txt", "r"); - char c; + char *input = aoc_read_input(); int floor = 0; - while (fread(&c, 1, 1, input) > 0) { - if (c == '(') floor++; - else if(c == ')') floor--; + int index = 0; + while (input[index] > 0) { + if (input[index] == '(') floor++; + else if(input[index] == ')') floor--; + index++; } printf("Part 1: %d\n", floor); floor = 0; int steps = 0; - rewind(input); + index = 0; - while (fread(&c, 1, 1, input) > 0) { - if (c == '(') floor++; - else if(c == ')') floor--; + while (input[index] > 0) { + if (input[index] == '(') floor++; + else if(input[index] == ')') floor--; steps++; if (floor < 0) break; + index++; } printf("Part 2: %d\n", steps); + free(input); } diff --git a/c/2015/2/problem.c b/c/2015/2/problem.c new file mode 100644 index 0000000..4567ba5 --- /dev/null +++ b/c/2015/2/problem.c @@ -0,0 +1,48 @@ +#include +#include + +#include "../../lib/aoc.h" + +int volume(int length, int width, int height) { + return length * width * height; +} + +int ribbon_length(int length, int width, int height) { + int first_perimeter = (length + width) * 2; + int second_perimeter = (length + height) * 2; + int third_perimeter = (height + width) * 2; + int smallest_perimeter = first_perimeter; + if (second_perimeter < smallest_perimeter) smallest_perimeter = second_perimeter; + if (third_perimeter < smallest_perimeter) smallest_perimeter = third_perimeter; + return smallest_perimeter + volume(length, width, height); +} + +int surface_area(int length, int width, int height) { + int first_side = length * width * 2; + int second_side = length * height * 2; + int third_side = height * width * 2; + int smallest_side = first_side; + if (second_side < smallest_side) smallest_side = second_side; + if (third_side < smallest_side) smallest_side = third_side; + return first_side + second_side + third_side + (smallest_side / 2); +} + +int main() { + char *input = aoc_read_input(); + int paper = 0; + int ribbon = 0; + char *tok = strtok(input, "x"); + while (tok != NULL) { + int l = atoi(tok); + tok = strtok(NULL, "x"); + int w = atoi(tok); + tok = strtok(NULL, "\n"); + int h = atoi(tok); + paper += surface_area(l, w, h); + ribbon += ribbon_length(l, w, h); + tok = strtok(NULL, "x"); + } + printf("Part 1: %d\n", paper); + printf("Part 1: %d\n", ribbon); + free(input); +} diff --git a/c/2015/3/problem.c b/c/2015/3/problem.c new file mode 100644 index 0000000..aa31b09 --- /dev/null +++ b/c/2015/3/problem.c @@ -0,0 +1,72 @@ +#include +#include + +#include "../../lib/aoc.h" + +int compare(const void *a, const void *b) { + return *(int*)a - *(int*)b; +} + +int visited_houses(char *input, int num_santas) { + int moves_count = strlen(input); + int *positions = calloc(moves_count + 1, sizeof(int)); // +1 for the starting position + int **santa_positions = calloc(num_santas, sizeof(int*)); + for (int i = 0; i < num_santas; i++) { + santa_positions[i] = calloc(2, sizeof(int)); + santa_positions[i][0] = 0; + santa_positions[i][1] = 0; + } + int santa_index = 0; + int *santa_position = santa_positions[0]; + + positions[0] = 0; + int index = 0; + + while (input[index] > 10) { + switch(input[index++]) { + case '^': + santa_position[1] += 1; + break; + case 'v': + santa_position[1] -= 1; + break; + case '>': + santa_position[0] += 1; + break; + case '<': + santa_position[0] -= 1; + break; + } + + positions[index] = (santa_position[0] * moves_count) + santa_position[1]; + santa_index = (santa_index + 1) % num_santas; + santa_position = santa_positions[santa_index]; + } + + qsort(positions, moves_count, sizeof(int), compare); + int last_position = positions[0]; + int num_visited_houses = 0; + + for (int i = 0; i < moves_count + 1; i++) { + if (positions[i] != last_position) { + num_visited_houses++; + last_position = positions[i]; + } + } + + free(positions); + for (int i = 0; i < num_santas; i++) { + free(santa_positions[i]); + } + free(santa_positions); + return num_visited_houses; +} + +int main() { + char *input = aoc_read_input(); + + printf("Part 1: %d\n", visited_houses(input, 1)); + printf("Part 2: %d\n", visited_houses(input, 2)); + + free(input); +} diff --git a/c/2017/1/problem.c b/c/2017/1/problem.c index 2b60143..b3255f4 100644 --- a/c/2017/1/problem.c +++ b/c/2017/1/problem.c @@ -1,43 +1,35 @@ #include #include +#include + +#include "../../lib/aoc.h" int main() { - FILE* input = fopen("../data/2017/1/input.txt", "r"); - char c1, c2, first_char; - long total; + char *input = aoc_read_input(); + int length = strlen(input) - 1; + int sum = 0; - fread(&first_char, 1, 1, input); - c2 = first_char; - - while (fread(&c1, 1, 1, input) > 0 && c1 != '\n') { - if (c1 == c2) { - total += c1 - '0'; - } - c2 = c1; - } - - if (c2 == first_char) { - total += c2 - '0'; - } - - printf("Part 1: %d\n", total); - - int num_chars = ftell(input); - rewind(input); - total = 0; - - char *buffer = malloc(num_chars); - fread(buffer, 1, num_chars, input); - - for(int i = 0; i < num_chars / 2; i++) { - c1 = buffer[i]; - c2 = buffer[i + (num_chars / 2)]; - if (c1 == c2) { - total += c1 - '0'; + for (int i = 0; i < length - 1; i++) { + if (input[i] == input[i + 1]) { + sum += input[i] - '0'; } } - total <<= 1; + if (input[0] == input[length - 1]) { + sum += input[0] - '0'; + } - printf("Part 2: %d\n", total); + printf("Part 1: %d\n", sum); + + sum = 0; + + for (int i = 0; i < length; i++) { + if (input[i] == input[(i + (length / 2)) % length]) { + sum += input[i] - '0'; + } + } + + printf("Part 2: %d\n", sum); + + free(input); } diff --git a/c/2017/2/problem.c b/c/2017/2/problem.c new file mode 100644 index 0000000..4201fd1 --- /dev/null +++ b/c/2017/2/problem.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include + +#include "../../lib/aoc.h" + +int line_checksum_1(char *line) { + char **saveptr = malloc(sizeof(char*)); + char *token = strtok_r(line, "\t", saveptr); + + int min = INT_MAX; + int max = INT_MIN; + + while (token != NULL) { + int value = atoi(token); + if (value < min) min = value; + if (value > max) max = value; + token = strtok_r(NULL, "\t", saveptr); + } + + free(saveptr); + return max - min; +} + +int line_checksum_2(char *line) { + int tokens[20]; + + char **saveptr = malloc(sizeof(char*)); + char *token = strtok_r(line, "\t", saveptr); + int index = 0; + + while (token != NULL) { + tokens[index++] = atoi(token); + token = strtok_r(NULL, "\t", saveptr); + } + + for (int i = 0; i < index; i++) { + for (int j = 0; j < index; j++) { + if (tokens[i] != tokens[j] && (tokens[i] % tokens[j] == 0)) { + free(saveptr); + return tokens[i] / tokens[j]; + } + } + } + + for (int i = 0; i < index; i++) { + printf("%d ", tokens[i]); + } + printf("ERROR! No checksum found\n"); + + return 0; +} + +int main() { + char *input = aoc_read_input(); + + char **line_saveptr = malloc(sizeof(char*)); + char *line = strtok_r(input, "\n", line_saveptr); + + int checksum_sum_1 = 0; + int checksum_sum_2 = 0; + + while (line != NULL) { + char *line_copy = malloc(strlen(line) + 1); + strcpy(line_copy, line); + checksum_sum_1 += line_checksum_1(line); + checksum_sum_2 += line_checksum_2(line_copy); + line = strtok_r(NULL, "\n", line_saveptr); + free(line_copy); + } + + printf("Part 1: %d\n", checksum_sum_1); + printf("Part 2: %d\n", checksum_sum_2); + + free(line_saveptr); + free(line); + free(input); +} diff --git a/c/bin/run b/c/bin/run index 176083a..ef8233d 100755 --- a/c/bin/run +++ b/c/bin/run @@ -3,4 +3,5 @@ year=$1 day=$2 -gcc -o $year/$day/problem $year/$day/problem.c && time ./$year/$day/problem +gcc -o $year/$day/problem $year/$day/problem.c +time (cat ../data/$year/$day/input.txt | ./$year/$day/problem) diff --git a/c/lib/aoc.h b/c/lib/aoc.h new file mode 100644 index 0000000..c3054e1 --- /dev/null +++ b/c/lib/aoc.h @@ -0,0 +1,22 @@ +#include +#include +#include + +#define INITIAL_BUFFER_SIZE 2 + +char *aoc_read_input(void) { + int buffer_size = INITIAL_BUFFER_SIZE; + char *input_buffer = malloc(buffer_size); + int chars_read = read(STDIN_FILENO, input_buffer, buffer_size); + char *buffer_position = &input_buffer[chars_read]; + + while (chars_read == buffer_size) { + buffer_size *= 2; + input_buffer = realloc(input_buffer, buffer_size); + buffer_position = &input_buffer[chars_read]; + chars_read += read(STDIN_FILENO, buffer_position, buffer_size / 2); + } + + input_buffer[chars_read] = 0; + return input_buffer; +}