diff options
Diffstat (limited to 'Advent-of-Code-2021/AOC-13/main.c')
-rw-r--r-- | Advent-of-Code-2021/AOC-13/main.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/Advent-of-Code-2021/AOC-13/main.c b/Advent-of-Code-2021/AOC-13/main.c new file mode 100644 index 0000000..876dae7 --- /dev/null +++ b/Advent-of-Code-2021/AOC-13/main.c @@ -0,0 +1,169 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#if 0 +#define PART_1 +#else +#define PART_2 +#endif + +#if 0 +#define FILE_PATH "example.txt" +#define RULES 2 +int WIDTH = 11; +int HEIGHT = 15; +#else +#define FILE_PATH "input.txt" +#define RULES 12 +int WIDTH = 1311; +int HEIGHT = 895; +#endif + +#define BOARD_SZ ((WIDTH)*(HEIGHT)) + +int *board = NULL; +int rules_val[RULES] = {0}; +int rules_axis[RULES] = {0}; // 0 is x; 1 is y + +void parse() +{ + FILE *fp = fopen(FILE_PATH, "r"); + if(!fp) { + fprintf(stderr, "Could not open file: %s", FILE_PATH); + return; + } + + board = malloc(BOARD_SZ*sizeof(int)); + + char line[256]; + char *tok; + int read_rules = -1; + while(fgets(line, sizeof(line), fp) != NULL) + { + if(line[0] == '\n') { + read_rules = 0; + } else if(read_rules < 0) { + tok = strtok(line, ","); + int x = atoi(tok); + tok = strtok(NULL, ","); + int y = atoi(tok); + + assert(strtok(NULL, ",") == NULL); + assert(x >= 0 && x < WIDTH); + assert(y >= 0 && y < HEIGHT); + board[y * WIDTH + x] = 1; + } else { + tok = strtok(line, "="); + rules_axis[read_rules] = (tok[11] == 'y'); + tok = strtok(NULL, "="); + rules_val[read_rules] = atoi(tok); + read_rules++; + assert(strtok(NULL, "=") == NULL); + } + } + + fclose(fp); +} + +void fold(int rules_i) +{ + int *board_cpy = malloc(BOARD_SZ*sizeof(int)); + + memcpy(board_cpy, board, BOARD_SZ*sizeof(int)); + free(board); + + int old_width = WIDTH; + if(rules_axis[rules_i] == 0) WIDTH = (WIDTH-1)/2; + else HEIGHT = (HEIGHT-1)/2; + + board = malloc(BOARD_SZ*sizeof(int)); + + for(int i = 0; i < HEIGHT; i++) + { + for(int j = 0; j < WIDTH; j++) + { + int index = i * WIDTH + j; + int bc_index = i * old_width + j; + int mirror; + + if(rules_axis[rules_i] == 0) { + mirror = i * old_width + (2*rules_val[rules_i] - j); + } else { + mirror = ((2*rules_val[rules_i] - i) + * old_width) + j; + } + + board[index] = + board_cpy[bc_index] + + board_cpy[mirror]; + } + } + + free(board_cpy); +} + +void print_board() +{ + for(int i = 0; i < HEIGHT; i++) + { + for(int j = 0; j < WIDTH; j++) + { + if(board[i * WIDTH + j] == 0) + putc('.', stdout); + else + putc('#', stdout); + } + putc('\n', stdout); + } +} + +void print_rules() +{ + for(int i = 0; i < RULES; i++) + { + char axis; + if(rules_axis[i] == 0) axis = 'x'; + else axis = 'y'; + printf("fold along %c=%d\n", axis, rules_val[i]); + } +} + +void part_1() +{ + parse(); + fold(0); + + int visible = 0; + for(int i = 0; i < BOARD_SZ; i++) + { + if(board[i] > 0) visible++; + } + + printf("%d dots are visible\n", visible); +} + +void part_2() +{ + parse(); + for(int i = 0; i < RULES; i++) + fold(i); + + print_board(); +} + +int main(void) +{ + +#ifdef PART_1 + part_1(); +#endif + +#ifdef PART_2 + part_2(); +#endif + + free(board); + return 0; +} |