/* Swimming Jellyfish Copyright (C) 2016 Frans Faase This program is used to analyze a Jellyfish swimming GIF. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. GNU General Public License: http://www.iwriteiam.nl/GNU.txt Details: http://www.iwriteiam.nl/D1606.html#26 */ #include char gifs[3][31][32] = { { " > > > > > > > > > > > > > > ", "^ v ^ v", " < < < < < < < < < < ", "^ v ^ v ^ v ^ v ", " > > > > > > > > ", "^ v ^ v ^ v ^ v", " < < < < < < < ", "^ v ^ v ^ v ^ v ^ v", " > > > > > > ", "^ v ^ v ^ v ^ v ^ v", " < < < < < < < < ", " ^ v ^ v ^ v", " > > > > > > > > > > ", "^ v ^ v ^ v", " < < < < < < < < < ", "^ v ^ v ^ v ^ v", " > > > > > > > ", "^ v ^ v ^ v ^ v ^ v", " < < < < < < ", " ^ v ^ v ^ v ^ v ^ v", " > > > > > > ", "^ v ^ v ^ v ^ v ^ v", " < < < < < < < < ", "^ v ^ v ^ v ", " > > > > > > > > > > ", "^ v ^ v ^ v", " < < < < < < < < < ", "^ v ^ v ^ v ^ v", " > > > > > > > > > > ", "^ v ^ v", " < < < < < < < < < < < < < < " }, { " > > > > > > > > > > > > > ", "| | | | | |", " < < < < < < < < ", "| | | | | | | | | |", " > > > > > > ", "| | | | | | | | | |", " < < < < < ", "| | | | | | | | | | | |", " > > > > > > ", "| | | | | | | |", " < < < < < < < < < < ", "| | | | ", " > > > > > > > > > > ", "| | | | | | | |", " < < < < < < < ", " | | | | | | | | | |", " > > > > > > > ", "| | | | | | | |", " < < < < < < < < < < ", "| | | | ", " > > > > > > > > > > > ", "| | | | | |", " < < < < < < < < < ", "| | | | | | | |", " > > > > > > > > ", "| | | | | | | |", " < < < < < < < < ", " | | | | | | | |", " > > > > > > > > > > ", "| | | |", " < < < < < < < < < < < < < < " }, { " > > > > > > > > > > > > > ", "| | | | | |", " < < < < < < < ", "| | | | | | | | | | | |", " > > > > > > ", "| | | | | | | |", " < < < < < < < < < ", " | | | | | |", " > > > > > > > > > ", "| | | | | | | |", " < < < < < < < < < ", "| | | | | | ", " > > > > > > > > > ", "| | | | | | | |", " < < < < < < < ", "| | | | | | | | | |", " > > > > > > > ", "| | | | | | | |", " < < < < < < < < < ", " | | | | | | ", " > > > > > > > > > > ", "| | | | | |", " < < < < < < < < < < ", "| | | | | |", " > > > > > > > > ", "| | | | | | | | | |", " < < < ", "| | | | | | | | | | | | | | | |", " > > > ", "| | | | | | | | | |", " < < < < < < < < < < < " }}; char at(int g, int i, int j) { if (i < 0 || i > 30 || j < 0 || j > 30) return ' '; return gifs[g][i][j]; } int gcd(int a, int b) { while (a != b) if (a < b) b -= a; else a -= b; return a; } int main(int argc, char *argv[]) { // Check input for (int g = 0; g < 3; g++) { for (int i = 0; i < 32; i += 2) for (int j = 0; j < 32; j += 2) { char u = at(g, i-1, j); char d = at(g, i+1, j); char l = at(g, i, j-1); char r = at(g, i, j+1); int c = 0; if (u != ' ') c++; if (d != ' ') c++; if (l != ' ') c++; if (r != ' ') c++; if (c != 2) { printf("Error at %d: %d,%d c = %d (%c%c%c%c)\n", g, i, j, c, u, d, l, r); return 1; } if (d == '|') { if (u == 'v' || l == '>' || r == '<') gifs[g][i+1][j] = 'v'; if (u == '^' || l == '<' || r == '>') gifs[g][i+1][j] = '^'; d = at(g, i+1, j); } int in = 0; if (u == 'v') in++; if (d == '^') in++; if (l == '>') in++; if (r == '<') in++; if (in != 1) { printf("Error at %d: %d,%d in = %d (%c%c%c%c)\n", g, i, j, in, u, d, l, r); return 1; } int out = 0; if (u == '^') out++; if (d == 'v') out++; if (l == '<') out++; if (r == '>') out++; if (out != 1) { printf("Error at %d: %d,%d out = %d (%c%c%c%c)\n", g, i, j, out, u, d, l, r); return 1; } } } int fish[16][16]; int nr = 0; for (int i = 0; i < 16; i++) for (int j = 0; j < 16; j++) fish[i][j] = nr++; int cycle_length[16][16]; int lowest[16][16]; for (int i = 0; i < 16; i++) for (int j = 0; j < 16; j++) { cycle_length[i][j] = -1; lowest[i][j] = 16*16; } int count = 0; int count_bottom_top = 0; int max_nr_bottom_top = 0; int g = 0; for (;;) { count++; int next_fish[16][16]; int nr_equal = 0; int nr = 0; int nr_bottom_top = 0; for (int i = 0; i < 16; i++) for (int j = 0; j < 16; j++) { char u = at(g, 2*i-1, 2*j); char d = at(g, 2*i+1, 2*j); char l = at(g, 2*i, 2*j-1); char r = at(g, 2*i, 2*j+1); if (u == 'v') next_fish[i][j] = fish[i-1][j]; else if (d == '^') next_fish[i][j] = fish[i+1][j]; else if (l == '>') next_fish[i][j] = fish[i][j-1]; else if (r == '<') next_fish[i][j] = fish[i][j+1]; else { printf("Error %d: %d,%d (%c%c%c%c)\n", g, i, j, u, d, l, r); return 1; } if (next_fish[i][j] == nr++) { nr_equal++; if (count % 3 == 0 && cycle_length[i][j] == -1) cycle_length[i][j] = count; } if (i == 0 && next_fish[i][j] >= 15*16) nr_bottom_top++; if (count % 3 == 0 && next_fish[i][j] < lowest[i][j]) lowest[i][j] = next_fish[i][j]; } for (int i = 0; i < 16; i++) for (int j = 0; j < 16; j++) fish[i][j] = next_fish[i][j]; g = (g+1)%3; if (nr_equal == 16*16) break; if (nr_bottom_top > 0) count_bottom_top++; if (nr_bottom_top > max_nr_bottom_top) { max_nr_bottom_top = nr_bottom_top; printf("After %d swims there are %d from the bottom on the top:\n", count, max_nr_bottom_top); for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) printf(" %02X", fish[i][j]); printf("\n"); } printf("\n"); } } printf("count = %d, bottom at the top = %d\n", count, count_bottom_top); printf("\n"); for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) printf("%5d", cycle_length[i][j]); printf("\n"); } printf("\n"); nr = 0; char letter[256]; char ch = 'a'; int sum = 0; int lcm = 1; for (int i = 0; i < 16; i++) for (int j = 0; j < 16; j++, nr++) if (lowest[i][j] == nr) { printf("%d : %d\n", nr, cycle_length[i][j]); sum += cycle_length[i][j]; lcm *= cycle_length[i][j] / gcd(lcm, cycle_length[i][j]); letter[lowest[i][j]] = ch++; } printf("\n\nsum = %d, sum/3 = %d, lcm = %d\n", sum, sum/3, lcm); printf("\n"); for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) printf(" %c", letter[lowest[i][j]]); printf("\n"); } return 0; }