#include #include #include #include struct permutation { int p[12]; }; static bool permutations_equal(struct permutation a, struct permutation b) { return memcmp(a.p, b.p, sizeof(a.p)) == 0; } static struct permutation compose(struct permutation a, struct permutation b) { struct permutation p; for (int i = 0; i < 12; ++i) p.p[i] = a.p[b.p[i]]; return p; } static uint16_t apply(struct permutation p, uint16_t v) { uint16_t r = 0; for (int i = 0; i < 12; ++i) { if (v & (1 << i)) r |= 1 << p.p[i]; } return r; } static const struct permutation I = { .p = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 } }; // identity static const struct permutation F = { .p = { 0, 4, 1, 2, 7, 8, 5, 3, 11, 9, 6, 10 } }; // rotation around a face (order 5) static const struct permutation V = { .p = { 2, 0, 1, 5, 3, 4, 8, 6, 7, 11, 9, 10 } }; // rotation around a vertex (order 3) static const uint16_t visible_faces = 0x9f; // looking out from face 0, faces 0, 1, 2, 3, 4, and 7 are visible static int compare_uint16(const void *a, const void *b) { return (int)(*(const uint16_t *)b) - (int)(*(const uint16_t *)a); } static void insert_permutation(struct permutation *a, int *length, struct permutation p) { for (int i = 0; i < *length; ++i) { if (permutations_equal(p, a[i])) return; } a[(*length)++] = p; } int main() { struct permutation rotations[60] = { I }; int cursor = 0; int length = 1; while (cursor < length) { struct permutation p = rotations[cursor++]; insert_permutation(rotations, &length, compose(F, p)); insert_permutation(rotations, &length, compose(V, p)); } uint16_t permuted_colors[60]; for (uint16_t i = 0; i < (1 << 12); ++i) { for (int j = 0; j < 60; ++j) permuted_colors[j] = apply(rotations[j], i) & visible_faces; qsort(permuted_colors, 60, sizeof(uint16_t), compare_uint16); bool unique = true; for (int j = 1; j < 60 && unique; ++j) { if (permuted_colors[j] == permuted_colors[j - 1]) unique = false; } if (unique) printf("%x\n", i); } }