Advertisement
Hamikadze

Untitled

Jan 12th, 2019
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.54 KB | None | 0 0
  1. // SatSolver.cpp : This file contains the 'main' function. Program execution begins and ends there.
  2. //
  3.  
  4. #include "pch.h"
  5. #include <array>
  6. #include <vector>
  7. #include <bitset>
  8. #include <fstream>
  9.  
  10. using namespace  std;
  11.  
  12. const auto ROWS = 4;
  13. const auto COLUMNS = 4;
  14. const auto O = false;
  15. const auto X = true;
  16. const bool CONFIGURATION[ROWS][COLUMNS] = {
  17.     {X, O, O, O},
  18.     {O, X, X, X},
  19.     {O, X, X, O},
  20.     {X, O, X, O}
  21. };
  22.  
  23. const size_t VAR_NUM = 9;
  24.  
  25. constexpr auto numberOfSetBits(uint32_t i) {
  26.     i = i - ((i >> 1) & 0x55555555);
  27.     i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
  28.     return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
  29. }
  30.  
  31. constexpr auto assembleMask(const uint8_t params, const bool e) {
  32.     return ~(uint32_t(params & 0xF0) << 1 | (params & 0xF) | e << 4);
  33. }
  34.  
  35. //делаем шаг вперёд
  36. std::vector<std::vector<int>> run1step(std::vector<std::vector<int>> ar)
  37. {
  38.     int xlen = ar.size();
  39.     int ylen = ar[0].size();
  40.     std::vector<std::vector<int>> result(xlen);
  41.     for (int i = 0; i < xlen; i++)
  42.     {
  43.         result[i] = vector<int>(ylen);
  44.     }
  45.     for (int x = 0; x < xlen; x++)
  46.     {
  47.         for (int y = 0; y < ylen; y++)
  48.         {
  49.             bool isleft = (y == 0);
  50.             bool isright = (y == ylen - 1);
  51.             bool isup = (x == 0);
  52.             bool isdown = (x == xlen - 1);
  53.  
  54.             int ncount = (isleft ? 0 : ar[x][y - 1]) +
  55.                 (isleft || isup ? 0 : ar[x - 1][y - 1]) +
  56.                 (isup ? 0 : ar[x - 1][y]) +
  57.                 (isup || isright ? 0 : ar[x - 1][y + 1]) +
  58.                 (isright ? 0 : ar[x][y + 1]) +
  59.                 (isright || isdown ? 0 : ar[x + 1][y + 1]) +
  60.                 (isdown ? 0 : ar[x + 1][y]) +
  61.                 (isdown || isleft ? 0 : ar[x + 1][y - 1]);
  62.  
  63.             result[x][y] = ((ncount == 3 || (ar[x][y] == 1 && ncount == 2)) ? 1 : 0);
  64.         }
  65.     }
  66.     return result;
  67. }
  68.  
  69. //увеличиваем поле на одну клетку по краям
  70. std::vector<std::vector<int>> lor(std::bitset<VAR_NUM> addpat)
  71. {
  72.     vector<vector<int>> result(5);
  73.     for (int i = 0; i < 5; i++)
  74.     {
  75.         result[i] = vector<int>(5);
  76.     }
  77.     int count = 0;
  78.  
  79.     for (int x = 0; x < 5; x++)
  80.     {
  81.         for (int y = 0; y < 5; y++)
  82.         {
  83.             if (1 <= x && x < 4 && 1 <= y && y < 4)
  84.             {
  85.                 result[x][y] = addpat[count++];
  86.             }
  87.             else
  88.             {
  89.                 result[x][y] = 0;
  90.             }
  91.         }
  92.     }
  93.     return result;
  94. }
  95.  
  96. //проверяем на удовлетворение условий
  97. bool check(int y, int x, vector<vector<int>> runF)
  98. {
  99.     int goalWidth = COLUMNS;
  100.     int goalHeight = ROWS;
  101.     if (x == 0 && y == 0)
  102.     {
  103.         if (runF[0][0] == 0 && runF[1][0] == 0 && runF[2][0] == 0 && runF[0][1] == 0 && runF[1][1] == 0 && runF[2][1] == 0
  104.             && runF[0][2] == 0 && runF[1][2] == 0)
  105.         {
  106.             return true;
  107.         }
  108.     }
  109.     if (y == 0)
  110.     {
  111.         if (x == goalWidth - 1)
  112.         {
  113.             if (runF[2][0] == 0 && runF[3][0] == 0 && runF[4][0] == 0 && runF[2][1] == 0 && runF[3][1] == 0 && runF[4][1] == 0 &&
  114.                 runF[3][2] == 0 && runF[4][2] == 0)
  115.             {
  116.                 return true;
  117.             }
  118.         }
  119.         else
  120.         {
  121.             if (runF[2][0] == 0 && runF[2][1] == 0)
  122.             {
  123.                 return true;
  124.             }
  125.         }
  126.     }
  127.     else if (y == goalHeight - 1)
  128.     {
  129.         if (x == 0)
  130.         {
  131.             if (runF[0][2] == 0 && runF[1][2] == 0 && runF[0][3] == 0 && runF[1][3] == 0 && runF[2][3] == 0 && runF[0][4] == 0 &&
  132.                 runF[1][4] == 0 && runF[2][4] == 0)
  133.             {
  134.                 return true;
  135.             }
  136.         }
  137.         else if (x == goalWidth - 1)
  138.         {
  139.             if (runF[3][2] == 0 && runF[4][2] == 0 && runF[2][3] == 0 && runF[3][3] == 0 && runF[4][3] == 0 && runF[2][4] == 0 &&
  140.                 runF[3][4] == 0 && runF[4][4] == 0)
  141.             {
  142.                 return true;
  143.             }
  144.         }
  145.         else
  146.         {
  147.             if (runF[2][3] == 0 && runF[2][4] == 0)
  148.             {
  149.                 return true;
  150.             }
  151.         }
  152.     }
  153.     else
  154.     {
  155.         if (x == 0)
  156.         {
  157.             if (runF[0][2] == 0 && runF[1][2] == 0)
  158.             {
  159.                 return true;
  160.             }
  161.         }
  162.         else if (x == goalWidth - 1)
  163.         {
  164.             if (runF[3][2] == 0 && runF[4][2] == 0)
  165.             {
  166.                 return true;
  167.             }
  168.         }
  169.         else
  170.         {
  171.             return true;
  172.         }
  173.     }
  174.     return false;
  175. }
  176.  
  177. int main()
  178. {
  179.     auto out = std::ofstream("output.txt");
  180.     auto outDimacs = std::ofstream("dimacs.cnf");
  181.  
  182.     // строим маски КНФ
  183.     std::vector<std::bitset<VAR_NUM>> cnfMasksLive;
  184.     std::vector<std::bitset<VAR_NUM>> cnfMasksDead;
  185.     for (uint32_t i = 0; i < 1 << 8; i++) {
  186.         const auto sb = numberOfSetBits(i);
  187.         if (sb != 3) {
  188.             cnfMasksLive.emplace_back(assembleMask(i, false));
  189.             if (sb != 2)
  190.                 cnfMasksLive.emplace_back(assembleMask(i, true));
  191.             else
  192.                 cnfMasksDead.emplace_back(assembleMask(i, true));
  193.         }
  194.         else {
  195.             cnfMasksDead.emplace_back(assembleMask(i, true));
  196.             cnfMasksDead.emplace_back(assembleMask(i, false));
  197.         }
  198.     }
  199.  
  200.     // пишем КНФ и DIMACS
  201.     const auto liveNum = std::count_if(&CONFIGURATION[0][0], &CONFIGURATION[ROWS - 1][COLUMNS - 1], [](const bool val) { return val; });
  202.     const auto varNum = (ROWS + 2)*(COLUMNS + 2); // пока не считаем
  203.     outDimacs << "p cnf " << varNum << ' ' << cnfMasksLive.size() * liveNum << '\n';
  204.     // КНФ клеток конфигурации
  205.     for (size_t i = 0; i < ROWS; i++)
  206.     {
  207.         for (size_t j = 0; j < COLUMNS; j++)
  208.         {
  209.             const auto & masks = CONFIGURATION[i][j] ? cnfMasksLive : cnfMasksDead;
  210.             for (const auto &mask : masks) {
  211.                 auto runF = run1step(lor(mask));
  212.                 if (!check(j, i, runF))
  213.                     continue;
  214.  
  215.                 out << '(';
  216.                 for (size_t k = 0; k < VAR_NUM; k++) {
  217.                     if (!mask.test(k)) {
  218.                         out << '~';
  219.                         outDimacs << '-';
  220.                     }
  221.  
  222.                     const int32_t literal = 1 + COLUMNS + 2 + 1 + (i + k / 3 - 1)*(COLUMNS + 2) + (j + k % 3 - 1);
  223.                     outDimacs << literal << " ";
  224.                     out << "x" << literal;
  225.                     if (k != VAR_NUM - 1)
  226.                         out << '|';
  227.                 }
  228.                 outDimacs << "0\n";
  229.                 out << ')';
  230.             }
  231.         }
  232.     }
  233.     // КНФ внешних клеток
  234.  
  235.     system("pause");
  236. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement