Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <deque>
- #include <string>
- #include <algorithm>
- #include <numeric>
- #include <functional>
- #include <set>
- #ifndef OUT
- #define OUT
- #endif
- #ifndef IN
- #define IN
- #endif
- #define ENABLE_UNIQUE_RESULT
- #ifdef ENABLE_UNIQUE_RESULT
- struct ResultType
- {
- std::vector<std::string> strings;
- std::set<double> hashes;
- };
- #else
- typedef std::vector<std::string> ResultType;
- #endif
- void input_coins(OUT std::vector<int>& coins)
- {
- // printing existing coins (only if they exists)
- if(!coins.empty())
- {
- std::cout << "Actually coins are: { ";
- for(auto& c : coins)
- std::cout << c << ", ";
- std::cout << "}" << std::endl;
- }
- // outing what's needed right now
- std::cout << "Insert a number or 'next' to continue " << std::endl;
- std::string ans{};
- std::cin >> ans;
- // checking if ans is a number, next, or a wrong value
- if(auto iter = std::find_if(ans.begin(), ans.end(), [](auto c ){ return !isdigit(c); });
- iter != ans.end() || ans.empty())
- {
- if(ans != "next")
- {
- // repeating input_coins since value was wrong
- std::cout << "You have inserted a wrong value." << std::endl;
- input_coins(coins);
- }
- return;
- }
- // value looks correct, moving it into coins and repeating input_coins
- int value = atoi(ans.c_str());
- coins.emplace_back(value);
- input_coins(coins);
- }
- void input_sum_result(OUT int& result)
- {
- // outing what's needed right now
- std::cout << "Insert the sum result:" << std::endl;
- std::string ans{};
- std::cin >> ans;
- // checking if ans is a number or a wrong value
- if(auto iter = std::find_if(ans.begin(), ans.end(), [](auto c ){ return !isdigit(c); });
- iter != ans.end() || ans.empty())
- {
- // repeating input_sum_result since ans is a wrong value
- std::cout << "You have inserted a wrong value." << std::endl;
- input_sum_result(result);
- return;
- }
- // ans looks to be a number so assigning result the value
- result = atoi(ans.c_str());
- }
- template<template<class T> class ContainerType>
- std::string stringfy_numbers(IN const ContainerType<int>& numbers)
- {
- auto res = std::accumulate(numbers.begin(), numbers.end(), std::string("{"),
- [](auto& res, auto& v){ return res + std::to_string(v) + ", "; });
- res += "}";
- return res;
- }
- template<template<class T> class ContainerType>
- ContainerType<int> copy_insert(ContainerType<int> container, int num)
- {
- container.emplace_back(num);
- return container;
- }
- #ifdef ENABLE_UNIQUE_RESULT
- double hash_numbers(IN const std::deque<int>& numbers)
- {
- double hash = 1;
- for(auto& num : numbers)
- hash *= (1.0/static_cast<double>(num));
- return hash;
- }
- void insert_result(OUT ResultType& res, IN const std::deque<int>& numbers)
- {
- double hash = hash_numbers(numbers);
- if(res.hashes.find(hash) == res.hashes.end())
- {
- res.hashes.emplace(hash);
- res.strings.emplace_back(stringfy_numbers(numbers));
- }
- }
- #else
- void insert_result(OUT ResultType& res, IN const std::deque<int>& numbers)
- {
- res.emplace_back(stringfy_numbers(numbers));
- }
- #endif
- void recursive_sum( IN std::vector<int> coins,
- IN int result,
- OUT ResultType& res,
- IN std::deque<int> numbers = {},
- IN int actual_sum = 0)
- {
- #ifdef PRINT_RECURSIVE_STATE
- std::cout << "starting recursive_sum with : "
- << "coins(" << stringfy_numbers(coins) << ") "
- << "result(" << result << ") "
- << "numbers(" << stringfy_numbers(numbers) << ") "
- << "actual_sum(" << actual_sum << ") "
- << std::endl;
- #endif
- for(auto& n: coins)
- {
- int nsum = actual_sum + n;
- if(nsum == result)
- insert_result(res, copy_insert(numbers, n));
- else if(nsum < result)
- recursive_sum(coins, result, res, copy_insert(numbers, n), nsum);
- }
- }
- void out_result(IN const ResultType& res)
- {
- #ifdef ENABLE_UNIQUE_RESULT
- if(res.strings.empty())
- #else
- if(res.empty())
- #endif
- {
- std::cout << "No results found." << std::endl;
- return;
- }
- std::cout << "Possible sums are: " << std::endl;
- #ifdef ENABLE_UNIQUE_RESULT
- for(auto& r : res.strings)
- #else
- for(auto& r : res)
- #endif
- std::cout << r << std::endl;
- }
- int main()
- {
- ResultType res{};
- std::vector<int> coins{};
- int sum_result = 0;
- input_coins(coins);
- input_sum_result(sum_result);
- recursive_sum(coins, sum_result, res);
- out_result(res);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement