Description of the Problem:
In this java tutorial we discuss about Josephus problem and its solution.
The Josephus Problem is a famous mathematical puzzle that goes back to ancient times. There are many stories to go with the puzzle. One is that Josephus was one of a group of Jews who were about to be captured by the Romans. Rather than be enslaved, they chose to commit suicide. They arranged themselves in a circle and, starting at a certain person, started counting off around the circle. Every nth person had to leave the circle and commit suicide.
Josephus decided he didn’t want to die, so he arranged the rules so he would be the last person left.
If there were (say) 20 people, and he was the seventh
person from the start of the circle, what number should he tell them to use for counting off?
The problem is made much more complicated because the circle
shrinks as the counting continues.
Inputs are the number of people in the circle, the number used for counting off, and the number of the person where counting starts (usually 1). The output is the list of persons being eliminated.
When a person drops out of the circle, counting starts again from the person
who was on his left (assuming you go around clockwise).
Here’s an example.
There are seven people numbered 1 through 7, and you start at 1 and count off
by threes. People will be eliminated in the order 4, 1, 6, 5, 7, 3. Number 2 will remain at last
Solution of the Problem:
This problem can be solved by using a circular linked list. Complete listing of the java code is given below:
Code for Circular linked list with some modified method(game())
package techy.rajeev;
public class CircularLinkedList {
private Node start;
private int count;
public void append(int x){
count++;
Node temp=new Node(x);
if(start==null){
start=temp;
}else{
Node tp=start;
while(tp.link!=start){
tp=tp.link;
}
tp.link=temp;
}
temp.link=start;
}
public void addBeg(int x){
count++;
Node temp=new Node(x);
if(start==null){
temp.link=temp;
}else{
Node tp=start;
while(tp.link!=start){
tp=tp.link;
}
tp.link=temp;
temp.link=start;
}
start=temp;
}
public void addAt(int pos,int x){
Node temp,tp;
temp=new Node(x);
tp=start;
for(int i=1;i<=pos;i++){
if(tp.link==start)
break;
tp=tp.link;
}
temp.link=tp.link;
tp.link=temp;
count++;
}
public void displayList(){
if(start==null)
System.out.println("List is empty..");
else{
Node temp=start;
System.out.print("->");
while(temp.link!=start){
System.out.println(" "+temp.data);
temp=temp.link;
}
System.out.println(temp.data+" ->");
}
}
public void deleteAt(int position){
Node current=start;
Node previous=start;
for(int i=0;i<position;i++){
if(current.link==start)
break;
previous=current;
current=current.link;
}
System.out.print(current.data);
if(position==0)
deleteFirst();
else
previous.link=current.link;
count--;
}
public int deleteNode(Node node){
Node current=start;
Node previous=start;
int data=node.data;
while(current.data!=data){
if(current.link==start)
break; // Node does not exists in circular linked list
previous=current;
current=current.link;
}
previous.link=current.link;
count--;
return data;//returning the deleted data
}
public void deleteFirst() {
Node temp=start;
while(temp.link!=start){
temp=temp.link;
}
temp.link=start.link;
start=start.link;
count--;
}
public int getCount(){
return count;
}
/* Extra method for Josephus problem */
public void game(int countToDeath,int persons){
Node current=start;
int caller=0;
while(true){
caller=current.data;
System.out.print(caller+"Says->");
for(int i=0;i<countToDeath;i++){
current=current.link;
}
start=current.link;
if(getCount()>1){
// comparing caller with person going to be dead
if(caller==current.data)
System.out.println("WTF!! I will have to kill myself ! :( "
+deleteNode(current));
else
System.out.println("I do not want to say but you must die Mr. no:"
+deleteNode(current));
}else{
System.out.println("Thank God ! I saved myself :)");
break;
}
current=start;
}
}
private static class Node{
int data;
Node link;
public Node(int data){
this.data=data;
}
@SuppressWarnings("unused")
public Node(int data,Node link){
this.data=data;
this.link=link;
}
}
}
Code for main class:
package techy.rajeev;
import java.util.Scanner;
public class Josephus {
private CircularLinkedList cl;
private int noOfPersons;
private int countToDeath;
public void setInts(){
System.out.print("Enter the no. of people:");
Scanner in=new Scanner(System.in);
noOfPersons=in.nextInt();
System.out.print("Enter the count to death:");
countToDeath=in.nextInt();
}
public void buildCircularLinkedList(){
cl=new CircularLinkedList();
for(int i=1;i<=noOfPersons;i++)
cl.append(i);
cl.displayList();
}
public void startTheGame(){
cl.game(countToDeath, noOfPersons);
System.out.print("Lucky fellow was:");cl.displayList();
}
public static void main(String args[]){
Josephus js=new Josephus();
js.setInts();
js.buildCircularLinkedList();
js.startTheGame();
}
}
Output for a test case:
Enter the no. of people:7
Enter the count to death:3
-> 1
2
3
4
5
6
7 ->
1Says->I do not want to say but you must die Mr. no:4
5Says->I do not want to say but you must die Mr. no:1
2Says->I do not want to say but you must die Mr. no:6
7Says->I do not want to say but you must die Mr. no:5
7Says->WTF!! I will have to kill myself ! :( 7
2Says->I do not want to say but you must die Mr. no:3
2Says->Thank God ! I saved myself :)
Lucky fellow was:->2 ->
More on this at
techcresendo.com
Read More ->>