diff --git a/backtracking/magic_sequence.cpp b/backtracking/magic_sequence.cpp index 3798dc013..440e2cee8 100644 --- a/backtracking/magic_sequence.cpp +++ b/backtracking/magic_sequence.cpp @@ -1,28 +1,57 @@ /* * @brief [Magic sequence](https://www.csplib.org/Problems/prob019/) implementation * - * @details + * @details Solve the magic sequence problem with a backtraking + * + * "A magic sequence of length $n$ is a sequence of integers $x_0 + * \ldots x_{n-1}$ between $0$ and $n-1$, such that for all $i$ + * in $0$ to $n-1$, the number $i$ occurs exactly $x_i$ times in + * the sequence. For instance, $6,2,1,0,0,0,1,0,0,0$ is a magic + * sequence since $0$ occurs $6$ times in it, $1$ occurs twice, etc." + * Quote of https://www.csplib.org/Problems/prob019/ * * @author [Jxtopher](https://github.com/jxtopher) */ -#include -#include -#include -#include -#include -#include +#include /// std::count +#include /// assert +#include /// IO operations +#include /// std::list +#include /// std::accumulate +#include /// std::vector +/** + * @namespace + * @brief Backtracking algorithms + */ namespace backtracking { + +/** + * @namespace + * @brief Definition and solve magic sequence problem + */ namespace magic_sequence { using sequence_t = std::vector; + +/** + * @brief print a magic sequence + * + * @param s a magic sequence + */ void print(const sequence_t& s) { for (const auto& item : s) std::cout << item << " "; std::cout << std::endl; } -// Check if it's a magic sequence +/** + * @brief Check if it's a magic sequence + * + * @param s a magic sequence + * @return true if is a magic sequence + * @return false otherwise + * + */ 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]) { @@ -32,13 +61,28 @@ bool is_magic(const sequence_t& s) { return true; } -// Filtering of sub-solutions -// true if the sub-solution is valid otherwise false +/** + * @brief Filtering of sub-solutions + * + * @param s a magic sequence + * @param depth + * @return true if the sub-solution is valid + * @return false otherwise + * + */ bool filtering(const sequence_t& s, unsigned int depth) { return std::accumulate(s.cbegin(), s.cbegin() + depth, static_cast(0)) <= s.size(); } +/** + * @brief solve magic squance problem + * + * @param s a magic sequence + * @param ret list of valid magic sequences + * @param depth depth in the tree + * + */ void solve(sequence_t* s, std::list* ret, unsigned int depth = 0) { if (depth == s->size()) { if (is_magic(*s)) { @@ -58,6 +102,11 @@ void solve(sequence_t* s, std::list* ret, unsigned int depth = 0) { } // namespace backtracking + +/** + * @brief tests + * + */ static void test() { backtracking::magic_sequence::sequence_t s_magic = {6, 2, 1, 0, 0, 0, 1, 0, 0, 0};