#include #include #include #include #include std::string join(const std::string& delimiter, const std::vector& list) { return list.empty() ? "" : std::accumulate(++list.begin(), list.end(), list[0], [delimiter](auto& a, auto& b) { return a + delimiter + b; }); } std::vector amb(std::function func, std::vector> options, std::string previous) { if ( options.empty() ) { return std::vector(); } for ( std::string& option : options.front() ) { if ( ! previous.empty() && ! func(previous, option) ) { continue; } if ( options.size() == 1 ) { return std::vector(1, option); } std::vector> next_options(options.begin() + 1, options.end()); std::vector result = amb(func, next_options, option); if ( ! result.empty() ) { result.emplace(result.begin(), option); return result; } } return std::vector(); } std::string Amb(std::vector> options) { std::function continues = [](std::string before, std::string after) { return before.back() == after.front(); }; std::vector amb_result = amb(continues, options, ""); return ( amb_result.empty() ) ? "No match found" : join(" ", amb_result); } int main() { std::vector> words = { { "the", "that", "a" }, { "frog", "elephant", "thing" }, { "walked", "treaded", "grows" }, { "slowly", "quickly" } }; std::cout << Amb(words) << std::endl; }