Guest User

Untitled

a guest
Dec 20th, 2020
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.71 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <algorithm>
  5. #include <regex>
  6. #include <fstream>
  7. #include <map>
  8. #include <queue>
  9. #include <chrono>
  10. using namespace std;
  11. using namespace std::chrono;
  12.  
  13. struct Tile
  14. {
  15.     Tile(const vector<string> & tileInput)
  16.     {
  17.         regex idrx("Tile (\\d+)\\:");
  18.         smatch match;
  19.         regex_match(tileInput.front(), match, idrx);
  20.         id = stoull(match[1].str().data());
  21.         copy(tileInput.begin() + 1, tileInput.end(),  std::back_inserter(orig));
  22.         rows = orig;
  23.     }
  24.  
  25.     void setConfig(int i) {
  26.         rows = orig;
  27.         switch(i) {
  28.         case 0 : flipHorizontal(); flipVertical(); break;
  29.         case 1 : flipHorizontal(); rotate(); break;
  30.         case 2 : flipVertical(); rotate(); break;
  31.         case 3 : rotate(); break;
  32.         case 4 : flipHorizontal(); break;
  33.         case 5 : flipVertical(); break;
  34.         case 6 : break;
  35.         case 7 : flipHorizontal(); flipVertical(); rotate(); break;
  36.         default : cout << "bad config requested"; break;
  37.         }
  38.     }
  39.  
  40.     string left() const
  41.     {
  42.         string s;
  43.         for (auto line : rows) s += line.front();
  44.         return s;
  45.     }
  46.  
  47.     string right() const
  48.     {
  49.         string s;
  50.         for (auto line : rows) s += line.back();
  51.         return s;
  52.     }
  53.  
  54.     string top() const
  55.     {
  56.         return rows.front();
  57.     }
  58.  
  59.     string bottom() const
  60.     {
  61.         return rows.back();
  62.     }
  63.  
  64.     void flipHorizontal()
  65.     {
  66.         for (auto & edge : rows) reverse(edge.begin(), edge.end());
  67.     }
  68.  
  69.     void flipVertical()
  70.     {
  71.         reverse(rows.begin(), rows.end());
  72.     }
  73.  
  74.     void rotate()
  75.     {
  76.         for (size_t n = 0; n < rows.size()-1; ++n) {
  77.             for (size_t m = n + 1; m < rows.size(); ++m)
  78.                 swap(rows[n][m], rows[m][n]);
  79.             reverse(rows[n].begin(), rows[n].end());
  80.         }
  81.         reverse(rows.back().begin(), rows.back().end());
  82.     }
  83.  
  84.     string toString() const
  85.     {
  86.         string s;
  87.         for (auto line : rows) s += line + "\n";
  88.         return s;
  89.     }
  90.  
  91.     size_t id;
  92.     vector<string> rows;
  93.     vector<string> orig;
  94.     Tile * south{nullptr};
  95.     Tile * east{nullptr};
  96. };
  97.  
  98. int main()
  99. {
  100.     auto start = high_resolution_clock::now();
  101.  
  102.     string line;
  103.     vector<string> lines;
  104.     vector<Tile> tiles;
  105.     ifstream file("C://Users//micha//Documents//ac//input20.txt");
  106.     while (getline(file, line)) {
  107.         if (line.size() == 0 && lines.size() > 0) {
  108.             tiles.push_back({lines});
  109.             lines.clear();
  110.         } else {
  111.             lines.push_back(line);
  112.         }
  113.     }
  114.     if (lines.size() > 0) tiles.push_back({lines});
  115.  
  116.     queue<Tile*> tileQ;
  117.     map<size_t, int> goodIds;
  118.     goodIds[tiles[0].id] = 0;
  119.     tileQ.push(&tiles[0]);
  120.     map<int, int> right, left, up, down;
  121.  
  122.     while (tileQ.size() > 0) {
  123.  
  124.         Tile * target = tileQ.front();
  125.         target->setConfig(goodIds[target->id]);
  126.  
  127.         for (size_t i = 0; i < tiles.size(); ++i) {
  128.             if (goodIds.find(tiles[i].id) != goodIds.end()) continue;
  129.             for (int j = 0; j<8; ++j) {
  130.                 tiles[i].setConfig(j);
  131.                 if (target->right() == tiles[i].left()) {
  132.                     goodIds[tiles[i].id] = j;
  133.                     tileQ.push(&tiles[i]);
  134.                 } else if (target->left() == tiles[i].right()) {
  135.                     goodIds[tiles[i].id] = j;
  136.                     tileQ.push(&tiles[i]);
  137.                 } else if (target->top() == tiles[i].bottom()) {
  138.                     goodIds[tiles[i].id] = j;
  139.                     tileQ.push(&tiles[i]);
  140.                 } else if (target->bottom() == tiles[i].top()) {
  141.                     tileQ.push(&tiles[i]);
  142.                     goodIds[tiles[i].id] = j;
  143.                 }
  144.             }
  145.         }
  146.         tileQ.pop();
  147.     }
  148.  
  149.     ///////////////
  150.     /// PART ONE //
  151.     ///////////////
  152.  
  153.     Tile * leftTile = nullptr;
  154.     size_t result = 1;
  155.     for (Tile & tile1 : tiles) {
  156.         int connections = 0;
  157.         for (Tile & tile2 : tiles) {
  158.             if (&tile1 != &tile2) {
  159.                 if (tile1.left() == tile2.right()) {++connections; tile2.east = &tile1;}
  160.                 if (tile1.top() == tile2.bottom()) {++connections; tile2.south = &tile1;}
  161.                 if (tile1.right() == tile2.left()) {++connections; tile1.east = &tile2;}
  162.                 if (tile1.bottom() == tile2.top()) {++connections; tile1.south = &tile2;}
  163.             }
  164.         }
  165.         if (connections == 2) {
  166.             result *= tile1.id;
  167.             if (tile1.east && tile1.south) leftTile = &tile1;
  168.         }
  169.     }
  170.     cout << "part one: " << result << endl;
  171.  
  172.  
  173.     ///////////////
  174.     /// PART TWO //
  175.     ///////////////
  176.  
  177.     vector<string> photo = {"Tile 0000:"};
  178.     while (leftTile) {
  179.         size_t photoLine = photo.size();
  180.         for (size_t i = 0; i < tiles[0].rows.size() - 2; ++i)
  181.             photo.push_back("");
  182.         Tile * curTile = leftTile;
  183.         while (curTile) {
  184.             for (size_t i = photoLine; i < photoLine + tiles[0].rows.size() - 2; ++i) {
  185.                 photo[i] += curTile->rows[i - photoLine + 1].substr(1, curTile->rows.size()-2);
  186.             }
  187.             curTile = curTile->east;
  188.         }
  189.         leftTile = leftTile->south;
  190.     }
  191.  
  192.     Tile final(photo);
  193.  
  194.     for (int config = 0; config < 8; ++config) {
  195.     final.setConfig(config);
  196.  
  197.         string monster1 = "                  # ";
  198.         string monster2 = "#    ##    ##    ###";
  199.         string monster3 = " #  #  #  #  #  #   ";
  200.  
  201.         int count = 0;
  202.         for (size_t i = 0; i < final.rows.size() - 3; ++i) {
  203.             for (size_t j = 0; j < final.rows.size() - monster1.size(); ++j) {
  204.                 bool ok = true;
  205.                 for (size_t k = 0; k < monster1.size(); ++k) {
  206.                     if ((monster1[k] == '#' && final.rows[i][k+j] != '#')
  207.                             || (monster2[k] == '#' && final.rows[i+1][k+j] != '#')
  208.                             || (monster3[k] == '#' && final.rows[i+2][k+j] != '#')) {
  209.                         ok = false; break;
  210.                     }
  211.                 }
  212.                 if (ok) ++count;
  213.             }
  214.         }
  215.         if (count > 0) {
  216.             size_t rough = 0;
  217.             for (size_t i = 0; i < final.rows.size(); ++i) {
  218.                 for (size_t j = 0; j < final.rows.size(); ++j) {
  219.                     if (final.rows[i][j] == '#') ++ rough;
  220.                 }
  221.             }
  222.             cout << "part two: " << rough - count * 15 << endl;
  223.         }
  224.     }
  225.  
  226.     auto stop = high_resolution_clock::now();
  227.     auto duration = duration_cast<milliseconds>(stop - start);
  228.     cout << duration.count() << endl;
  229.  
  230.     return 0;
  231. }
  232.  
Advertisement
Add Comment
Please, Sign In to add comment