Skip to content

Commit

Permalink
josephus permutation is done
Browse files Browse the repository at this point in the history
  • Loading branch information
puffikru committed Sep 8, 2019
1 parent a35ad95 commit dc409b7
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 37 deletions.
102 changes: 65 additions & 37 deletions josephus_permutation/josephus_permutation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,46 @@ using namespace std;

template<typename RandomIt>
void MakeJosephusPermutation(RandomIt first, RandomIt last, uint32_t step_size) {
// deque<typename RandomIt::value_type> 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<typename RandomIt::value_type> pool(make_move_iterator(first), make_move_iterator(last));
// list<typename RandomIt::value_type> pool(make_move_iterator(first), make_move_iterator(last));
// list<typename RandomIt::value_type> 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<typename RandomIt::value_type> pool(make_move_iterator(first), make_move_iterator(last));
list<typename RandomIt::value_type> 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<typename RandomIt::value_type> pool;
move(first, last, back_inserter(pool));
size_t cur_pos = 0;
size_t pred_pos = 0;
Expand All @@ -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<uint32_t> next_alive_positions(range_size);
iota(begin(next_alive_positions), end(next_alive_positions), 1);
next_alive_positions.back() = 0;

vector<typename RandomIt::value_type> 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<int> MakeTestVector() {
Expand Down
35 changes: 35 additions & 0 deletions josephus_permutation/solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <list>
#include <cstdint>
#include <iterator>
#include <utility>

using namespace std;


// Вспомогательная функция, позволяющая «зациклить» список
template <typename Container, typename ForwardIt>
ForwardIt LoopIterator(Container& container, ForwardIt pos) {
return pos == container.end() ? container.begin() : pos;
}

template <typename RandomIt>
void MakeJosephusPermutation(RandomIt first, RandomIt last,
uint32_t step_size) {
list<typename RandomIt::value_type> 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));
}
}
}

0 comments on commit dc409b7

Please sign in to comment.