ResultType vector_comprehension(const std::vector<T>& in_vec, Function func) { ResultType result; result.reserve(in_vec.size()); for (auto& elem : in_vec) { result.push_back(func(elem)); } return result; }
std::vector<std::vector<int>> GetCombinationsIterative(const std::vector<int>& input) { typedef std::vector<std::vector<int>> ResultType; typedef std::vector<int> InputType; typedef std::vector<std::tuple<int, InputType>> ProblemType; typedef std::map<int, ProblemType> ProblemListType; typedef std::queue<InputType> LevelResultsType; ResultType result; ProblemListType problemTree; int currentLevel = input.size(); int startLevel = currentLevel; problemTree[currentLevel] = ProblemType { std::tuple<int, InputType> {0, input} }; InputType temp = input; int nodeNr = 1; while (currentLevel > 2) { problemTree[currentLevel - 1] = ProblemType{}; const auto& nodes = problemTree[currentLevel]; for (const auto& node : nodes) { temp = std::get<1>(node); for (const auto& element : temp) { std::vector<int> diffSet = temp; diffSet.erase(std::find(diffSet.begin(), diffSet.end(), element)); problemTree[currentLevel - 1].push_back(std::make_tuple(element, diffSet)); } } currentLevel = currentLevel - 1; } LevelResultsType resultsCurrentLevel; LevelResultsType resultsPreviousLevel; while (currentLevel < startLevel) { resultsCurrentLevel = {}; const auto& nodes = problemTree[currentLevel]; int partitionSize = currentLevel == 2 ? 2 : resultsPreviousLevel.size() / nodes.size(); for (const auto& node : nodes) { temp = std::get<1>(node); if (temp.size() == 2) { resultsPreviousLevel.push({ temp[0], temp[1] }); resultsPreviousLevel.push({ temp[1], temp[0] }); } for (int i = 0; i < partitionSize ; ++i) { auto& previousLevelResult = resultsPreviousLevel.front(); previousLevelResult.insert(previousLevelResult.begin(), std::get<0>(node)); resultsCurrentLevel.push(resultsPreviousLevel.front()); resultsPreviousLevel.pop(); } } resultsPreviousLevel = resultsCurrentLevel; ++currentLevel; } while (!resultsCurrentLevel.empty()) { result.push_back(resultsCurrentLevel.front()); resultsCurrentLevel.pop(); } return result; }