#include #include #include #include #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; }