exercise 3.6 The Josephus problem is the following game: N people, numbered 1 to N, are sitting in a circle. Starting at person 1, a hot potato is passed. After M passes, the person holding the hot potato is eliminated, the circle closes ranks, and the game continues with the person who was sitting after the eliminated person picking up the hot potato. The last remaining person wins. Thus, if M = 0 and N = 5, players are eliminated in order, and player 5 wins. if M = 1 and N = 5, the order of elimination is 2, 4, 1, 5.
a. Write aprogram to solve the Josephus problem for general values of M and N. Try to make your program as efficient as possible. Make sure you dispose of cells.
b. What is the running time of your program?
//list.hpp
#ifndef LIST_HPP__
#define LIST_HPP__
#include <iostream>
#include <cassert>
template<typename Object>
class List {
private:
class Node {
public:
Node(const Object& d = Object(), Node* p = 0, Node* n = 0) : data(d), next(n), prev(p) {}
public:
Object data;
Node* next;
Node* prev;
};
public:
class Const_Iterator {
public:
Const_Iterator() : current(0){}
const Object& operator* () const { return retrieve(); }
Const_Iterator& operator++()
{
current = current->next;
return *this;
}
Const_Iterator& operator++(int)
{
Const_Iterator old = *this;
++(*this);
return old;
}
Const_Iterator& operator--()
{
current = current->prev;
return *this;
}
Const_Iterator& operator--(int)
{
Const_Iterator old = *this;
--(*this);
return old;
}
bool operator==(const Const_Iterator& rhs) const
{
return current == rhs.current;
}
bool operator!=(const Const_Iterator& rhs) const
{
return !(*this == rhs);
}
protected:
Node* current;
Object& retrieve() const { return current->data; }
Const_Iterator(Node* p) :current(p) {}
friend class List<Object>;
};
class Iterator : public Const_Iterator {
public:
Iterator(){}
Object& operator*() { return retrieve(); }
Object& operator*() const { return retrieve(); }
Iterator& operator++()
{
current = current->next;
return *this;
}
Iterator& operator++(int)
{
Node old = *this;
++(*this);
return old;
}
Iterator& operator--()
{
current = current->prev;
return *this;
}
Iterator& operator--(int)
{
Node old = *this;
--(*this);
return old;
}
bool operator==(const Iterator& rhs) const
{
return current == rhs.current;
}
bool operator!=(const Iterator& rhs) const
{
return !(*this == rhs);
}
private:
Iterator(Node *p) : Const_Iterator(p) {}
friend class List<Object>;
};
public:
List()
{
init();
}
List(const List& rhs)
{
init();
*this = rhs;
}
~List()
{
Clear();
delete head;
delete tail;
}
List& operator=(const List& rhs)
{
if(rhs == *this)
return *this;
Clear();
for(Const_Iterator it = rhs.Begin(); it != rhs.End(); ++ it)
Push_Back(*it);
return *this;
}
Iterator Begin() { return Iterator(head->next); }
Const_Iterator Begin() const { return Const_Iterator(head->next); }
Iterator End() { return Iterator(tail); }
Const_Iterator End() const { return Const_Iterator(tail); }
int Size() const { return theSize; }
bool Empty() const { return theSize == 0; }
void Clear()
{
while(!Empty())
Pop_Front();
}
Object& Front() { return *Begin(); }
const Object& Front() const { return *Begin(); }
Object& Back() { return *(--End()); }
const Object& Back() const { return *(--End()); }
void Push_Front(const Object& ob)
{
Insert(Begin(), ob);
}
void Push_Back(const Object& ob)
{
Insert(End(), ob);
}
void Pop_Front() { Erase(Begin()); }
void Pop_Back() { Erase(--End()); }
Iterator Insert(Iterator it, const Object& ob)
{
Node* p = it.current;
++theSize;
return Iterator(p->prev = p->prev->next = new Node(ob, p->prev, p));
}
Iterator Erase(Iterator it)
{
Node* p = it.current;
Iterator retVal(p->next);
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
--theSize;
return retVal;
}
Iterator Erase(Iterator start, Iterator end)
{
for(Iterator it = start; it != end; )
it = Erase(it);
return end;
}
private:
int theSize;
Node* head;
Node* tail;
void init()
{
theSize = 0;
head = new Node();
tail = new Node();
head->next = tail;
tail->prev = head;
}
};
#endif
//main.cpp
#include "list.hpp"
#include <iostream>
using namespace std;
int game(int people, int num)
{
int cnt = 0;
List<int> lst;
List<int>::Iterator it = lst.Begin();
for(int i = 1; i <= people; ++i)
lst.Push_Back(i);
while(lst.Size() > 1) //O(N)
{
if(it == lst.End())
it = lst.Begin();
if(cnt != num)
{
++cnt;
++it;
}
else
{
cnt = 0;
it = lst.Erase(it);
}
}
return *lst.Begin();
}
int main()
{
int ppl, pass;
cout << "Input number of people and passes: ";
cin >> ppl >> pass;
cout << "/nThe number of people you entered was: " << ppl
<< "/nand the passes was: " << pass << "/n";
cout << "People sits on the " << game(ppl, pass) << " wins/n";
return 0;
}