1
1
/*
2
2
* @brief [Magic sequence](https://www.csplib.org/Problems/prob019/) implementation
3
3
*
4
- * @details
4
+ * @details Solve the magic sequence problem with a backtraking
5
+ *
6
+ * "A magic sequence of length $n$ is a sequence of integers $x_0
7
+ * \ldots x_{n-1}$ between $0$ and $n-1$, such that for all $i$
8
+ * in $0$ to $n-1$, the number $i$ occurs exactly $x_i$ times in
9
+ * the sequence. For instance, $6,2,1,0,0,0,1,0,0,0$ is a magic
10
+ * sequence since $0$ occurs $6$ times in it, $1$ occurs twice, etc."
11
+ * Quote of https://www.csplib.org/Problems/prob019/
5
12
*
6
13
* @author [Jxtopher](https://github.com/jxtopher)
7
14
*/
8
15
9
- #include < algorithm>
10
- #include < cassert>
11
- #include < iostream>
12
- #include < list>
13
- #include < numeric>
14
- #include < vector>
16
+ #include < algorithm> // / std::count
17
+ #include < cassert> // / assert
18
+ #include < iostream> // / IO operations
19
+ #include < list> // / std::list
20
+ #include < numeric> // / std::accumulate
21
+ #include < vector> // / std::vector
15
22
23
+ /* *
24
+ * @namespace
25
+ * @brief Backtracking algorithms
26
+ */
16
27
namespace backtracking {
28
+
29
+ /* *
30
+ * @namespace
31
+ * @brief Definition and solve magic sequence problem
32
+ */
17
33
namespace magic_sequence {
18
34
using sequence_t = std::vector<unsigned int >;
19
35
36
+
37
+ /* *
38
+ * @brief print a magic sequence
39
+ *
40
+ * @param s a magic sequence
41
+ */
20
42
void print (const sequence_t & s) {
21
43
for (const auto & item : s) std::cout << item << " " ;
22
44
std::cout << std::endl;
23
45
}
24
46
25
- // Check if it's a magic sequence
47
+ /* *
48
+ * @brief Check if it's a magic sequence
49
+ *
50
+ * @param s a magic sequence
51
+ * @return true if is a magic sequence
52
+ * @return false otherwise
53
+ *
54
+ */
26
55
bool is_magic (const sequence_t & s) {
27
56
for (unsigned int i = 0 ; i < s.size (); i++) {
28
57
if (std::count (s.cbegin (), s.cend (), i) != s[i]) {
@@ -32,13 +61,28 @@ bool is_magic(const sequence_t& s) {
32
61
return true ;
33
62
}
34
63
35
- // Filtering of sub-solutions
36
- // true if the sub-solution is valid otherwise false
64
+ /* *
65
+ * @brief Filtering of sub-solutions
66
+ *
67
+ * @param s a magic sequence
68
+ * @param depth
69
+ * @return true if the sub-solution is valid
70
+ * @return false otherwise
71
+ *
72
+ */
37
73
bool filtering (const sequence_t & s, unsigned int depth) {
38
74
return std::accumulate (s.cbegin (), s.cbegin () + depth,
39
75
static_cast <unsigned int >(0 )) <= s.size ();
40
76
}
41
77
78
+ /* *
79
+ * @brief solve magic squance problem
80
+ *
81
+ * @param s a magic sequence
82
+ * @param ret list of valid magic sequences
83
+ * @param depth depth in the tree
84
+ *
85
+ */
42
86
void solve (sequence_t * s, std::list<sequence_t >* ret, unsigned int depth = 0 ) {
43
87
if (depth == s->size ()) {
44
88
if (is_magic (*s)) {
@@ -58,6 +102,11 @@ void solve(sequence_t* s, std::list<sequence_t>* ret, unsigned int depth = 0) {
58
102
59
103
} // namespace backtracking
60
104
105
+
106
+ /* *
107
+ * @brief tests
108
+ *
109
+ */
61
110
static void test () {
62
111
backtracking::magic_sequence::sequence_t s_magic = {6 , 2 , 1 , 0 , 0 ,
63
112
0 , 1 , 0 , 0 , 0 };
0 commit comments