Advertisement
Guest User

Untitled

a guest
Feb 19th, 2020
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.87 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) {
  14.     if (i == j) {
  15.         return;
  16.     }
  17.     int n = j - i;
  18.     uint64_t bound = pow(3, n);
  19.     for (uint64_t k = 1; k < bound; ++k) {
  20.         int64_t sum = 0;
  21.         uint64_t kk = k;
  22.         int ind = i;
  23.         while (kk != 0) {
  24.             if (kk % 3 == 2) {
  25.                 sum += data[ind];
  26.             } else if (kk % 3 == 1) {
  27.                 sum -= data[ind];
  28.             }
  29.             ind++;
  30.             kk = kk / 3;
  31.         }
  32.         mp[sum] = k;
  33.     }
  34. }
  35.  
  36. void FindIndexes(size_t num, std::vector<size_t>& first, std::vector<size_t>& second, int i) {
  37.     int ind = i;
  38.     while (num != 0) {
  39.         if (num % 3 == 2) {
  40.             first.push_back(ind);
  41.         } else if (num % 3 == 1) {
  42.             second.push_back(ind);
  43.         }
  44.         ind++;
  45.         num /= 3;
  46.     }
  47. }
  48.  
  49. Subsets subset;
  50. std::atomic<bool> fl;
  51. std::mutex mtx;
  52.  
  53. template <class InputIt>
  54. void my_advance(InputIt& it, InputIt end, int n ) {
  55.     while (n-- > 0 && it != end) {
  56.         std::advance(it, 1);
  57.     }
  58. }
  59.  
  60. bool Check(size_t first, size_t second) {
  61.     int a = 0, b = 0, c = 0, d = 0;
  62.     while (first != 0) {
  63.         if (first % 3 == 2) {
  64.             a++;
  65.         } else if (first % 3 == 1) {
  66.             b++;
  67.         }
  68.         first /= 3;
  69.     }
  70.  
  71.     while (second!= 0) {
  72.         if (second % 3 == 2) {
  73.             c++;
  74.         } else if (second % 3 == 1) {
  75.             d++;
  76.         }
  77.         second /= 3;
  78.     }
  79.     return (a + d != 0 && b + c != 0);
  80. }
  81.  
  82. void Result(const std::unordered_map<int64_t, size_t>& mp1,
  83.             const std::unordered_map<int64_t, size_t>& mp2, size_t sz, int i) {
  84.     auto st = mp1.begin();
  85.     my_advance(st, mp1.end(), i);
  86.     for (auto& it = st; it != mp1.end() && !fl.load(); my_advance(it, mp1.end(), 4)) {
  87.         int64_t key = it->first;
  88.         if (mp2.find(key) != mp2.end()) {
  89.             if (Check(mp1.at(key), mp2.at(key))) {
  90.                 std::vector<size_t> first, second;
  91.                 FindIndexes(mp1.at(key), first, second, 0);
  92.                 FindIndexes(mp2.at(key), second, first, sz);
  93.                 fl.store(true);
  94.                 mtx.lock();
  95.                 subset = Subsets{first, second, true};
  96.                 mtx.unlock();
  97.                 return;
  98.             }
  99.         }
  100.     }
  101. }
  102.  
  103. Subsets FindEqual(const std::unordered_map<int64_t, size_t>& mp1,
  104.                   const std::unordered_map<int64_t, size_t>& mp2, size_t sz) {
  105.     fl.store(false);
  106.     std::thread t1([&mp1, &mp2, sz] { Result(mp1, mp2, sz, 0); });
  107.     std::thread t2([&mp1, &mp2, sz] { Result(mp1, mp2, sz, 1); });
  108.     std::thread t3([&mp1, &mp2, sz] { Result(mp1, mp2, sz, 2); });
  109.     std::thread t4([&mp1, &mp2, sz] { Result(mp1, mp2, sz, 3); });
  110.     t1.join();
  111.     t2.join();
  112.     t3.join();
  113.     t4.join();
  114.  
  115.     if (fl) {
  116.         return subset;
  117.     }
  118.     return Subsets{{}, {}, false};
  119. }
  120.  
  121. Subsets FindEqualSumSubsets(const std::vector<int64_t>& data) {
  122.     size_t sz = data.size() / 2;
  123.     std::unordered_map<int64_t, size_t> mp1;
  124.     std::unordered_map<int64_t, size_t> mp2;
  125.     std::thread th1([&mp1, sz, &data] { FindSum(mp1, 0, sz, data); });
  126.     std::thread th2([&mp2, sz, &data] { FindSum(mp2, sz, data.size(), data); });
  127.     th1.join();
  128.     th2.join();
  129.     std::vector<size_t> first, second;
  130.     if (mp1.find(0) != mp1.end()) {
  131.         FindIndexes(mp1[0], first, second, 0);
  132.         return Subsets{first, second, true};
  133.     }
  134.     if (mp2.find(0) != mp2.end()) {
  135.         FindIndexes(mp2[0], first, second, sz);
  136.         return Subsets{first, second, true};
  137.     }
  138.     return FindEqual(mp1, mp2, sz);
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement