Advertisement
sadov_a

Untitled

May 17th, 2024
468
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.08 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <random>
  4. #include <chrono>
  5. #include <algorithm>
  6.  
  7. class Miner {
  8. private:
  9.     size_t n;
  10.     size_t mines;
  11.     std::vector<bool> line;
  12.     std::vector<bool> click;
  13.     size_t clicked = 0;
  14.     bool lost = false;
  15.     std::mt19937 rnd;
  16.  
  17.  
  18.     int get_count(size_t i) {
  19.         int ans = 0;
  20.         if (i > 0) {
  21.             ans += line[i - 1];
  22.         }
  23.         if (i + 1 < n) {
  24.             ans += line[i + 1];
  25.         }
  26.         return ans;
  27.     }
  28.  
  29. public:
  30.     Miner(size_t n, size_t mines): n(n), mines(mines), line(n), click(n),
  31.             rnd(std::chrono::high_resolution_clock::now().time_since_epoch().count())
  32.     {
  33.         for (size_t i = 0; i < mines; ++i) {
  34.             line[i] = true;
  35.         }
  36.         std::shuffle(line.begin(), line.end(), rnd);
  37.     }
  38.  
  39.     int click_square(size_t i) {
  40.         if (line[i]) {
  41.             lost = true;
  42.             return -1;
  43.         }
  44.         if (!click[i]) {
  45.             ++clicked;
  46.         }
  47.         click[i] = true;
  48.         return get_count(i);
  49.     }
  50.  
  51.     int game_result() {
  52.         if (lost) {
  53.             return -1;
  54.         }
  55.         if (clicked == n - mines) {
  56.             return 1;
  57.         }
  58.         return 0;
  59.     }
  60. };
  61.  
  62. void middle_solver_helper(int l, int r, std::vector<int>& line, Miner& miner) {
  63.     if (l > r) return;
  64.     int m = (l + r) / 2;
  65.     if (line[m] == -2) {
  66.         line[m] = miner.click_square(m);
  67.     }
  68.     if (line[m] >= 0) {
  69.         if (m >= 2 && line[m - 1] == 1) {
  70.             line[m - 2] = -1;
  71.         } else if (m + 2 < line.size() && line[m + 1] == 1) {
  72.             line[m + 2] = -1;
  73.         }
  74.     }
  75.     // std::cerr << l << ' ' << m << ' ' << r << ' ' << line[m] << std::endl;
  76.     if (line[m] == 2) {
  77.         line[m - 1] = line[m + 1] = -1;
  78.         middle_solver_helper(l, m - 2, line, miner);
  79.         middle_solver_helper(m + 2, r, line, miner);
  80.         return;
  81.     }
  82.     if (line[m] == 0) {
  83.         for (int j = m - 1; j >= l; --j) {
  84.             line[j] = miner.click_square(j);
  85.             if (line[j] == 1) {
  86.                 line[j - 1] = -1;
  87.                 middle_solver_helper(l, j - 2, line, miner);
  88.                 break;
  89.             }
  90.         }
  91.         for (int j = m + 1; j <= r; ++j) {
  92.             line[j] = miner.click_square(j);
  93.             if (line[j] == 1) {
  94.                 line[j + 1] = -1;
  95.                 middle_solver_helper(j + 2, r, line, miner);
  96.                 break;
  97.             }
  98.         }
  99.         return;
  100.     }
  101.     if (line[m] == 1) {
  102.         if (m == 0 || line[m - 1] >= 0) {
  103.             line[m + 1] = -1;
  104.         } else if (m + 1 == line.size() || line[m + 1] >= 0) {
  105.             line[m - 1] = -1;
  106.         }
  107.     }
  108.     middle_solver_helper(l, m - 1, line, miner);
  109.     middle_solver_helper(m + 1, r, line, miner);
  110. }
  111.  
  112. void middle_solver(size_t n, size_t mines, Miner& miner) {
  113.     std::vector<int> line(n, -2);
  114.     middle_solver_helper(0, n - 1, line, miner);
  115. }
  116.  
  117. void random_solver(size_t n, size_t mines, Miner& miner) {
  118.     std::vector<int> line(n, -2);
  119.     std::vector<size_t> order(n);
  120.     std::iota(order.begin(), order.end(), 0);
  121.     std::mt19937 rnd(std::chrono::high_resolution_clock::now().time_since_epoch().count());
  122.     std::shuffle(order.begin(), order.end(), rnd);
  123.     for (size_t i : order) {
  124.         if (miner.game_result() == 1) {
  125.             break;
  126.         }
  127.         if (line[i] != -2) {
  128.             continue;
  129.         }
  130.         line[i] = miner.click_square(i);
  131.         if (line[i] == -1) {
  132.             return;
  133.         }
  134.         if (line[i] == 2) {
  135.             line[i - 1] = line[i + 1] = -1;
  136.         } else if (line[i] == 1) {
  137.             if (i == 0 || line[i - 1] >= 0) {
  138.                 line[i + 1] = -1;
  139.             } else if (i == n - 1 || line[i + 1] >= 0) {
  140.                 line[i - 1] = -1;
  141.             }
  142.         } else if (line[i] == 0) {
  143.             for (int j = static_cast<int>(i) - 1; j >= 0; --j) {
  144.                 line[j] = miner.click_square(j);
  145.                 if (line[j] > 0) {
  146.                     line[j - 1] = -1;
  147.                     break;
  148.                 }
  149.             }
  150.             for (int j = i + 1; j < n; ++j) {
  151.                 line[j] = miner.click_square(j);
  152.                 if (line[j] > 0) {
  153.                     line[j + 1] = -1;
  154.                     break;
  155.                 }
  156.             }
  157.         }
  158.     }
  159. }
  160.  
  161. void simple_solver(size_t n, size_t mines, Miner& miner) {
  162.     std::vector<int> line(n, -2);
  163.     for (size_t i = 0; i < n; ++i) {
  164.         if (line[i] != -2) {
  165.             continue;
  166.         }
  167.         line[i] = miner.click_square(i);
  168.         if (line[i] == -1) {
  169.             return;
  170.         }
  171.         int next = line[i] - (i > 0 && line[i - 1] == -1);
  172.         if (next) {
  173.             line[i + 1] = -1;
  174.         }
  175.     }
  176. }
  177.  
  178. int main() {
  179.     size_t n = 10000, mines = 90, rep = 10000, won = 0;
  180.     for (size_t i = 0; i < rep; ++i) {
  181.         Miner miner(n, mines);
  182.         middle_solver(n, mines, miner);
  183.         won += miner.game_result() == 1;
  184.     }
  185.     std::cout << "won " << won << " out of " << rep << std::endl;
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement