Josephus Problem Using Bit Magic
Last Updated :
15 Nov, 2022
The Problem
This problem is named after Flavius Josephus a Jewish historian who fought against the Romans. According to Josephus he and his group of Jewish soldiers were cornered & surrounded by the Romans inside a cave, and they choose to murder and suicide inside of surrender and capture. They decided that all the soldiers will sit in a circle and starting from the soldier sitting at the first position every soldier will kill the soldier to their sequentially. So if there are 5 soldiers sitting in a circle with positions numbered as 1, 2, 3, 4, 5. The soldier 1 kills 2, then 3 kills 4, then 5 kills 1, then 3 kills 5, and since 3 is the only one left then 3 commits suicide.
Now Josephus doesn’t want to get murdered or commit suicide. He would rather be captured by the Romans and is presented with a problem. He has to figure out at which position should he sit in a circle (provided there are n men in total and the man sitting at position 1 gets the first chance to murder) so that he is the last man standing and instead of committing suicide he will surrender to the Romans.
The Pattern
If you work this out for different values of n you will find a pattern here. If n is a true power of 2 then the answer is always 1. For every n greater than that power of 2 the answer is incremented by 2.
n soldiers |
2a+ l |
Survivor W(n) = 2l + 1 |
1 |
1 + 0 |
2 * 0 + 1 = 1 |
2 |
2 + 0 |
2 * 0 + 1 = 1 |
3 |
2 + 1 |
2 * 1 + 1 = 3 |
4 |
4 + 0 |
2 * 0 + 1 = 1 |
5 |
4 + 1 |
2 * 1 + 1 = 3 |
6 |
4 + 2 |
2 * 2 + 1 = 5 |
7 |
4 + 3 |
2 * 3 + 1 = 7 |
8 |
8 + 0 |
2 * 0 + 1 = 1 |
9 |
8 + 1 |
2 * 1 + 1 = 3 |
10 |
8 + 2 |
2 * 2 + 1 = 5 |
11 |
8 + 3 |
2 * 3 + 1 = 7 |
12 |
8 + 4 |
2 * 4 + 1 = 9 |
Now for every n, the right position for Josephus can be found out by deducting the biggest possible power of 2 from the number and we get the answer (provided that value of n is not a pure power of 2 otherwise the answer is 1)
N = 2a + something
where a = the biggest possible power
The Trick
Whenever someone talks about the powers of 2 the first word that comes to mind is “binary”. The solution to this problem is much is easier and shorter in binary than in decimal. There is a trick to this. Since we need to deduct the biggest possible power of in binary that number is the Most Significant Bit. In the original Josephus problem, there were 40 other soldiers along with Josephus which makes n = 41. 41 in binary is 101001. If we shift the MSB i.e. the leftmost 1 to the rightmost place we get 010011 which is 19 (in decimal) which is the answer. This is true for all cases. This can be done easily using bit manipulation.
C++
#include <bits/stdc++.h>
using namespace std;
int msbPos( int n)
{
int pos = 0;
while (n != 0) {
pos++;
n = n >> 1;
}
return pos;
}
int josephify( int n)
{
int position = msbPos(n);
int j = 1 << (position - 1);
n = n ^ j;
n = n << 1;
n = n | 1;
return n;
}
int main()
{
int n = 41;
cout <<josephify(n);
return 0;
}
|
C
#include <stdio.h>
int msbPos( int n)
{
int pos = 0;
while (n != 0) {
pos++;
n = n >> 1;
}
return pos;
}
int josephify( int n)
{
int position = msbPos(n);
int j = 1 << (position - 1);
n = n ^ j;
n = n << 1;
n = n | 1;
return n;
}
int main()
{
int n = 41;
printf ( "%d\n" , josephify(n));
return 0;
}
|
Java
public class GFG
{
static int msbPos( int n)
{
int pos = 0 ;
while (n != 0 ) {
pos++;
n = n >> 1 ;
}
return pos;
}
static int josephify( int n)
{
int position = msbPos(n);
int j = 1 << (position - 1 );
n = n ^ j;
n = n << 1 ;
n = n | 1 ;
return n;
}
public static void main(String[] args)
{
int n = 41 ;
System.out.println(josephify(n));
}
}
|
Python3
def msbPos(n):
pos = 0
while n ! = 0 :
pos + = 1
n = n >> 1
return pos
def josephify(n):
position = msbPos(n)
j = 1 << (position - 1 )
n = n ^ j
n = n << 1
n = n | 1
return n
n = 41
print (josephify(n))
|
C#
using System;
public class GFG
{
static int msbPos( int n)
{
int pos = 0;
while (n != 0) {
pos++;
n = n >> 1;
}
return pos;
}
static int josephify( int n)
{
int position = msbPos(n);
int j = 1 << (position - 1);
n = n ^ j;
n = n << 1;
n = n | 1;
return n;
}
public static void Main()
{
int n = 41;
Console.WriteLine(josephify(n));
}
}
|
PHP
<?php
function msbPos( $n )
{
$pos = 0;
while ( $n != 0)
{
$pos ++;
$n = $n >> 1;
}
return $pos ;
}
function josephify( $n )
{
$position = msbPos( $n );
$j = 1 << ( $position - 1);
$n = $n ^ $j ;
$n = $n << 1;
$n = $n | 1;
return $n ;
}
$n = 41;
print (josephify( $n ));
?>
|
Javascript
<script>
function msbPos(n)
{
var pos = 0;
while (n != 0) {
pos++;
n = n >> 1;
}
return pos;
}
function josephify(n)
{
var position = msbPos(n);
var j = 1 << (position - 1);
n = n ^ j;
n = n << 1;
n = n | 1;
return n;
}
var n = 41;
document.write(josephify(n));
</script>
|
Time Complexity: O(log n)
Auxiliary Space: O(1)
Another Approach: If we see carefully we can see a pattern, if we represent any number in the form of (2a + L) then the answer will be (2*L + 1).
Below is the code implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int josephify( int n)
{
int ans = log2(n);
int l = n - pow (2, ans);
return 2 * l + 1;
}
int main()
{
int n = 41;
cout << josephify(n);
return 0;
}
|
Java
public class GFG {
static int josephify( int n)
{
int ans = ( int )(Math.log(n) / Math.log( 2 ));
int l = n - ( int )Math.pow( 2 , ans);
return 2 * l + 1 ;
}
public static void main(String[] args)
{
int n = 41 ;
System.out.print(josephify(n));
}
}
|
Python3
import math
def josephify(n):
ans = math.log(n, 2 );
ans = round (ans);
l = n - 2 * * ans;
return 2 * l + 1 ;
n = 41 ;
print (josephify(n));
|
C#
using System;
class GFG {
static int josephify( int n)
{
int ans = ( int )Math.Log(n, 2);
int l = n - ( int )Math.Pow(2, ans);
return 2 * l + 1;
}
public static void Main( string [] args)
{
int n = 41;
Console.Write(josephify(n));
}
}
|
Javascript
function josephify(n)
{
let ans = Math.log2(n);
ans = Math.round(ans);
let l = n - Math.pow(2, ans);
return 2 * l + 1;
}
let n = 41;
console.log(josephify(n));
|
Time Complexity: O(log(log(n))), for using pow() function.
Auxiliary Space: O(1)
Previous articles on the same topic:
- Josephus problem | Set 1 (A O(n) Solution)
- Josephus problem | Set 2 (A Simple Solution when k = 2)
Share your thoughts in the comments
Please Login to comment...