Advertisement
Hamikadze

Untitled

Jan 12th, 2019
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.89 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. //делаем шаг вперёд
  37. std::vector<std::vector<int>> run1step(std::vector<std::vector<int>> ar)
  38. {
  39.     int xlen = ar.size();
  40.     int ylen = ar[0].size();
  41.     std::vector<std::vector<int>> result(xlen);
  42.     for (int i = 0; i < xlen; i++)
  43.     {
  44.         result[i] = vector<int>(ylen);
  45.     }
  46.     for (int x = 0; x < xlen; x++)
  47.     {
  48.         for (int y = 0; y < ylen; y++)
  49.         {
  50.             bool isleft = (y == 0);
  51.             bool isright = (y == ylen - 1);
  52.             bool isup = (x == 0);
  53.             bool isdown = (x == xlen - 1);
  54.  
  55.             int ncount = (isleft ? 0 : ar[x][y - 1]) +
  56.                 (isleft || isup ? 0 : ar[x - 1][y - 1]) +
  57.                 (isup ? 0 : ar[x - 1][y]) +
  58.                 (isup || isright ? 0 : ar[x - 1][y + 1]) +
  59.                 (isright ? 0 : ar[x][y + 1]) +
  60.                 (isright || isdown ? 0 : ar[x + 1][y + 1]) +
  61.                 (isdown ? 0 : ar[x + 1][y]) +
  62.                 (isdown || isleft ? 0 : ar[x + 1][y - 1]);
  63.  
  64.             result[x][y] = ((ncount == 3 || (ar[x][y] == 1 && ncount == 2)) ? 1 : 0);
  65.         }
  66.     }
  67.     return result;
  68. }
  69.  
  70. //увеличиваем поле на одну клетку по краям
  71. std::vector<std::vector<int>> lor(std::bitset<VAR_NUM> addpat)
  72. {
  73.     vector<vector<int>> result(5);
  74.     for (int i = 0; i < 5; i++)
  75.     {
  76.         result[i] = vector<int>(5);
  77.     }
  78.     int xmin = 1;
  79.     int xmax = 4;
  80.     int ymin = 1;
  81.     int ymax = 4;
  82.     int xrange = 5;
  83.     int yrange = 5;
  84.     int count = 0;
  85.  
  86.     for (int x = 0; x < xrange; x++)
  87.     {
  88.         for (int y = 0; y < yrange; y++)
  89.         {
  90.             if (xmin <= x && x < xmax && ymin <= y && y < ymax)
  91.             {
  92.                 result[x][y] = addpat[count++];
  93.             }
  94.             else
  95.             {
  96.                 result[x][y] = 0;
  97.             }
  98.         }
  99.     }
  100.     return result;
  101. }
  102.  
  103.  
  104. //проверяем на удовлетворение условий
  105. bool check(int y, int x, vector<vector<int>> runF)
  106. {
  107.     auto goal = CONFIGURATION;
  108.     int goalWidth = COLUMNS;
  109.     int goalHeight = ROWS;
  110.     if (y == 0)
  111.     {
  112.         //0,0 code at start.
  113.         if (x == goalWidth - 1)
  114.         {
  115.             if (goal[x, y] == 0)
  116.             {
  117.                 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 &&
  118.                     runF[3][2] == 0 && runF[4][2] == 0)
  119.                 {
  120.                     return true;
  121.                 }
  122.             }
  123.             else
  124.             {
  125.                 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 &&
  126.                     runF[3][2] == 0 && runF[4][2] == 0)
  127.                 {
  128.                     return true;
  129.                 }
  130.             }
  131.         }
  132.         else
  133.         {
  134.             if (goal[x, y] == 0)
  135.             {
  136.                 if (runF[2][0] == 0 && runF[2][1] == 0)
  137.                 {
  138.                     return true;
  139.                 }
  140.             }
  141.             else
  142.             {
  143.                 if (runF[2][0] == 0 && runF[2][1] == 0)
  144.                 {
  145.                     return true;
  146.                 }
  147.             }
  148.         }
  149.     }
  150.     else if (y == goalHeight - 1)
  151.     {
  152.         if (x == 0)
  153.         {
  154.             if (goal[x, y] == 0)
  155.             {
  156.                 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 &&
  157.                     runF[1][4] == 0 && runF[2][4] == 0)
  158.                 {
  159.                     return true;
  160.                 }
  161.             }
  162.             else
  163.             {
  164.                 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 &&
  165.                     runF[1][4] == 0 && runF[2][4] == 0)
  166.                 {
  167.                     return true;
  168.                 }
  169.             }
  170.         }
  171.         else if (x == goalWidth - 1)
  172.         {
  173.             if (goal[x, y] == 0)
  174.             {
  175.                 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 &&
  176.                     runF[3][4] == 0 && runF[4][4] == 0)
  177.                 {
  178.                     return true;
  179.                 }
  180.             }
  181.             else
  182.             {
  183.                 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 &&
  184.                     runF[3][4] == 0 && runF[4][4] == 0)
  185.                 {
  186.                     return true;
  187.                 }
  188.             }
  189.         }
  190.         else
  191.         {
  192.             if (goal[x, y] == 0)
  193.             {
  194.                 if (runF[2][3] == 0 && runF[2][4] == 0)
  195.                 {
  196.                     return true;
  197.                 }
  198.             }
  199.             else
  200.             {
  201.                 if (runF[2][3] == 0 && runF[2][4] == 0)
  202.                 {
  203.                     return true;
  204.                 }
  205.             }
  206.         }
  207.     }
  208.     else
  209.     {
  210.         if (x == 0)
  211.         {
  212.             if (goal[x, y] == 0)
  213.             {
  214.                 if (runF[0][2] == 0 && runF[1][2] == 0)
  215.                 {
  216.                     return true;
  217.                 }
  218.             }
  219.             else
  220.             {
  221.                 if (runF[0][2] == 0 && runF[1][2] == 0)
  222.                 {
  223.                     return true;
  224.                 }
  225.             }
  226.         }
  227.         else if (x == goalWidth - 1)
  228.         {
  229.             if (goal[x, y] == 0)
  230.             {
  231.                 if (runF[3][2] == 0 && runF[4][2] == 0)
  232.                 {
  233.                     return true;
  234.                 }
  235.             }
  236.             else
  237.             {
  238.                 if (runF[3][2] == 0 && runF[4][2] == 0)
  239.                 {
  240.                     return true;
  241.                 }
  242.             }
  243.         }
  244.         else
  245.         {
  246.             if (goal[x, y] == 0)
  247.             {
  248.                 return true;
  249.             }
  250.             else
  251.             {
  252.                 return true;
  253.             }
  254.         }
  255.     }
  256.     return false;
  257. }
  258.  
  259. int main()
  260. {
  261.     auto out = std::ofstream("output.txt");
  262.     auto outDimacs = std::ofstream("dimacs.cnf");
  263.  
  264.     // строим маски КНФ
  265.     std::vector<std::bitset<VAR_NUM>> cnfMasksLive;
  266.     std::vector<std::bitset<VAR_NUM>> cnfMasksDead;
  267.     for (uint32_t i = 0; i < 1 << 8; i++) {
  268.         const auto sb = numberOfSetBits(i);
  269.         if (sb != 3) {
  270.             cnfMasksLive.emplace_back(assembleMask(i, false));
  271.             if (sb != 2)
  272.                 cnfMasksLive.emplace_back(assembleMask(i, true));
  273.             else
  274.                 cnfMasksDead.emplace_back(assembleMask(i, true));
  275.         }
  276.         else {
  277.             cnfMasksDead.emplace_back(assembleMask(i, true));
  278.             cnfMasksDead.emplace_back(assembleMask(i, false));
  279.         }
  280.     }
  281.  
  282.     // пишем КНФ и DIMACS
  283.     const auto liveNum = std::count_if(&CONFIGURATION[0][0], &CONFIGURATION[ROWS - 1][COLUMNS - 1], [](const bool val) { return val; });
  284.     const auto varNum = (ROWS + 2)*(COLUMNS + 2); // пока не считаем
  285.     outDimacs << "p cnf " << varNum << ' ' << cnfMasksLive.size() * liveNum << '\n';
  286.     // КНФ клеток конфигурации
  287.     for (size_t i = 0; i < ROWS; i++)
  288.     {
  289.         for (size_t j = 0; j < COLUMNS; j++)
  290.         {
  291.             const auto & masks = CONFIGURATION[i][j] ? cnfMasksLive : cnfMasksDead;
  292.             for (const auto &mask : masks) {
  293.                 auto runF = run1step(lor(mask));
  294.                 if (!check(i, j, runF))
  295.                     continue;
  296.  
  297.                 out << '(';
  298.                 for (size_t k = 0; k < VAR_NUM; k++) {
  299.                     if (!mask.test(k)) {
  300.                         out << '~';
  301.                         outDimacs << '-';
  302.                     }
  303.  
  304.                     const int32_t literal = 1 + COLUMNS + 2 + 1 + (i + k / 3 - 1)*(COLUMNS + 2) + (j + k % 3 - 1);
  305.                     outDimacs << literal << " ";
  306.                     out << "x" << literal;
  307.                     if (k != VAR_NUM - 1)
  308.                         out << '|';
  309.                 }
  310.                 outDimacs << "0\n";
  311.                 out << ')';
  312.             }
  313.         }
  314.     }
  315.     // КНФ внешних клеток
  316.  
  317.     system("pause");
  318. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement