Created
November 28, 2023 15:42
-
-
Save kusano/2edc77b79c1ba782add1a0203ef29661 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <cstdint> | |
| #include <string> | |
| #include <vector> | |
| #include <unordered_map> | |
| #include <unordered_set> | |
| #include <algorithm> | |
| #include <functional> | |
| using namespace std; | |
| // x1 <- x2 <- x3 <- x4 <- x1 | |
| void rotate(uint8_t &x1, uint8_t &x2, uint8_t &x3, uint8_t &x4) | |
| { | |
| uint8_t t = x1; | |
| x1 = x2; | |
| x2 = x3; | |
| x3 = x4; | |
| x4 = t; | |
| } | |
| struct Cube | |
| { | |
| vector<uint8_t> EO, EP; | |
| Cube() | |
| { | |
| EO = vector<uint8_t>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | |
| EP = vector<uint8_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; | |
| } | |
| void move(int m) | |
| { | |
| switch (m) | |
| { | |
| case 0: // U | |
| rotate(EO[0], EO[3], EO[2], EO[1]); | |
| rotate(EP[0], EP[3], EP[2], EP[1]); | |
| break; | |
| case 1: // U2 | |
| swap(EO[0], EO[2]), swap(EO[3], EO[1]); | |
| swap(EP[0], EP[2]), swap(EP[3], EP[1]); | |
| break; | |
| case 2: // U' | |
| rotate(EO[0], EO[1], EO[2], EO[3]); | |
| rotate(EP[0], EP[1], EP[2], EP[3]); | |
| break; | |
| case 3: // R | |
| rotate(EO[1], EO[6], EO[9], EO[5]); | |
| rotate(EP[1], EP[6], EP[9], EP[5]); | |
| break; | |
| case 4: // R2 | |
| swap(EO[1], EO[9]), swap(EO[6], EO[5]); | |
| swap(EP[1], EP[9]), swap(EP[6], EP[5]); | |
| break; | |
| case 5: // R' | |
| rotate(EO[1], EO[5], EO[9], EO[6]); | |
| rotate(EP[1], EP[5], EP[9], EP[6]); | |
| break; | |
| case 6: // F | |
| rotate(EO[2], EO[7], EO[10], EO[6]); | |
| rotate(EP[2], EP[7], EP[10], EP[6]); | |
| EO[2] ^= 1; | |
| EO[7] ^= 1; | |
| EO[10] ^= 1; | |
| EO[6] ^= 1; | |
| break; | |
| case 7: // F2 | |
| swap(EO[2], EO[10]), swap(EO[7], EO[6]); | |
| swap(EP[2], EP[10]), swap(EP[7], EP[6]); | |
| break; | |
| case 8: // F' | |
| rotate(EO[2], EO[6], EO[10], EO[7]); | |
| rotate(EP[2], EP[6], EP[10], EP[7]); | |
| EO[2] ^= 1; | |
| EO[6] ^= 1; | |
| EO[10] ^= 1; | |
| EO[7] ^= 1; | |
| break; | |
| case 9: // D | |
| rotate(EO[8], EO[9], EO[10], EO[11]); | |
| rotate(EP[8], EP[9], EP[10], EP[11]); | |
| break; | |
| case 10: // D2 | |
| swap(EO[8], EO[10]), swap(EO[9], EO[11]); | |
| swap(EP[8], EP[10]), swap(EP[9], EP[11]); | |
| break; | |
| case 11: // D' | |
| rotate(EO[8], EO[11], EO[10], EO[9]); | |
| rotate(EP[8], EP[11], EP[10], EP[9]); | |
| break; | |
| case 12: // L | |
| rotate(EO[3], EO[4], EO[11], EO[7]); | |
| rotate(EP[3], EP[4], EP[11], EP[7]); | |
| break; | |
| case 13: // L2 | |
| swap(EO[3], EO[11]), swap(EO[4], EO[7]); | |
| swap(EP[3], EP[11]), swap(EP[4], EP[7]); | |
| break; | |
| case 14: // L' | |
| rotate(EO[3], EO[7], EO[11], EO[4]); | |
| rotate(EP[3], EP[7], EP[11], EP[4]); | |
| break; | |
| case 15: // B | |
| rotate(EO[0], EO[5], EO[8], EO[4]); | |
| rotate(EP[0], EP[5], EP[8], EP[4]); | |
| EO[0] ^= 1; | |
| EO[5] ^= 1; | |
| EO[8] ^= 1; | |
| EO[4] ^= 1; | |
| break; | |
| case 16: // B2 | |
| swap(EO[0], EO[8]), swap(EO[5], EO[4]); | |
| swap(EP[0], EP[8]), swap(EP[5], EP[4]); | |
| break; | |
| case 17: // B' | |
| rotate(EO[0], EO[4], EO[8], EO[5]); | |
| rotate(EP[0], EP[4], EP[8], EP[5]); | |
| EO[0] ^= 1; | |
| EO[4] ^= 1; | |
| EO[8] ^= 1; | |
| EO[5] ^= 1; | |
| break; | |
| } | |
| } | |
| uint64_t compress() const | |
| { | |
| uint64_t c = 0; | |
| for (int i=0; i<12; i++) | |
| { | |
| c *= 12; | |
| c += EP[i]; | |
| c *= 2; | |
| c += EO[i]; | |
| } | |
| return c; | |
| } | |
| void decompress(uint64_t c) | |
| { | |
| for (int i=11; i>=0; i--) | |
| { | |
| EO[i] = c%2; | |
| c /= 2; | |
| EP[i] = c%12; | |
| c /= 12; | |
| } | |
| } | |
| string str() const | |
| { | |
| vector<string> E = {"UB", "UR", "UF", "UL", "BL", "BR", "FR", "FL", "DB", "DR", "DF", "DL"}; | |
| auto e = [&](int p, int o) -> char | |
| { | |
| return E[EP[p]][(2-EO[p]+o)%2]; | |
| }; | |
| auto c = [&](int p, int o) -> char | |
| { | |
| return '.'; | |
| }; | |
| string res = string() + | |
| ' ' + ' ' + ' ' + c( 0, 0) + e( 0, 0) + c( 1, 0) + '\n' + | |
| ' ' + ' ' + ' ' + e( 3, 0) + 'U' + e( 1, 0) + '\n' + | |
| ' ' + ' ' + ' ' + c( 3, 0) + e( 2, 0) + c( 2, 0) + '\n' + | |
| c( 0, 1) + e( 3, 1) + c( 3, 2) + c( 3, 1) + e( 2, 1) + c( 2, 2) + c( 2, 1) + e( 1, 1) + c( 1, 2) + c( 1, 1) + e( 0, 1) + c( 0, 2) + '\n' + | |
| e( 4, 1) + 'L' + e( 7, 1) + e( 7, 0) + 'F' + e( 6, 0) + e( 6, 1) + 'R' + e( 5, 1) + e( 5, 0) + 'B' + e( 4, 0) + '\n' + | |
| c( 4, 2) + e(11, 1) + c( 7, 1) + c( 7, 2) + e(10, 1) + c( 6, 1) + c( 6, 2) + e( 9, 1) + c( 5, 1) + c( 5, 2) + e( 8, 1) + c( 4, 1) + '\n' + | |
| ' ' + ' ' + ' ' + c( 7, 0) + e(10, 0) + c( 6, 0) + '\n' + | |
| ' ' + ' ' + ' ' + e(11, 0) + 'D' + e( 9, 0) + '\n' + | |
| ' ' + ' ' + ' ' + c( 4, 0) + e( 8, 0) + c( 5, 0) + '\n'; | |
| string colored; | |
| for (char c: res) | |
| switch (c) | |
| { | |
| case 'U': colored += "\x1b[47mU \x1b[0m"; break; | |
| case 'D': colored += "\x1b[43mD \x1b[0m"; break; | |
| case 'L': colored += "\x1b[45mL \x1b[0m"; break; | |
| case 'R': colored += "\x1b[41mR \x1b[0m"; break; | |
| case 'F': colored += "\x1b[42mF \x1b[0m"; break; | |
| case 'B': colored += "\x1b[44mB \x1b[0m"; break; | |
| case '.': colored += ".."; break; | |
| case ' ': colored += " "; break; | |
| case '\n': colored += "\n"; break; | |
| default: | |
| colored += "ERROR"; | |
| } | |
| return colored; | |
| } | |
| }; | |
| int main() | |
| { | |
| unordered_map<uint64_t, int> T; | |
| Cube cube; | |
| T[cube.compress()] = 0; | |
| const int N = 8; | |
| for (int i=0; i<N; i++) | |
| { | |
| unordered_set<uint64_t> S; | |
| for (auto it: T) | |
| if (it.second==i) | |
| { | |
| cube.decompress(it.first); | |
| for (int m=0; m<18; m++) | |
| if (m!=6 && m!=8 && m!=15 && m!=17) | |
| { | |
| cube.move(m); | |
| uint64_t c = cube.compress(); | |
| if (T.count(c)==0) | |
| S.insert(c); | |
| cube.move(m/3*3+2-m%3); | |
| } | |
| } | |
| for (uint64_t c: S) | |
| T[c] = i+1; | |
| cout<<i+1<<": "<<S.size()<<endl; | |
| } | |
| vector<int> C(21); | |
| int c = 0; | |
| vector<uint8_t> ep; | |
| for (int i=0; i<12; i++) | |
| ep.push_back(i); | |
| do | |
| { | |
| if (c%1000000==0) | |
| cout<<c<<"/"<<479001600<<endl; | |
| c++; | |
| cube.EP = ep; | |
| for (int md=0; ; md++) | |
| { | |
| function<int(int)> f = [&](int d) | |
| { | |
| if (T.count(cube.compress())>0) | |
| return d+T[cube.compress()]; | |
| if (d>=md) | |
| return -1; | |
| for (int m=0; m<18; m++) | |
| { | |
| cube.move(m); | |
| int t = f(d+1); | |
| cube.move(m/3*3+2-m%3); | |
| if (t>=0) | |
| return t; | |
| } | |
| return -1; | |
| }; | |
| int t = f(0); | |
| if (t>=0) | |
| { | |
| C[t]++; | |
| break; | |
| } | |
| } | |
| } | |
| while (next_permutation(ep.begin(), ep.end())); | |
| for (int i=0; i<=20; i++) | |
| if (C[i]>0) | |
| cout<<i<<": "<<C[i]<<endl; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment