#include #include #include #include #define COUNT 10 #define SIZE (10 * sizeof(int)) #define INP_COUNT 144 #define FLIP_X (0b11 << 0) #define FLIP_Y (0b11 << 2) #define ROT_ONE (0b11 << 4) #define ROT_TWO (0b11 << 6) #define ROT_THREE (0b11 << 8) enum cnt_pos { T, R, B, L }; struct tile { int id; int match[INP_COUNT]; int reversed; // Bitmap char image[COUNT][COUNT]; int cnt[4]; // cnt_pos int top[COUNT]; int right[COUNT]; int bottom[COUNT]; int left[COUNT]; int top_rev[COUNT]; int right_rev[COUNT]; int bottom_rev[COUNT]; int left_rev[COUNT]; }; void set_rotation(int *reversed, int pos_a, int pos_b, int is_rev) { int rot = abs((pos_a + 1) - (pos_b + 1)); if (rot == 0) return; if (rot == 1 && !is_rev) *reversed |= ROT_ONE; else if (rot == 2 && !is_rev) *reversed |= ROT_TWO; else if (rot == 3 && !is_rev) *reversed |= ROT_THREE; if (is_rev && rot % 2 == 0) { *reversed |= FLIP_X; } else if (is_rev && rot % 2 == 1) { *reversed |= FLIP_Y; } } void reverse(int dest[], int src[]) { for (int i = 0; i < COUNT; i++) { dest[COUNT - 1 - i] = src[i]; } } long part_one(FILE *fp) { long res = 1; struct tile tiles[INP_COUNT] = { 0 }; int tile_cnt = 0; char *line = NULL; size_t len; int y = 0; while (getline(&line, &len, fp) != -1) { int num; if (line[0] == '\n') { tile_cnt++; } else if (sscanf(line, "Tile %d:", &num) == 1) { struct tile new = { 0 }; new.id = num; tiles[tile_cnt] = new; y = 0; } else { struct tile *tile = &tiles[tile_cnt]; memcpy(tile->image, line, COUNT); if (y == 0) { for (int i = 0; i < COUNT; i++) { tile->top[i] = line[i] == '#'; tile->cnt[T] += tile->top[i]; } } else if (y == COUNT - 1) { for (int i = 0; i < COUNT; i++) { tile->bottom[i] = line[i] == '#'; tile->cnt[B] += tile->bottom[i]; } } tile->left[y] = line[0] == '#'; tile->cnt[L] += tile->left[y]; tile->right[y] = line[COUNT - 1] == '#'; tile->cnt[R] += tile->right[y]; y++; } } tile_cnt++; free(line); for (int i = 0; i < tile_cnt; i++) { struct tile *tile = &tiles[i]; reverse(tile->top_rev, tile->top); reverse(tile->right_rev, tile->right); reverse(tile->bottom_rev, tile->bottom); reverse(tile->left_rev, tile->left); } for (int i = 0; i < tile_cnt; i++) { struct tile *tile = &tiles[i]; // Find adjacent int *cur, cnt; for (int j = 0; j < 4; j++) { // TRBL switch (j) { case T: cnt = tile->cnt[T]; cur = tile->top; break; case R: cnt = tile->cnt[R]; cur = tile->right; break; case B: cnt = tile->cnt[B]; cur = tile->bottom; break; case L: cnt = tile->cnt[L]; cur = tile->left; break; default: exit(1); break; } for (int k = 0; k < tile_cnt; k++) { struct tile *cmp = &tiles[k]; if (cmp->id == tile->id) continue; int match_cnt = 0, reversed = 0; if (cnt == cmp->cnt[T]) { if (!memcmp(cur, cmp->top, SIZE)) { set_rotation(&reversed, T, j, 0); match_cnt++; } else if (!memcmp(cur, cmp->top_rev, SIZE)) { set_rotation(&reversed, T, j, 1); match_cnt++; } } if (cnt == cmp->cnt[R]) { if (!memcmp(cur, cmp->right, SIZE)) { set_rotation(&reversed, R, j, 0); match_cnt++; } else if (!memcmp(cur, cmp->right_rev, SIZE)) { set_rotation(&reversed, R, j, 1); //reversed |= REV_RIGHT; match_cnt++; } } if (cnt == cmp->cnt[B]) { if (!memcmp(cur, cmp->bottom, SIZE)) { set_rotation(&reversed, B, j, 0); match_cnt++; } else if (!memcmp(cur, cmp->bottom_rev, SIZE)) { set_rotation(&reversed, B, j, 1); //reversed |= REV_BOTTOM; match_cnt++; } } if (cnt == cmp->cnt[L]) { if (!memcmp(cur, cmp->left, SIZE)) { set_rotation(&reversed, L, j, 0); match_cnt++; } else if (!memcmp(cur, cmp->left_rev, SIZE)) { set_rotation(&reversed, L, j, 1); //reversed |= REV_LEFT; match_cnt++; } } tile->match[k] += match_cnt; if (reversed != 0) cmp->reversed = reversed; } } } for (int i = 0; i < tile_cnt; i++) { struct tile *tile = &tiles[i]; if (tile->reversed) printf("%d: %x\n", tile->id, tile->reversed); int cnt = 0, flipped = 0; for (int j = 0; j < tile_cnt; j++) { cnt += tile->match[j]; } if (cnt == 2) { res *= tile->id; } } return res; } long part_two(FILE *fp) { long res = 0; return res; } int main(int argc, char *argv[]) { FILE *fp = fopen("input", "r"); if (!fp) exit(EXIT_FAILURE); clock_t tic = clock(); printf("%lu\n", part_one(fp)); rewind(fp); printf("%lu\n", part_two(fp)); clock_t toc = clock(); printf("TIME: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC); fclose(fp); return 0; }