You are on page 1of 5

Josephus Problem Given a group of men arranged in a circle under the edict that every th man wi ll be executed going

around the circle until only one remains, find the position in which you should stand in order to be the last survivor (Ball and Coxeter 1 987). The list giving the place in the execution sequence of the first, second, etc. man can be given by Josephus[n, m] in the Mathematica package Combinatorica ` . For example, consider men numbered 1 to 4 such that each second ( ) man is iteratively slaughtered, as illustrated above. As can be seen, the first man is slaughtered 4th, the second man 1st, the third man 3rd, and the fourth man 2nd, so Josephus[4, 2] returns 4, 1, 3, 2 . To obtain the ordered list of men who are consecutively slaughtered, InversePerm utation can be applied to the output of Josephus. So, in the above example, Inve rsePermutation[Josephus[4, 2]] returns 2, 4, 3, 1 since the 2nd man is slaught ered first, the 4th man is slaughtered second, the 3rd man is slaughtered third, and the 1st man is slaughtered fourth. The original Josephus problem consisted of a circle of 41 men with every third m an killed ( , ), illustrated above, where the outer number indicates the order in which a given man is killed. In order for the lives of the last two men to be spared, they must be placed at positions 31 (last) and 16 (second-to-last). The complete list in order of execution is 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 1, 5, 10, 14, 19, 23, 28, 32, 37, 41, 7, 13, 20, 26, 34, 40, 8, 17, 29, 38, 11, 25, 2, 22, 4, 35, 16, 31. Program: /*-------------------------------------------Author : UTSAV CHATURVEDI utsavchaturvedi [AT] yahoo.com BHOPAL (M.P). ---------------------------------------------*/ #include typedef struct node { int soilder; struct node * next; }q; q sol_q; q *current,*head,*save; int tot_soilders=0; void freelist() { int i; current = head; for (i=1;inext; free(head); head = current; } } q * getnode() { q *temp; temp = (q *) malloc(sizeof(q)); if (temp == NULL) { printf("\n Memory allocation Failure");

exit(1); } else return(temp); } void create_list(int n) { q *temp; int i; if (nsoilder = 1; current->next = current; head = current; for (i=2;inext = temp; current = temp; current->soilder = i; } current->next = head; tot_soilders = n; } void display() { if (head == NULL) { printf("\nNo Soilders in the Queue"); return; } printf("%d",head->soilder); printf("%c ",2); current = head->next; while( current != head) { printf("%d";,current->soilder); printf("%c ",2); current = current->next; } return; } q *tail() { q *temp; current = head->next; while (current != head) { temp = current; current = current->next; } return(temp); } int left_after_sucide(int by_n) { int i=1,j,dead_sol; current = head; save = tail(); while (i<tot_soilders) { for (j=1;jnext;

} save->next = current->next; if (current == head) head = current->next; dead_sol = current->soilder; free(current); display(); printf("\n\n%d%c is Dead \n%c RIP",dead_sol,1,5); getch(); current = save->next; i++; } head = current; display(); tot_soilders = 1; return(head->soilder); } main() { int ch,n; head = NULL; do { printf("\n1. For printf("\n2. For printf("\n3. For printf("\n0. For scanf("%d",&ch);

soilder list creation"); Displaying soilder list"); Sucide"); Exit");

switch(ch) { case 1: printf("\nEnter the total no. of soilders"); scanf("%d",&n); create_list(n); break; case 2: display(); getch(); break; case 3: if (tot_soilders <= 1) printf("There Should Be Atleast 2 Soilders in the List"); else { printf("\nEnter the no by which sucide is to be commited"); scanf("%d",&n); if (n<1) printf("\nInvalid Number!"); else printf("\nThe only Soilder left after " "sucide session is %d%c",left_after_sucide(n),2); } getch(); break; case 0: return; default : printf("\nINVALID CHOICE"); getch();

} } while (ch!=0); freelist(); } Josephus Problem Imagine a game where N people stand on a circle. Every third person is eliminat ed from the circle until only one person remains. For example, with 6 people in the circle (labeled 1 through 6), the order of elimination would be: 3, 6, 4, 2, 5 and player 1 would be the last person standing. We can generalize the game by having every M-th person eliminated from the circl e. The original version of the problem corresponds to M = 3. We can define a f unction J(N, M) = label of the last player left standing in the circle in a ga me with N players labeled 1 through N where every M-th person gets eliminated. The case M = 2 has a particularly elegant solution. Let's tabulate J(N, 2) for several values of N: N 16 17 J(N,2) 1 3 18 2 3 19 ... 1 1 3 5 7 ... 1 4 1 5 3 6 5 7 7 8 1 9 3 10 5 11 7 12 9 13 11 14 13 15 15

A pattern clearly emerges: J(N,2) = 1 when N is a power of two. For N between two powers of two, the label of the last player left standing in the game takes on consecutive odd values 3, 5, 7, 9, 11, etc. Abbreviating J(N,2) to just J(N ), we have the following recurrence: J(1) = 1 J(2N) = 2J(N) - 1 for N >= 1 J(2N+1) = 2J(N) + 1 for N >= 1 J(N) can be easily computed from the binary expansion of N: if N = bmbm-1 ...b 2b1b0 in base 2, then J(N) = bm-1 ...b2b1b0bm. That is, J(N) is obtained from the binary expansion of N by a circular left shift of the binary digits of N. For example, when N = 14 = 1110, J(N) = 1101 = 13. The following program uses a circular linked list to compute J(N,M) for arbitrar y values of N and M: int main() { int N, struct struct int i,

M; node { int player_id; struct node *next; } node *p, *q; count;

printf("Enter N (number of players): "); scanf("%d", &N); printf("Enter M (every M-th payer gets eliminated): "); scanf("%d", &M); // Create circular linked list containing all the players: p = q = malloc(sizeof(struct node)); p->player_id = 1;

for (i = 2; i <= N; ++i) { p->next = malloc(sizeof(struct node)); p = p->next; p->player_id = i; } p->next = q; // Close the circular linked list by having the last node poin t to the first. // Eliminate every M-th player as long as more than one player remains: for (count = N; count > 1; --count) { for (i = 0; i < M - 1; ++i) p = p->next; p->next = p->next->next; // Remove the eiminated player from the circula r linked list. } printf("Last player left standing is %d\n.", p->player_id); return 0; }

You might also like