From dc409b79c15ac88e3911935e6114a9215e36ae07 Mon Sep 17 00:00:00 2001 From: Bulakh Igor Date: Sun, 8 Sep 2019 05:31:08 +0300 Subject: [PATCH] josephus permutation is done --- josephus_permutation/josephus_permutation.cpp | 102 +++++++++++------- josephus_permutation/solution.cpp | 35 ++++++ 2 files changed, 100 insertions(+), 37 deletions(-) create mode 100644 josephus_permutation/solution.cpp diff --git a/josephus_permutation/josephus_permutation.cpp b/josephus_permutation/josephus_permutation.cpp index f940392..fbea1a3 100644 --- a/josephus_permutation/josephus_permutation.cpp +++ b/josephus_permutation/josephus_permutation.cpp @@ -15,46 +15,46 @@ using namespace std; template void MakeJosephusPermutation(RandomIt first, RandomIt last, uint32_t step_size) { -// deque pool(make_move_iterator(first), make_move_iterator(last)); -// -// size_t cur_pos = 0; -// while (!pool.empty()) { -// *(first++) = move(pool[cur_pos]); -// pool.erase(pool.begin() + cur_pos); -// if (pool.empty()) { -// break; -// } -//// cout << cur_pos << " " << step_size << " " << pool.size() << " " << (last - first) << endl; -// cur_pos = (cur_pos + step_size - 1) % pool.size(); -// } +/* deque pool(make_move_iterator(first), make_move_iterator(last)); -// list pool(make_move_iterator(first), make_move_iterator(last)); -// list pool; -// move(first,last,back_inserter(pool)); -// -// auto it = pool.begin(); -// -// while (!pool.empty()) { -// -// *(first++) = move(*it); -// it = pool.erase(it); -// if (pool.empty()) { -// break; -// } -// -// size_t dist = distance(it, pool.end()); -// -// if (dist <= step_size - 1) { -// it = pool.begin(); -// if (next(it) != pool.end()) { -// it = next(it, step_size - dist - 1); -// } -// } else { -// it = next(it, step_size - 1); -// } -// } + size_t cur_pos = 0; + while (!pool.empty()) { + *(first++) = move(pool[cur_pos]); + pool.erase(pool.begin() + cur_pos); + if (pool.empty()) { + break; + } +// cout << cur_pos << " " << step_size << " " << pool.size() << " " << (last - first) << endl; + cur_pos = (cur_pos + step_size - 1) % pool.size(); + } + list pool(make_move_iterator(first), make_move_iterator(last)); list pool; + move(first,last,back_inserter(pool)); + + auto it = pool.begin(); + + while (!pool.empty()) { + + *(first++) = move(*it); + it = pool.erase(it); + if (pool.empty()) { + break; + } + + size_t dist = distance(it, pool.end()); + + if (dist <= step_size - 1) { + it = pool.begin(); + if (next(it) != pool.end()) { + it = next(it, step_size - dist - 1); + } + } else { + it = next(it, step_size - 1); + } + }*/ + + /*list pool; move(first, last, back_inserter(pool)); size_t cur_pos = 0; size_t pred_pos = 0; @@ -75,8 +75,36 @@ void MakeJosephusPermutation(RandomIt first, RandomIt last, uint32_t step_size) pred_pos = cur_pos; cur_pos = (cur_pos + step_size - 1) % pool.size(); + }*/ + + const uint32_t range_size = last - first; + if (range_size <= 2) { + return; } + vector next_alive_positions(range_size); + iota(begin(next_alive_positions), end(next_alive_positions), 1); + next_alive_positions.back() = 0; + + vector permutation; + uint32_t current_position = 0; + uint32_t prev_alive_position = range_size - 1; + + for (uint32_t step_index = 0; step_index < range_size; ++step_index) { + permutation.push_back(move(*(first + current_position))); + next_alive_positions[prev_alive_position] = next_alive_positions[current_position]; + for (uint32_t i = 0; i < step_size; ++i) { + if (i > 0) { + prev_alive_position = current_position; + } + current_position = next_alive_positions[current_position]; + } + } +// for (uint32_t i = 0; i < range_size; ++i, ++first) { +// *first = move(permutation[i]); +// } + + move(begin(permutation), end(permutation), first); } vector MakeTestVector() { diff --git a/josephus_permutation/solution.cpp b/josephus_permutation/solution.cpp new file mode 100644 index 0000000..bc65802 --- /dev/null +++ b/josephus_permutation/solution.cpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +using namespace std; + + +// Вспомогательная функция, позволяющая «зациклить» список +template +ForwardIt LoopIterator(Container& container, ForwardIt pos) { + return pos == container.end() ? container.begin() : pos; +} + +template +void MakeJosephusPermutation(RandomIt first, RandomIt last, + uint32_t step_size) { + list pool; + for (auto it = first; it != last; ++it) { + pool.push_back(move(*it)); + } + auto cur_pos = pool.begin(); + while (!pool.empty()) { + *(first++) = move(*cur_pos); + if (pool.size() == 1) { + break; + } + const auto next_pos = LoopIterator(pool, next(cur_pos)); + pool.erase(cur_pos); + cur_pos = next_pos; + for (uint32_t step_index = 1; step_index < step_size; ++step_index) { + cur_pos = LoopIterator(pool, next(cur_pos)); + } + } +}