Advertisement
Guest User

Untitled

a guest
Feb 19th, 2020
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.36 KB | None | 0 0
  1. #include "find_subsets.h"
  2. #include <stdexcept>
  3. #include <vector>
  4. #include <unordered_map>
  5. #include <cmath>
  6. #include <thread>
  7. #include <mutex>
  8. #include <atomic>
  9.  
  10. #include <iostream>
  11.  
  12. void FindSum(std::unordered_map<int64_t, size_t>& mp, size_t i, size_t j,
  13.              const std::vector<int64_t>& data, const std::vector<size_t>& rev) {
  14.     if (i == j) {
  15.         return;
  16.     }
  17.     int n = j - i;
  18.     size_t bound = pow(3, n);
  19.     for (size_t k = 1; k < bound; ++k) {
  20.         if (k > rev[k]) {
  21.             continue;
  22.         }
  23.         int64_t sum = 0;
  24.         size_t kk = k;
  25.         int ind = i;
  26.         while (kk != 0) {
  27.             if (kk % 3 == 2) {
  28.                 sum += data[ind];
  29.             } else if (kk % 3 == 1) {
  30.                 sum -= data[ind];
  31.             }
  32.             ind++;
  33.             kk = kk / 3;
  34.         }
  35.         mp[sum] = k;
  36.     }
  37. }
  38.  
  39. void FindIndexes(size_t num, std::vector<size_t>& first, std::vector<size_t>& second, int i) {
  40.     int ind = i;
  41.     while (num != 0) {
  42.         if (num % 3 == 2) {
  43.             first.push_back(ind);
  44.         } else if (num % 3 == 1) {
  45.             second.push_back(ind);
  46.         }
  47.         ind++;
  48.         num /= 3;
  49.     }
  50. }
  51.  
  52. Subsets subset;
  53. std::atomic<bool> fl;
  54. std::mutex mtx;
  55.  
  56. template <class InputIt>
  57. void MyAdvance(InputIt& it, InputIt end, int n) {
  58.     while (n-- > 0 && it != end) {
  59.         std::advance(it, 1);
  60.     }
  61. }
  62.  
  63. bool Check(size_t first, size_t second) {
  64.     int a = 0, b = 0, c = 0, d = 0;
  65.     while (first != 0) {
  66.         if (first % 3 == 2) {
  67.             a++;
  68.         } else if (first % 3 == 1) {
  69.             b++;
  70.         }
  71.         first /= 3;
  72.     }
  73.  
  74.     while (second != 0) {
  75.         if (second % 3 == 2) {
  76.             c++;
  77.         } else if (second % 3 == 1) {
  78.             d++;
  79.         }
  80.         second /= 3;
  81.     }
  82.     return (a + d != 0 && b + c != 0);
  83. }
  84.  
  85. void Result(const std::unordered_map<int64_t, size_t>& mp1,
  86.             const std::unordered_map<int64_t, size_t>& mp2, size_t sz, int i,
  87.             const std::vector<size_t>& rev) {
  88.     auto st = mp1.begin();
  89.     MyAdvance(st, mp1.end(), i);
  90.     for (; st != mp1.end() && !fl.load(); MyAdvance(st, mp1.end(), 8)) {
  91.         int64_t key = st->first;
  92.         bool fl1 = (mp2.find(key) != mp2.end());
  93.         bool fl2 = (mp2.find(-1 * key) != mp2.end());
  94.         if (fl1) {
  95.             size_t vl = mp2.at(key);;
  96.             if (Check(mp1.at(key), vl)) {
  97.                 std::vector<size_t> first, second;
  98.                 FindIndexes(mp1.at(key), first, second, 0);
  99.                 FindIndexes(vl, second, first, sz);
  100.                 fl.store(true);
  101.                 mtx.lock();
  102.                 subset = Subsets{first, second, true};
  103.                 mtx.unlock();
  104.                 return;
  105.             }
  106.         }
  107.         if (fl2) {
  108.             size_t vl = rev[mp2.at(-1 * key)];
  109.             if (Check(mp1.at(key), vl)) {
  110.                 std::vector<size_t> first, second;
  111.                 FindIndexes(mp1.at(key), first, second, 0);
  112.                 FindIndexes(vl, second, first, sz);
  113.                 fl.store(true);
  114.                 mtx.lock();
  115.                 subset = Subsets{first, second, true};
  116.                 mtx.unlock();
  117.                 return;
  118.             }
  119.         }
  120.     }
  121. }
  122.  
  123. Subsets FindEqual(const std::unordered_map<int64_t, size_t>& mp1,
  124.                   const std::unordered_map<int64_t, size_t>& mp2, size_t sz,
  125.                   const std::vector<size_t>& rev) {
  126.     fl.store(false);
  127.     std::thread t1([&mp1, &mp2, sz, &rev] { Result(mp1, mp2, sz, 0, rev); });
  128.     std::thread t2([&mp1, &mp2, sz, &rev] { Result(mp1, mp2, sz, 1, rev); });
  129.     std::thread t3([&mp1, &mp2, sz, &rev] { Result(mp1, mp2, sz, 2, rev); });
  130.     std::thread t4([&mp1, &mp2, sz, &rev] { Result(mp1, mp2, sz, 3, rev); });
  131.     std::thread t5([&mp1, &mp2, sz, &rev] { Result(mp1, mp2, sz, 4, rev); });
  132.     std::thread t6([&mp1, &mp2, sz, &rev] { Result(mp1, mp2, sz, 5, rev); });
  133.     std::thread t7([&mp1, &mp2, sz, &rev] { Result(mp1, mp2, sz, 6, rev); });
  134.     std::thread t8([&mp1, &mp2, sz, &rev] { Result(mp1, mp2, sz, 7, rev); });
  135.     t1.join();
  136.     t2.join();
  137.     t3.join();
  138.     t4.join();
  139.     t5.join();
  140.     t6.join();
  141.     t7.join();
  142.     t8.join();
  143.  
  144.     if (fl) {
  145.         return subset;
  146.     }
  147.     return Subsets{{}, {}, false};
  148. }
  149.  
  150. Subsets FindEqualSumSubsets(const std::vector<int64_t>& data) {
  151.     size_t sz = data.size() / 2;
  152.     std::vector<size_t> rev(pow(3, data.size()));
  153.     for (size_t i = 0; i < rev.size(); ++i) {
  154.         size_t rev_i = 0;
  155.         size_t ii = i;
  156.         int64_t pw = 1;
  157.         while (ii > 0) {
  158.             rev_i += pw * (3 - ii % 3) % 3;
  159.             pw *= 3;
  160.             ii /= 3;
  161.         }
  162.         rev[i] = rev_i;
  163.     }
  164.     std::unordered_map<int64_t, size_t> mp1;
  165.     std::unordered_map<int64_t, size_t> mp2;
  166.     std::thread th1([&mp1, sz, &data, &rev] { FindSum(mp1, 0, sz, data, rev); });
  167.     std::thread th2([&mp2, sz, &data, &rev] { FindSum(mp2, sz, data.size(), data, rev); });
  168.     th1.join();
  169.     th2.join();
  170.     std::vector<size_t> first, second;
  171.     if (mp1.find(0) != mp1.end()) {
  172.         FindIndexes(mp1[0], first, second, 0);
  173.         return Subsets{first, second, true};
  174.     }
  175.     if (mp2.find(0) != mp2.end()) {
  176.         FindIndexes(mp2[0], first, second, sz);
  177.         return Subsets{first, second, true};
  178.     }
  179.     return FindEqual(mp1, mp2, sz, rev);
  180. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement