Skip to content

Commit ae8685f

Browse files
Jxtophergithub-actionsPanquesito7
authored
feat: solving magic sequence problem with backtracking (TheAlgorithms#1533)
* Create magic_sequence.cpp * update code formatter * updating DIRECTORY.md * Update magic_sequence.cpp * Delete settings.json * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update magic_sequence.cpp * Revert "Delete settings.json" This reverts commit 64b08de. * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * clang-format and clang-tidy fixes for 2263f03 * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update magic_sequence.cpp * Update backtracking/magic_sequence.cpp * Update backtracking/magic_sequence.cpp * Update backtracking/magic_sequence.cpp * Update backtracking/magic_sequence.cpp * Update backtracking/magic_sequence.cpp * Update backtracking/magic_sequence.cpp * Update backtracking/magic_sequence.cpp * Update backtracking/magic_sequence.cpp * Update backtracking/magic_sequence.cpp * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update magic_sequence.cpp * Update magic_sequence.cpp * Update magic_sequence.cpp * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update magic_sequence.cpp * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * clang-format and clang-tidy fixes for f889fb4 * Update backtracking/magic_sequence.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update magic_sequence.cpp * fix: Apply suggestions from code review Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: David Leal <halfpacho@gmail.com>
1 parent 7bab516 commit ae8685f

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
## Backtracking
33
* [Graph Coloring](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/graph_coloring.cpp)
44
* [Knight Tour](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/knight_tour.cpp)
5+
* [Magic Sequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/magic_sequence.cpp)
56
* [Minimax](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/minimax.cpp)
67
* [N Queens](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/n_queens.cpp)
78
* [N Queens All Solution Optimised](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/n_queens_all_solution_optimised.cpp)

backtracking/magic_sequence.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
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> /// for std::count
19+
#include <cassert> /// for assert
20+
#include <iostream> /// for IO operations
21+
#include <list> /// for std::list
22+
#include <numeric> /// for std::accumulate
23+
#include <vector> /// for std::vector
24+
25+
/**
26+
* @namespace backtracking
27+
* @brief Backtracking algorithms
28+
*/
29+
namespace backtracking {
30+
/**
31+
* @namespace magic_sequence
32+
* @brief Functions for the [Magic
33+
* sequence](https://www.csplib.org/Problems/prob019/) implementation
34+
*/
35+
namespace magic_sequence {
36+
using sequence_t =
37+
std::vector<unsigned int>; ///< Definition of the sequence type
38+
/**
39+
* @brief Print the magic sequence
40+
* @param s working memory for the sequence
41+
*/
42+
void print(const sequence_t& s) {
43+
for (const auto& item : s) std::cout << item << " ";
44+
std::cout << std::endl;
45+
}
46+
47+
/**
48+
* @brief Check if the sequence is magic
49+
* @param s working memory for the sequence
50+
* @returns true if it's a magic sequence
51+
* @returns false if it's NOT a magic sequence
52+
*/
53+
bool 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+
62+
/**
63+
* @brief Sub-solutions filtering
64+
* @param s working memory for the sequence
65+
* @param depth current depth in tree
66+
* @returns true if the sub-solution is valid
67+
* @returns false if the sub-solution is NOT valid
68+
*/
69+
bool 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+
74+
/**
75+
* @brief Solve the Magic Sequence problem
76+
* @param s working memory for the sequence
77+
* @param ret list of the valid magic sequences
78+
* @param depth current depth in the tree
79+
*/
80+
void 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+
98+
/**
99+
* @brief Self-test implementations
100+
* @returns void
101+
*/
102+
static 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+
114+
/**
115+
* @brief Main function
116+
* @returns 0 on exit
117+
*/
118+
int 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+
}

0 commit comments

Comments
 (0)