TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
magic_sequence.cpp
1/*
2 * @brief [Magic sequence](https://www.csplib.org/Problems/prob019/)
3 * implementation
4 *
5 * @details Solve the magic sequence problem with backtracking
6 *
7 * "A magic sequence of length $n$ is a sequence of integers $x_0
8 * \ldots x_{n-1}$ between $0$ and $n-1$, such that for all $i$
9 * in $0$ to $n-1$, the number $i$ occurs exactly $x_i$ times in
10 * the sequence. For instance, $6,2,1,0,0,0,1,0,0,0$ is a magic
11 * sequence since $0$ occurs $6$ times in it, $1$ occurs twice, etc."
12 * Quote taken from the [CSPLib](https://www.csplib.org/Problems/prob019/)
13 * website
14 *
15 * @author [Jxtopher](https://github.com/Jxtopher)
16 */
17
18#include <algorithm>
19#include <cassert>
20#include <iostream>
21#include <list>
22#include <numeric>
23#include <vector>
24
29namespace backtracking {
35namespace magic_sequence {
36using sequence_t =
37 std::vector<unsigned int>;
42void print(const sequence_t& s) {
43 for (const auto& item : s) std::cout << item << " ";
44 std::cout << std::endl;
45}
46
53bool is_magic(const sequence_t& s) {
54 for (unsigned int i = 0; i < s.size(); i++) {
55 if (std::count(s.cbegin(), s.cend(), i) != s[i]) {
56 return false;
57 }
58 }
59 return true;
60}
61
69bool filtering(const sequence_t& s, unsigned int depth) {
70 return std::accumulate(s.cbegin(), s.cbegin() + depth,
71 static_cast<unsigned int>(0)) <= s.size();
72}
73
80void solve(sequence_t* s, std::list<sequence_t>* ret, unsigned int depth = 0) {
81 if (depth == s->size()) {
82 if (is_magic(*s)) {
83 ret->push_back(*s);
84 }
85 } else {
86 for (unsigned int i = 0; i < s->size(); i++) {
87 (*s)[depth] = i;
88 if (filtering(*s, depth + 1)) {
89 solve(s, ret, depth + 1);
90 }
91 }
92 }
93}
94
95} // namespace magic_sequence
96} // namespace backtracking
97
102static void test() {
103 // test a valid magic sequence
104 backtracking::magic_sequence::sequence_t s_magic = {6, 2, 1, 0, 0,
105 0, 1, 0, 0, 0};
106 assert(backtracking::magic_sequence::is_magic(s_magic));
107
108 // test a non-valid magic sequence
109 backtracking::magic_sequence::sequence_t s_not_magic = {5, 2, 1, 0, 0,
110 0, 1, 0, 0, 0};
111 assert(!backtracking::magic_sequence::is_magic(s_not_magic));
112}
113
118int main() {
119 test(); // run self-test implementations
120
121 // solve magic sequences of size 2 to 11 and print the solutions
122 for (unsigned int i = 2; i < 12; i++) {
123 std::cout << "Solution for n = " << i << std::endl;
124 // valid magic sequence list
125 std::list<backtracking::magic_sequence::sequence_t> list_of_solutions;
126 // initialization of a sequence
127 backtracking::magic_sequence::sequence_t s1(i, i);
128 // launch of solving the problem
129 backtracking::magic_sequence::solve(&s1, &list_of_solutions);
130 // print solutions
131 for (const auto& item : list_of_solutions) {
132 backtracking::magic_sequence::print(item);
133 }
134 }
135 return 0;
136}
int main()
Main function.
bool solve(int x, int y, int mov, std::array< std::array< int, V >, V > &sol, const std::array< int, V > &xmov, std::array< int, V > &ymov)
for vector container
Functions for the Magic sequence implementation.