Advertisement
Guest User

2gensq1

a guest
Aug 28th, 2014
318
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.69 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <ctime>
  4. #include <cstdlib>
  5. #include <sstream>
  6. using namespace std;
  7.  
  8. int size;
  9. bool useMiddle=0;
  10. unsigned char *states;
  11. string filename;
  12.  
  13. struct puzzle{
  14.     unsigned char pieces[18];
  15.     unsigned char pieces2[12];
  16.     bool middleFlipped;
  17.  
  18.     puzzle(){
  19.         pieces[0]=1;
  20.         pieces[1]=1;
  21.         pieces[2]=2;
  22.         pieces[3]=3;
  23.         pieces[4]=3;
  24.         pieces[5]=4;
  25.         pieces[6]=5;
  26.         pieces[7]=5;
  27.         pieces[8]=6;
  28.         pieces[9]=7;
  29.         pieces[10]=7;
  30.         pieces[11]=8;
  31.         pieces[12]=9;
  32.         pieces[13]=10;
  33.         pieces[14]=10;
  34.         pieces[15]=11;
  35.         pieces[16]=12;
  36.         pieces[17]=12;
  37.         middleFlipped = 0;
  38.     }
  39.  
  40.     void stringToPos(string str){
  41.         for(int aa=0; aa<12; aa++){
  42.             pieces2[aa]=str.at(aa)-'a'+1;
  43.         }
  44.  
  45.         int extra=0;
  46.         for(int aa=0; aa<12; aa++){
  47.             pieces[aa+extra]=pieces2[aa];
  48.             if(pieces2[aa]==1||pieces2[aa]==3||pieces2[aa]==5||pieces2[aa]==7||pieces2[aa]==10||pieces2[aa]==12){
  49.                 pieces[aa+extra+1]=pieces2[aa];
  50.                 extra++;
  51.             }
  52.         }
  53.  
  54.         if(str.length()==13) middleFlipped = str.at(12)-'0';
  55.         else middleFlipped=0;
  56.     }
  57.  
  58.     int posToInt(){
  59.         int extra=0;
  60.         for(int aa=0; aa<17; aa++){
  61.             pieces2[aa-extra]=pieces[aa];
  62.             if(pieces[aa]==pieces[aa+1]) extra++;
  63.         }
  64.         pieces2[11]=pieces[17];
  65.         int t = 0;
  66.         for(int i=0; i<12; i++){
  67.             t*=(12-i);
  68.             for(int j=i+1; j<12; j++){
  69.                 if(pieces2[i] > pieces2[j]) t++;
  70.             }
  71.         }
  72.         return ((middleFlipped&&useMiddle)?(t+479001600):t);
  73.     }
  74.  
  75.     void intToPos(int t){
  76.         middleFlipped=t/479001600;
  77.         pieces2[11]=1;
  78.         for(int i=11; i>=1; i--){
  79.             pieces2[i-1] = 1+(t%(13-i));
  80.             t/=(13-i);
  81.             for(int j=i+1; j<=12; j++){
  82.                 if(pieces2[j-1] >= pieces2[i-1]) pieces2[j-1]++;
  83.             }
  84.         }
  85.         int extra=0;
  86.         for(int aa=0; aa<12; aa++){
  87.             pieces[aa+extra]=pieces2[aa];
  88.             if(pieces2[aa]==1||pieces2[aa]==3||pieces2[aa]==5||pieces2[aa]==7||pieces2[aa]==10||pieces2[aa]==12){
  89.                 pieces[aa+extra+1]=pieces2[aa];
  90.                 extra++;
  91.             }
  92.         }
  93.     }
  94.  
  95.     void doMove(){
  96.         unsigned char temp = pieces[11];
  97.         for(int aa=11; aa>0; aa--) pieces[aa] = pieces[aa-1];
  98.         pieces[0] = temp;
  99.     }
  100.  
  101.     bool canDoSlice(){
  102.         return !(pieces[0]==pieces[11]||pieces[5]==pieces[6]);
  103.     }
  104.  
  105.     void doSlice(){
  106.         unsigned char temp;
  107.         for(int aa=0; aa<6; aa++){
  108.             temp = pieces[6+aa];
  109.             pieces[6+aa] = pieces[12+aa];
  110.             pieces[12+aa] = temp;
  111.         }
  112.         middleFlipped=(!middleFlipped);
  113.     }
  114. };
  115.  
  116. void getSolution(puzzle p, string sol){
  117.     int d = states[p.posToInt()];
  118.     if(d==0){
  119.         cout<<sol<<"\n";
  120.         return;
  121.     }
  122.  
  123.     stringstream stream;
  124.     int m;
  125.  
  126.     for(int aa=0; aa<12; aa++){
  127.         p.doMove();
  128.         if(!p.canDoSlice()) continue;
  129.         if(states[p.posToInt()]==d-1){
  130.             stream.str("");
  131.             m=(aa+1)%12;
  132.             if(m>6) m-=12;
  133.             stream<<m;
  134.             getSolution(p, sol+stream.str());
  135.         }
  136.     }
  137.     p.doSlice();
  138.     if(states[p.posToInt()]==d-1) getSolution(p, sol+"/");
  139. }
  140.  
  141. bool goodInput(string input){
  142.     if(input.length() != 12 && input.length() != 13) return false;
  143.     if(input.length() == 13) if(input.at(12) != '1') return false;
  144.     bool chars[12]={1,1,1,1,1,1,1,1,1,1,1,1};
  145.     for(int aa=0; aa<12; aa++){
  146.         if(input.at(aa)-'a'>11 || input.at(aa)-'a'<0) return false;
  147.         if(chars[input.at(aa)-'a']!=0) chars[input.at(aa)-'a']=0;
  148.         else return false;
  149.     }
  150.     for(int aa=0; aa<12; aa++) if(chars[aa]) return false;
  151.     return true;
  152. }
  153.  
  154. int main(){
  155.     puzzle p = puzzle();
  156.  
  157.     char m;
  158.     cout<<"Include middle layer? (y/n) ";
  159.     cin>>m;
  160.     if(m=='y') useMiddle=true;
  161.     else if(m=='n') useMiddle=false;
  162.     else exit(-1);
  163.  
  164.     if(useMiddle){
  165.         filename="sq1_2gen_middle.table";
  166.         size=958003200;
  167.         cout<<"Loading solver (with middle layer).\n";
  168.     }
  169.     else{
  170.         filename="sq1_2gen.table";
  171.         size=479001600;
  172.         cout<<"Loading solver (ignoring middle layer).\n";
  173.     }
  174.  
  175.     int depth = 0;
  176.     int newPositions;
  177.     int totalPositions = 1;
  178.     int index;
  179.  
  180.     states = new unsigned char[size];
  181.     ifstream file(filename.c_str(), ios_base::binary);
  182.     if(!file.fail()){
  183.         cout<<"Table found on file.\n\n";
  184.         char b;
  185.         for(int aa=0; aa<size; aa++){
  186.             file.read(&b, 1);
  187.             states[aa]=b;
  188.         }
  189.         file.close();
  190.     }
  191.     else{
  192.         for(int aa=0; aa<size; aa++) states[aa]=255;
  193.         cout<<"depth\tpositions\n0\t1\n";
  194.         states[p.posToInt()]=0;
  195.         do{
  196.             newPositions = 0;
  197.             for(int aa=0; aa<size; aa++){
  198.                 if(states[aa]!=depth) continue;
  199.                 p.intToPos(aa);
  200.                 if(!p.canDoSlice()) continue;
  201.                 for(int ab=0; ab<11; ab++){
  202.                     p.doMove();
  203.                     if(!p.canDoSlice()) continue;
  204.                     index = p.posToInt();
  205.                     if(states[index]==255){
  206.                         states[index]=depth+1;
  207.                         newPositions++;
  208.                     }
  209.                 }
  210.                 p.doMove();
  211.                 p.doSlice();
  212.                 index = p.posToInt();
  213.                 if(states[index]==255){
  214.                     states[index]=depth+1;
  215.                     newPositions++;
  216.                 }
  217.             }
  218.             depth++;
  219.             totalPositions+=newPositions;
  220.             cout << depth << "\t" << newPositions << "\n";
  221.         }
  222.         while(newPositions != 0);
  223.         cout<<totalPositions<<" positions\n\n";
  224.  
  225.         ofstream table(filename.c_str(), ios_base::binary);
  226.         for(int aa=0; aa<size; aa++) table<<states[aa];
  227.         table.close();
  228.     }
  229.  
  230.     string input;
  231.     bool c;
  232.     while(1){
  233.         c=false;
  234.         cout<<"Position: ";
  235.         cin>>input;
  236.         if(!goodInput(input)){
  237.             cout<<"Bad input.\n\n";
  238.             continue;
  239.         }
  240.  
  241.         p.stringToPos(input);
  242.         index=p.posToInt();
  243.         if(states[index] == 255){
  244.             cout<<"Bad input.\n\n";
  245.             continue;
  246.         }
  247.  
  248.         cout<<"\nPosition is at depth "<<(int)states[p.posToInt()]<<"\n";
  249.         cout<<"Optimal solutions:\n";
  250.         getSolution(p, "");
  251.         cout<<"\n";
  252.     }
  253.  
  254.     return 0;
  255. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement