The Josephus Problem

Nishant Arora 06/Mar/2013
Facebook
Twitter
LinkedIn
Reddit

Across some programming challenge boards there lies many problems which are actually a variation of this beautiful problem. The text for this problem as stated by Wikipedia is as follows:

There are people standing in a circle waiting to be executed. The counting out begins at some point in the circle and proceeds around the circle in a fixed direction. In each step, a certain number of people are skipped and the next person is executed. The elimination proceeds around the circle (which is becoming smaller and smaller as the executed people are removed), until only the last person remains, who is given freedom.

The task is to choose the place in the initial circle so that you are the last one remaining and so survive.

Though I believe the interested guys would like to do more research on this, I spent a fair share of time with one of my colleagues and friend Ankit to figure this out. Wikipedia actually shows the theorems required to prove this mathematical equation, here is the implementation in Python.

Approach 1: My initial approach was to run a loop which can actually yield out the required results:

def josephus( n, k):
   r = 0
   i = 2
   while i <= n:
     r = (r + k) % i;
     i+= 1
   return r+1

this is a O(n) solution, which will solve your problem, but will run for very long as compared to other approaches. Run this on IdeOne.

Approach 2: Recursive solution was something everyone was talking about:

def josephus( n, k):
   if n ==1:
     return 1
   else:
     return ((josephus(n-1,k)+k-1) % n)+1

but even that is O(n) solution and in cases where k is very small and n is very large, Python may even run out of memory. Run this on IdeOne.

Approach 3: Also known as the Josephus Extended Problem, if k=2 and n is very large, the problem can be solved in O(k logn). Wikipedia has the theorem to prove this, the function is just so simple:

from math import log
  def josephus_2( n ):
    return 2*(n - 2**(int(log(n,2))))+1

this is the best approach possible and the fastest one yet. Run this on IdeOne.

I also edited the wiki to have these solutions here Josephus Problem Wikipedia

Cheers, Lemme know of a better approach!