/* * @brief [Magic sequence](https://www.csplib.org/Problems/prob019/) * * @details * * @author [Jxtopher](https://github.com/jxtopher) */ #include #include #include #include #include #include namespace backtracking { namespace magic_sequence { using sequence_t = std::vector; void print(const sequence_t& s) { for(auto item : s) std::cout << item << " "; std::cout << std::endl; } // Check if it's a magic sequence bool is_magic(const sequence_t& s) { for(unsigned int i = 0; i < s.size(); i++) if(std::count(s.cbegin(), s.cend(), i) != s[i]) return false; return true; } // Filtering of sub-solutions // true if the sub-solution is valid otherwise false bool filtering(const sequence_t& s, unsigned int depth) { return std::accumulate(s.cbegin(), s.cbegin() + depth, static_cast(0)) <= s.size(); } void solve(sequence_t& s, std::list& ret, unsigned int depth = 0) { if(depth == s.size()) { if(is_magic(s)) ret.push_back(s); } else { for(unsigned int i = 0; i < s.size(); i++) { s[depth] = i; if(filtering(s, depth + 1)) solve(s, ret, depth + 1); } } } } // namespace magic_sequence } // namespace backtracking using namespace backtracking::magic_sequence; static void test() { sequence_t s_magic = {6, 2, 1, 0, 0, 0, 1, 0, 0, 0}; assert(is_magic(s_magic)); sequence_t s_not_magic = {5, 2, 1, 0, 0, 0, 1, 0, 0, 0}; assert(!is_magic(s_not_magic)); } int main() { test(); for(unsigned int i = 2; i < 12; i++) { std::cout << "Solution for n = " << i << std::endl; std::list r1; sequence_t s1(i, i); solve(s1, r1); for(auto item : r1) print(item); } }