#include #include #include struct Piece { char name; char left; char top[3]; char bottom[3]; char right; char bottoml() { return bottom[0]; } char bottomr() { return bottom[1] != '\0' ? bottom[1] : bottom[0]; } }; Piece pieces[8] = { { 'a', '|', "2", "4", '.' }, { 'b', '.', "3", "15", '.' }, { 'c', '.', "4", "2", '|' }, { 'd', '.', "", "3", '.' }, { 'e', '|', "3", "3", '|' }, { 'f', '.', "41", "14", '.' }, { 'g', '.', "52", "25", '.' }, { '-', '.', "3", "3", '.' }, }; #define KINDINDEX(C) ((C) == '-' ? 7 : (C) - 'a') struct Connection { bool possible; char top[4]; char bottom[4]; }; Connection connections[8][8]; void buildConnections() { for (int li = 0; li < 8; li++) { Piece &l = pieces[li]; if (l.name == 'd') continue; for (int ri = 0; ri < 8; ri++) { Piece &r = pieces[ri]; if (r.name == 'd') continue; Connection &c = connections[li][ri]; c.possible = false; if (l.right != r.left) continue; if (l.bottomr() == '5' && r.bottoml() == '3') continue; if (l.bottomr() == '3' && r.bottoml() == '1') continue; c.possible = true; strcpy(c.top, r.top); char *t = c.bottom; char *f = r.bottom; if (l.bottomr() == '5') { if (*f == '1') { *t++ = '3'; f++; } else *t++ = '5'; } for (; *f != '\0' && *f != '5'; f++) *t++ = *f; *t = '\0'; } } printf(" "); for (int ri = 0; ri < 8; ri++) printf(" %c", pieces[ri].name); printf("\n"); for (int li = 0; li < 8; li++) { printf(" %c ", pieces[li].name); for (int ri = 0; ri < 8; ri++) { Connection &c = connections[li][ri]; if (c.possible) printf(" %2s/%-2s", c.top, c.bottom); else printf(" - "); } printf("\n"); } } #define MAX_LEN 50 void reverse(const char *in, char *out) { int l = strlen(in); for (int i = 0; i < l; i++) { char ch = in[i]; switch(ch) { case 'a' : ch = 'c'; break; case 'c' : ch = 'a'; break; case 'f' : ch = 'g'; break; case 'g' : ch = 'f'; break; case '1' : ch = '5'; break; case '2' : ch = '4'; break; case '4' : ch = '2'; break; case '5' : ch = '1'; break; } out[l-1-i] = ch; } out[l] = '\0'; } int normalize(char *in, char *out) { char temp[MAX_LEN+1]; char rev_temp[MAX_LEN+1]; int opt = 0; strcpy(out, in); int l = strlen(in); for (int i = 0; i < l; i++) { for (int j = 0; j < l; j++) temp[j] = in[(i+j)%l]; temp[l] = '\0'; if (strcmp(temp, out) < 0) { strcpy(out, temp); opt = i; } reverse(temp, rev_temp); if (strcmp(rev_temp, out) < 0) { strcpy(out, rev_temp); opt = -1-i; } } //printf("normalize %s %s %d\n", in, out, opt); return opt; } void shift(char *in, int opt, char *out) { int l = strlen(in); int i = opt >= 0 ? opt : -1 - opt; for (int j = 0; j < l; j++) out[j] = in[(i+j)%l]; out[l] = '\0'; if (opt < 0) { char rev_temp[MAX_LEN+1]; reverse(out, rev_temp); strcpy(out, rev_temp); } } int gcd(int a, int b) { while (b != 0) { int c = a % b; a = b; b = c; } return a; } int repeats(char *in) { int count = 1; int l = strlen(in); for (int i = 1; i < l; i++) { bool eq = true; for (int j = 0; j < l; j++) if (in[j] != in[(i+j)%l]) { eq = false; break; } if (eq) count++; } return count; } struct BelowLine; struct Group; struct Line { int len; char line[MAX_LEN+1]; int nr_top; int nr_bottom; bool ok; BelowLine *below_lines; Group *group; Line *next_in_group; int nr_in_group; int visited; Line *next; }; struct BelowLine { Line *line; char pieces[MAX_LEN+1]; int i_top; int i_bottom; int rep; BelowLine *next; }; Line *lines = 0; Line *find_line(const char *s) { int len = strlen(s); Line **ref_line = &lines; while (*ref_line != 0 && ((*ref_line)->len < len || ((*ref_line)->len == len && strcmp((*ref_line)->line, s) < 0))) ref_line = &(*ref_line)->next; if (*ref_line != 0 && strcmp((*ref_line)->line, s) == 0) return (*ref_line); Line *new_line = new Line; new_line->len = len; strcpy(new_line->line, s); new_line->nr_top = 0; new_line->nr_bottom = 0; new_line->below_lines = 0; new_line->group = 0; new_line->next_in_group = 0; new_line->nr_in_group = 0; new_line->visited = 0; new_line->next = *ref_line; *ref_line = new_line; return new_line; } void distance(char *line, int *movements) { for (int i = 1; i <= 5; i++) movements[i] = 0; for (char *s =line; *s != '\0'; s++) { if (*s == '1' && movements[5] > 0) { movements[5]--; movements[3]++; } else if (*s == '5' && movements[1] > 0) { movements[1]--; movements[3]++; } else movements[*s - '0']++; } } bool equal_distances(int *a, int *b) { for (int i = 1; i <= 5; i++) if (a[i] != b[i]) return false; return true; } char g_top[MAX_LEN+5]; char g_bottom[MAX_LEN+5]; char g_pieces[MAX_LEN+2]; void find_length(int n, int start, int cur, int depth) { //printf("%*.*sFind %c |%s|%s| %d\n", 2*depth, 2*depth, "", pieces[cur].name, g_top, g_bottom, n); if (depth == n) { if (start == cur) { //printf("%*.*sFind %s/%s |%s|%s| %d\n", 2*depth, 2*depth, "", cur->top, cur->bottom, g_top, g_bottom, n); char out_p[MAX_LEN+1]; if (normalize(g_pieces, out_p) == 0) { char out_t[MAX_LEN+1]; int i_top = normalize(g_top, out_t); Line *top_line = find_line(out_t); char out_b[MAX_LEN+1]; int i_bottom = normalize(g_bottom, out_b); Line *bottom_line = find_line(out_b); top_line->nr_top++; bottom_line->nr_bottom++; BelowLine *new_below_line = new BelowLine; new_below_line->line = bottom_line; new_below_line->i_top = i_top; new_below_line->i_bottom = i_bottom; g_pieces[depth] = '\0'; // printf("%s / %s %s / %s : %s\n", g_top, g_bottom, out_t, out_b, g_pieces); strcpy(new_below_line->pieces, g_pieces); new_below_line->rep = repeats(g_pieces); new_below_line->next = top_line->below_lines; top_line->below_lines = new_below_line; char out[MAX_LEN+1]; int top_dist[6]; distance(g_top, top_dist); int bottom_dist[6]; distance(g_bottom, bottom_dist); if (!equal_distances(top_dist, bottom_dist)) { printf("Dist not equal %s %s\n", g_top, g_bottom); } } } return; } int g_top_len = strlen(g_top); int g_bottom_len = strlen(g_bottom); for (int next = 0; next < 8; next++) { Connection &conn = connections[cur][next]; if (conn.possible) { g_pieces[depth] = pieces[next].name; strcpy(g_top + g_top_len, conn.top); strcpy(g_bottom + g_bottom_len, conn.bottom); find_length(n, start, next, depth+1); g_top[g_top_len] = '\0'; g_bottom[g_bottom_len] = '\0'; } } } void fill_lines(int max_length) { for (int n = 1; n < max_length; n++) { //printf("\n\nn = %d\n", n); for (int i = 0; i < 8; i++) { g_top[0] = '\0'; g_bottom[0] = '\0'; find_length(n, i, i, 0); } } for (Line *line = lines; line != 0; line = line->next) line->ok = line->nr_bottom > 0 && line->nr_top > 0; //printf("\n"); for (bool go = true; go;) { //printf("Pass: "); go = false; for (Line *line = lines; line != 0; line = line->next) if (line->ok) { bool any_below_ok = false; for (BelowLine *below_line = line->below_lines; below_line != 0; below_line = below_line->next) if (below_line->line->ok) { any_below_ok = true; break; } if (!any_below_ok) { line->ok = false; go = true; //printf("*"); } } //printf("\n"); } } struct Group { Line *lines; int nr; int mul; int distance[6]; Group *next; }; Group *groups = 0; void find_group(Line *line, Group* group) { if (line->group == 0 && line->ok) { //printf(" %s %d %d", line->line, line->nr_top, line->nr_bottom); for (BelowLine *below_line = line->below_lines; below_line != 0; below_line = below_line->next) { //printf(" = %s (%s%s)", below_line->pieces, below_line->line->line, below_line->line->ok ? "" : " FAIL"); group->mul = group->mul = 0 ? below_line->rep : gcd(group->mul, below_line->rep); } //printf("\n"); line->group = group; Line **ref_line = &group->lines; int nr_in_group = 0; while (*ref_line != 0) { ref_line = &(*ref_line)->next_in_group; nr_in_group++; } *ref_line = line; line->nr_in_group = nr_in_group; for (BelowLine *line_below = line->below_lines; line_below != 0; line_below = line_below->next) find_group(line_below->line, group); } } void make_groups() { int nr_groups = 1; Group **ref_groups = &groups; for (Line *line = lines; line != 0; line = line->next) if (line->group == 0 && line->ok) { Group *group = new Group; group->lines = 0; group->nr = nr_groups; group->mul = 0; distance(line->line, group->distance); group->next = 0; find_group(line, group); *ref_groups = group; ref_groups = &(group->next); nr_groups++; } *ref_groups = 0; } void print_groups() { for (Group *group = groups; group != 0; group = group->next) { printf("\ngroup "); double h = 0.5; double d = sqrt(3)/2; double x = h * group->distance[1] + d * group->distance[2] + 1 * group->distance[3] + d * group->distance[4] + h * group->distance[5]; double y = d * group->distance[1] + h * group->distance[2] - h * group->distance[4] - d * group->distance[5]; printf("%7.2lf %7.2lf ", y, x); for (int i = 1; i <= 5; i++) printf("%s%d", i == 1 ? "(" : ", ", group->distance[i]); printf(")\n %d\n", group->nr); for (Line *line = group->lines; line != 0; line = line->next_in_group) { printf(" %s %d %d", line->line, line->nr_top, line->nr_bottom); for (BelowLine *below_line = line->below_lines; below_line != 0; below_line = below_line->next) printf(" = %s (%s%s %d#%d)", below_line->pieces, below_line->line->line, below_line->line->ok ? "" : " FAIL", below_line->i_top, below_line->i_bottom); printf("\n"); } printf("mul = %d", group->mul); for (Group *other_group = groups; other_group != 0; other_group = other_group->next) if (equal_distances(other_group->distance, group->distance)) { printf(" dist %d", other_group->nr); break; } printf("\n"); } } #define MAX_PATT_DEPTH 30 #define MAX_PIECES 50 bool debug_pattern = false; struct Pattern { int nr_pieces; int nr_pieces_per_kind[7]; int nr_sym; Line *first; int depth; BelowLine *below_lines[MAX_PATT_DEPTH]; int nr_vertices; int neighbours[2*MAX_PIECES][12]; Pattern *next; int compare(Pattern *other) { int c = other->nr_pieces - nr_pieces; for (int i = 0; c == 0 && i < 7; i++) c = other->nr_pieces_per_kind[i] - nr_pieces_per_kind[i]; return c; } void connect(int f, int t, int d) { if (debug_pattern) printf("connect %d %d %d\n", f, t, d); neighbours[f][d] = t; neighbours[t][d + 6] = f; } }; Pattern *patterns = 0; BelowLine *below_line_stack[MAX_PATT_DEPTH]; void search_pattern(Line *first, Line *cur, bool inverted, int depth, int *pieces, int nr_pieces, int mul) { //printf("%*.*s%s %s %d\n", depth, depth, "", first->line, cur->line, nr_pieces); if (nr_pieces > MAX_PIECES || depth == MAX_PATT_DEPTH) return; if (depth > 0 && first == cur) { if (nr_pieces > 0 && mul == 1 && !inverted) { Pattern *pattern = new Pattern; pattern->first = first; pattern->depth = depth; for (int i = 0; i < depth; i++) pattern->below_lines[i] = below_line_stack[i]; pattern->next = 0; int norm_pieces[7]; for (int i = 0; i < 7; i++) { pattern->nr_pieces_per_kind[i] = norm_pieces[i] = pieces[i]; pattern->nr_pieces += pieces[i]; } pattern->nr_sym = 1; for (int j = 0; j < 23; j++) { if (j == 11) { int h = norm_pieces[0]; norm_pieces[0] = norm_pieces[2]; norm_pieces[2] = h; h = norm_pieces[5]; norm_pieces[5] = norm_pieces[6]; norm_pieces[6] = h; } else { int h = norm_pieces[3]; norm_pieces[3] = norm_pieces[0]; norm_pieces[0] = norm_pieces[1]; norm_pieces[1] = norm_pieces[2]; norm_pieces[2] = h; h = norm_pieces[6]; norm_pieces[6] = norm_pieces[5]; norm_pieces[5] = norm_pieces[4]; norm_pieces[4] = h; } int c = 0; for (int i = 0; c == 0 && i < 7; i++) c = pattern->nr_pieces_per_kind[i] - norm_pieces[i]; if (c < 0) { for (int i = 0; i < 7; i++) pattern->nr_pieces_per_kind[i] = norm_pieces[i]; pattern->nr_sym = 1; } else if (c == 0) pattern->nr_sym++; } /* printf("pat %03d |", nr_pieces); for (int i = 0; i < 7; i++) printf("%3d", best_pieces[i]); //printf(" | %d %d%s\n", nr_sym, depth, inverted ? " INVERTED" : ""); printf(" | %2d\n", nr_sym); */ Pattern **ref_pattern = &patterns; while (*ref_pattern != 0 && (*ref_pattern)->compare(pattern) >= 0) ref_pattern = &(*ref_pattern)->next; pattern->next = *ref_pattern; *ref_pattern = pattern; } return; } int visited_match = inverted ? 2 : 1; for (BelowLine *below = cur->below_lines; below != 0; below = below->next) { if ((below->line->nr_in_group < first->nr_in_group || below->line == first) && (below->line->visited & visited_match) == 0) { below_line_stack[depth] = below; below->line->visited += visited_match; int new_pieces[7]; for (int i = 0; i < 7; i++) new_pieces[i] = pieces[i]; int new_nr_pieces = nr_pieces; int new_mul = mul == 0 ? below->rep : gcd(mul, below->rep); int inv_pieces = inverted ^ (below->i_top < 0); char prev_s; for (char *s = below->pieces; *s != '\0'; s++) { char ch = *s; if (ch == 'b' || ch == 'g') { char next_ch = s[1] != '\0' ? s[1] : *below->pieces; if (ch == 'b' || ch == 'f') new_pieces['d' - 'a']++; } if (inv_pieces) switch (ch) { case 'a': ch = 'c'; break; case 'c': ch = 'a'; break; case 'f': ch = 'g'; break; case 'g': ch = 'f'; break; } if (ch != '-') { new_pieces[ch - 'a']++; new_nr_pieces++; } } search_pattern(first, below->line, inv_pieces ^ (below->i_bottom < 0), depth+1, new_pieces, new_nr_pieces, new_mul); below->line->visited -= visited_match; } } } int main(int argc, char **argv) { buildConnections(); //return 0; fill_lines(10); make_groups(); print_groups(); for (Group *group = groups; group != 0; group = group->next) { if (group->mul == 1) { for (Line *line = group->lines; line != 0; line = line->next_in_group) { int pieces[7]; for (int i = 0; i < 7; i++) pieces[i] = 0; search_pattern(line, line, false, 0, pieces, 0, 0); } } } for (Pattern *pattern = patterns; pattern != 0; pattern = pattern->next) { printf("pat %03d |", pattern->nr_pieces); for (int i = 0; i < 7; i++) printf("%3d", pattern->nr_pieces_per_kind[i]); //printf(" | %d %d%s\n", nr_sym, depth, inverted ? " INVERTED" : ""); printf(" | %2d %s", pattern->nr_sym, pattern->first->line); for (int i = 0; i < pattern->depth; i++) printf(" %s %s", pattern->below_lines[i]->pieces, pattern->below_lines[i]->line->line); printf("\n"); int len_first = strlen(pattern->first->line); for (int i = 0; i < 2*MAX_PIECES; i++) for (int j = 0; j < 12; j++) pattern->neighbours[i][j] = -1; pattern->nr_vertices = 0; int vertices[MAX_LEN+1][MAX_LEN+1]; int nr_vertices[MAX_LEN+1]; for (int d = 0; d < pattern->depth; d++) nr_vertices[d] = 0; for (const char *a = pattern->first->line; *a != '\0'; a++) { vertices[0][pattern->nr_vertices] = pattern->nr_vertices; pattern->nr_vertices++; } nr_vertices[0] = pattern->nr_vertices; debug_pattern = false; int p_i = 0; for (int pass = 1; pass <= 2; pass++) { if (debug_pattern) printf("Pass %d %d\n", pass, pattern->nr_vertices); for (int i = 0; i < pattern->depth; i++) { BelowLine* below_line = pattern->below_lines[i]; //char top[MAX_LEN+1]; //top[0] = '\0'; //char *t = top; //char bottom[MAX_LEN+1]; //bottom[0] = '\0'; //char *b = bottom; int (&top_vertices)[MAX_LEN+1] = vertices[i]; int &nr_top_vertices = nr_vertices[i]; int (&bottom_vertices)[MAX_LEN+1] = vertices[(i+1) % pattern->depth]; int &nr_bottom_vertices = nr_vertices[(i+1) % pattern->depth]; if (pass == 1) { if (i < pattern->depth - 1) { nr_bottom_vertices = strlen(below_line->line->line); if (pass == 1) for (int j = 0; j < nr_bottom_vertices; j++) bottom_vertices[j] = -1; } } if (debug_pattern) printf(" line %d (%d) %s %s (%d)", i, below_line->i_top, below_line->pieces, below_line->line->line, below_line->i_bottom); int top_d = below_line->i_top < 0 ? nr_top_vertices - 1 : 1; int top_i = (top_d == 1 ? nr_top_vertices - below_line->i_top : -1 - below_line->i_top) % nr_top_vertices; //int top_i = (below_line->i_top + (top_d == 1 ? 0 : nr_top_vertices + 1)) % nr_top_vertices; int bottom_d = below_line->i_bottom < 0 ? nr_bottom_vertices - 1 : 1; int bottom_i = (bottom_d == 1 ? nr_bottom_vertices - below_line->i_bottom : -1 - below_line->i_bottom) % nr_bottom_vertices; //int bottom_i = (below_line->i_bottom + (bottom_d == 1 ? 0 : nr_bottom_vertices + 1)) % nr_bottom_vertices; if (debug_pattern) printf(" %d:%d %d:%d\n", top_i, top_d, bottom_i, bottom_d); char prev = below_line->pieces[strlen(below_line->pieces)-1]; int prev_i = KINDINDEX(prev); for (char *s = below_line->pieces; *s != '\0'; s++) { //pattern->piece_types[p_i] = char cur = *s; int cur_i = KINDINDEX(cur); if (debug_pattern) printf(" %c (%d) %c (%d)\n", prev, prev_i, cur, cur_i); //if (cur != '-') // pattern->piece_types[p_i] = cur; Connection &con = connections[prev_i][cur_i]; if (debug_pattern) printf(" top %s bottom %s\n", con.top, con.bottom); //printf(" top_vertices[%d] = %d\n", top_i, top_vertices[top_i]); int top_i_n = (top_i + top_d * strlen(con.top)) % nr_top_vertices; if (debug_pattern) printf(" top_vertices[%d] = %d\n", top_i_n, top_vertices[top_i_n]); for (const char *bl = con.bottom; *bl != '\0'; bl++) { int bottom_i_n = (bottom_i + bottom_d) % nr_bottom_vertices; if (pass == 1) { if (debug_pattern) printf(" %c ", *bl); if (*bl == '1' || *bl == '2' || (*bl == '3' && cur != '-')) { if (debug_pattern) printf("new"); if (bottom_vertices[bottom_i_n] == -1) bottom_vertices[bottom_i_n] = pattern->nr_vertices++; } else { if (debug_pattern) printf("connect"); int top_i_s = *bl == '5' && bl[1] == '2' ? top_i : top_i_n; if (bottom_vertices[bottom_i_n] == -1) bottom_vertices[bottom_i_n] = top_vertices[top_i_s]; else { // Join bottom and top vertices int a = bottom_vertices[bottom_i_n]; int b = top_vertices[top_i_s]; if (b < a) { int h = a; a = b; b = h; } if (debug_pattern) printf(" join %d %d ", a, b); for (int d = 0; d < pattern->depth; d++) for (int v = 0; v < nr_vertices[d]; v++) if (vertices[d][v] == b) vertices[d][v] = a; else if (vertices[d][v] > b) vertices[d][v]--; pattern->nr_vertices--; } } if (debug_pattern) printf(" bottom_vertices[%d] = %d\n", bottom_i_n, bottom_vertices[bottom_i_n]); } else // pass == 2 { if (debug_pattern) printf(" bottom_vertices[%d] = %d\n", bottom_i_n, bottom_vertices[bottom_i_n]); if (debug_pattern) printf(" %c ", *bl); pattern->connect(bottom_vertices[bottom_i], bottom_vertices[bottom_i_n], *bl - '0'); if (*bl == '3' && cur != '-' && cur != 'e') { if (debug_pattern) printf(" d up "); pattern->connect(bottom_vertices[bottom_i], top_vertices[top_i], 5); if (debug_pattern) printf(" d down "); pattern->connect(top_vertices[top_i], bottom_vertices[bottom_i_n], 1); } } top_i = top_i_n; bottom_i = bottom_i_n; } if (pass == 2) { if (cur == 'c' || cur == 'e') { if (debug_pattern) printf("CONNECT %c: ", cur); pattern->connect(top_vertices[top_i], bottom_vertices[bottom_i], 0); } } //strcat(top, con.top); //strcat(bottom, con.bottom); prev = cur; prev_i = cur_i; /* if (pass == 2) for (int v = 0; v < pattern->nr_vertices; v++) { printf("%3d: ", v); for (int d = 0; d < 12; d++) if (pattern->neighbours[v][d] == -1) printf(" .."); else printf("%3d", pattern->neighbours[v][d]); printf("\n"); } for (int v = 0; v < pattern->nr_vertices; v++) { for (int d = 0; d < 12; d++) if (v < pattern->neighbours[v][d]) printf("%3d - %3d: %2d\n", v, pattern->neighbours[v][d], d); } */ } //char top_opt[MAX_LEN+1]; //shift(top, below_line->i_top, top_opt); //char bottom_opt[MAX_LEN+1]; //shift(bottom, below_line->i_bottom, bottom_opt); //printf("%s %s (%d:%s) %s (%d:%s)\n", below_line->pieces, top, below_line->i_top, top_opt, bottom, below_line->i_bottom, bottom_opt); } } if (debug_pattern) { for (int v = 0; v < pattern->nr_vertices; v++) { printf("%3d: ", v); for (int d = 0; d < 12; d++) if (pattern->neighbours[v][d] == -1) printf(" .."); else printf("%3d", pattern->neighbours[v][d]); printf("\n"); } for (int v = 0; v < pattern->nr_vertices; v++) { for (int d = 0; d < 12; d++) if (v < pattern->neighbours[v][d]) printf("%3d - %3d: %2d\n", v, pattern->neighbours[v][d], d); } } bool pattern_unique = true; for (Pattern *pattern2 = patterns; pattern2 != pattern && pattern_unique; pattern2 = pattern2->next) if ( pattern2->nr_pieces == pattern->nr_pieces && pattern2->nr_vertices == pattern->nr_vertices) { bool equal = true; for (int i = 0; i < 7 && equal; i++) equal = pattern2->nr_pieces_per_kind[i] == pattern->nr_pieces_per_kind[i]; if (equal) { int nr_matchings = 0; int nr_v = pattern->nr_vertices; for (int v = 0; v < nr_v; v++) for (int o = 0; o < 12; o++) for (int d = -1; d <= 1; d += 2) { int matching[MAX_LEN]; for (int v2 = 0; v2 < nr_v; v2++) matching[v2] = -1; bool correct = true; matching[0] = v; for (int o2 = 0; o2 < 12 && correct; o2++) { int v1 = pattern->neighbours[0][o2]; int v2 = pattern2->neighbours[v][(12 + o + d * o2) % 12]; if (v1 == -1) correct = v2 == -1; else if (v2 == -1) correct = false; else { if (matching[v1] == -1) matching[v1] = v2; else correct = matching[v1] == v2; } } bool change = true; while (change && correct) { change = false; for (int v3 = 0; v3 < nr_v; v3++) { int v4 = matching[v3]; if (v4 != -1) { for (int o2 = 0; o2 < 12 && correct; o2++) { int v1 = pattern->neighbours[v3][o2]; int v2 = pattern2->neighbours[v4][(12 + o + d * o2) % 12]; if (v1 == -1) correct = v2 == -1; else if (v2 == -1) correct = false; else { if (matching[v1] == -1) { matching[v1] = v2; change = true; } else correct = matching[v1] == v2; } } } } } if (correct) nr_matchings++; } if (nr_matchings > 0) { pattern_unique = false; printf("NOT UNIQUE: %d matchings with: %2d %s", nr_matchings, pattern2->nr_sym, pattern2->first->line); for (int i = 0; i < pattern2->depth; i++) printf(" %s %s", pattern2->below_lines[i]->pieces, pattern2->below_lines[i]->line->line); printf("\n"); } } } if (pattern_unique) printf("UNIQUE\n"); } return 0; }