Advertisement
Guest User

recursive sum finder

a guest
Oct 12th, 2021
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.83 KB | None | 0 0
  1.  
  2. #include <iostream>
  3. #include <vector>
  4. #include <deque>
  5. #include <string>
  6. #include <algorithm>
  7. #include <numeric>
  8. #include <functional>
  9. #include <set>
  10.  
  11. #ifndef OUT
  12. #define OUT
  13. #endif
  14.  
  15. #ifndef IN
  16. #define IN
  17. #endif
  18.  
  19. #define ENABLE_UNIQUE_RESULT
  20.  
  21.  
  22. #ifdef ENABLE_UNIQUE_RESULT
  23. struct ResultType
  24. {
  25.     std::vector<std::string> strings;
  26.     std::set<double> hashes;
  27. };
  28. #else
  29. typedef std::vector<std::string> ResultType;
  30. #endif
  31.  
  32. void input_coins(OUT std::vector<int>& coins)
  33. {
  34.     // printing existing coins (only if they exists)
  35.     if(!coins.empty())
  36.     {
  37.         std::cout << "Actually coins are: { ";
  38.         for(auto& c : coins)
  39.             std::cout << c << ", ";
  40.         std::cout << "}" << std::endl;
  41.     }
  42.    
  43.     // outing what's needed right now
  44.     std::cout << "Insert a number or 'next' to continue " << std::endl;
  45.     std::string ans{};
  46.     std::cin >> ans;
  47.    
  48.     // checking if ans is a number, next, or a wrong value
  49.     if(auto iter = std::find_if(ans.begin(), ans.end(), [](auto c ){ return !isdigit(c); });
  50.        iter != ans.end() || ans.empty())
  51.     {
  52.         if(ans != "next")
  53.         {
  54.             // repeating input_coins since value was wrong
  55.             std::cout << "You have inserted a wrong value." << std::endl;
  56.             input_coins(coins);
  57.         }
  58.         return;
  59.     }
  60.    
  61.     // value looks correct, moving it into coins and repeating input_coins
  62.     int value = atoi(ans.c_str());
  63.     coins.emplace_back(value);
  64.     input_coins(coins);
  65. }
  66.  
  67. void input_sum_result(OUT int& result)
  68. {
  69.     // outing what's needed right now
  70.     std::cout << "Insert the sum result:" << std::endl;
  71.     std::string ans{};
  72.     std::cin >> ans;
  73.    
  74.     // checking if ans is a number or a wrong value
  75.     if(auto iter = std::find_if(ans.begin(), ans.end(), [](auto c ){ return !isdigit(c); });
  76.        iter != ans.end() || ans.empty())
  77.     {
  78.         // repeating input_sum_result since ans is a wrong value
  79.         std::cout << "You have inserted a wrong value." << std::endl;
  80.         input_sum_result(result);
  81.         return;
  82.     }
  83.    
  84.     // ans looks to be a number so assigning result the value
  85.     result = atoi(ans.c_str());
  86. }
  87.  
  88. template<template<class T> class ContainerType>
  89. std::string stringfy_numbers(IN const ContainerType<int>& numbers)
  90. {
  91.     auto res = std::accumulate(numbers.begin(), numbers.end(), std::string("{"),
  92.         [](auto& res, auto& v){ return res + std::to_string(v) + ", "; });
  93.     res += "}";
  94.     return res;
  95. }
  96.  
  97. template<template<class T> class ContainerType>
  98. ContainerType<int> copy_insert(ContainerType<int> container, int num)
  99. {
  100.     container.emplace_back(num);
  101.     return container;
  102. }
  103.  
  104. #ifdef ENABLE_UNIQUE_RESULT
  105. double hash_numbers(IN const std::deque<int>& numbers)
  106. {
  107.     double hash = 1;
  108.     for(auto& num : numbers)
  109.         hash *= (1.0/static_cast<double>(num));
  110.     return hash;
  111. }
  112.  
  113. void insert_result(OUT ResultType& res, IN const std::deque<int>& numbers)
  114. {
  115.     double hash = hash_numbers(numbers);
  116.     if(res.hashes.find(hash) == res.hashes.end())
  117.     {
  118.         res.hashes.emplace(hash);
  119.         res.strings.emplace_back(stringfy_numbers(numbers));
  120.     }
  121. }
  122. #else
  123. void insert_result(OUT ResultType& res, IN const std::deque<int>& numbers)
  124. {
  125.     res.emplace_back(stringfy_numbers(numbers));
  126. }
  127. #endif
  128.  
  129.  
  130. void recursive_sum( IN std::vector<int> coins,
  131.                     IN int result,
  132.                     OUT ResultType& res,
  133.                     IN std::deque<int> numbers = {},
  134.                     IN int actual_sum = 0)
  135. {
  136. #ifdef PRINT_RECURSIVE_STATE
  137.     std::cout   << "starting recursive_sum with : "
  138.                 << "coins(" << stringfy_numbers(coins) << ") "
  139.                 << "result(" << result << ") "
  140.                 << "numbers(" << stringfy_numbers(numbers) << ") "
  141.                 << "actual_sum(" << actual_sum << ") "
  142.                 << std::endl;
  143. #endif          
  144.    
  145.     for(auto& n: coins)
  146.     {
  147.         int nsum = actual_sum + n;
  148.         if(nsum == result)
  149.             insert_result(res, copy_insert(numbers, n));
  150.         else if(nsum < result)
  151.             recursive_sum(coins, result, res, copy_insert(numbers, n), nsum);
  152.     }
  153. }
  154.  
  155. void out_result(IN const ResultType& res)
  156. {
  157. #ifdef ENABLE_UNIQUE_RESULT
  158.     if(res.strings.empty())
  159. #else
  160.     if(res.empty())
  161. #endif
  162.     {
  163.         std::cout << "No results found." << std::endl;
  164.         return;
  165.     }
  166.    
  167.     std::cout << "Possible sums are: " << std::endl;
  168. #ifdef ENABLE_UNIQUE_RESULT
  169.     for(auto& r : res.strings)
  170. #else
  171.     for(auto& r : res)
  172. #endif
  173.         std::cout << r << std::endl;
  174. }
  175.  
  176. int main()
  177. {
  178.     ResultType res{};
  179.     std::vector<int> coins{};
  180.     int sum_result = 0;
  181.    
  182.     input_coins(coins);
  183.     input_sum_result(sum_result);
  184.     recursive_sum(coins, sum_result, res);
  185.     out_result(res);
  186.     return 0;
  187. }
  188.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement