In computer science and mathematics, the Josephus problem (or Josephus permutation) is a theoretical problem related to a certain counting-out game.
There are people standing in a circle waiting to be executed. After the first person is executed, certain number of people are skipped and one person is executed. Then again, people are skipped and a 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. If 2 are the number of people that are skipped
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | #!/usr/bin/env python
#let's speak about cladiators and the survivor (Josephus)
import sys
from math import log
CLDTRS_NUMBER = 0
last2first = lambda L : L[-1::] + L[0:len(L) -1]
def wholives(n):
## ---We search Within lowest-highest power of 2 that n Gladiators resides---
## wholives Function assumes that we have assigned each Gladiator a number in ascending order
## (in a way that Gladiators are ordered as they --have,need or must -- to. The numbers just follow their order)
## wholives is a FAST FUNCTION WITH CONSTANT TIME COMPLEXITY
## We calculate the log2 of the number of Gladiators if it is integer then we subtract one from the number raised in
## powers of 2 then we subtract the number of Gladiators from the base power and finally we subtract it from the number of
## Gladiators. If it the log2 is not integer we take the next exponent (successor) as Base
## The key here is that at every increment of exponent of power of 2 (minus 1) we can calculate all the previous Gladiators down to
## the previous exponent( minus 1) just by subtracting the nearest higher power of 2 (minus 1) and from Gladiators n and then
## subtracting the result from the Gladiators n itself.
## in order to select efficiently the correct nearest higher exponent we simply calculate the log2 of n Gladiators
## if it is integer we are in (we can use it as our Base exponent)
## it it is not then it means we need to take the next higher exponent for our Base exponent
## we are not interesting into any result of log2 of n Gladiators that is not integer since the subtractions
## between the limits of the lower power and higher power can give us the result
#there are two base cases
# if there are two Gladiators the first survives because he has the Sword
# if there is only one Gladiator ..he is already the Survivor...
if n == 1:
return 1
if n == 2:
return 1
LogN = log(n,2)
if not LogN.is_integer():
BaseExpo = int(LogN) + 1
BasePower = int(pow(2,BaseExpo)) - 1
Sub = BasePower - n
Res = n - Sub
return Res
else:
#Here we need to restart counting
#eg 7 lives 7 (2^3 -1) ,15 lives 15 (2^4 -1) ,31 lives 31 (2^5 -1) ,63 lives 63 (2^6 -1)\
# 127 lives 127 (2^7 -1 ) so we can just return 1 to restart at 8 , 16 , 32, 64, 128 respectively
# and so on and so forth...
#BaseExpo = int(LogN)
#BasePower = int(pow(2,BaseExpo)) - 1
#Sub = BasePower - n
#Res = n - Sub
#return Res
return 1
def isNotEven(x):
if not x % 2:
return False
else:
return True
def PrepareCladiators(NUMBER):
cladiators = tuple(xrange(1,NUMBER + 1))
return cladiators
def Survivor(cladiators):
if len(cladiators) < 2:
raise Exception ,"\n\n***** Cladiators must be at least 2!!! ***** \n"
##
##
## print"\nCeasar says:\n\tLET THE DEATH MATCH BEGIN!!!\
## \n\nThey started kiling each other... \nEach one kills the next one\
## \nand passes the Sword to the next one alive.. \
## \nthere are all",len(cladiators)," still alive and here they are \n" ,cladiators
FirstClads = len(cladiators)
Clads = cladiators
deathcycle =0
while len(Clads) > 1 :
if isNotEven(len(Clads)):
deathcycle += 1
Clads = Clads[::2]
Clads = last2first(Clads)
##
## print "\n",len(Clads), "left alive after the",deathcycle,"death cycle and "\
## ,FirstClads - len(Clads)," have died till know"
## print "\nThese are the live ones\n",Clads
##
else:
deathcycle += 1
Clads = Clads[::2]
##
## print "\n",len(Clads), "left alive after the",deathcycle,"death cycle and "\
## ,FirstClads - len(Clads)," have died till know"
## if len(Clads) > 1 :
## print "\nThese are the live ones\n",Clads
## else :
## print "\n**** The last Survivor **** \nis:\n***\n\tCladiator",Clads[0]\
## ,"\n\n*********************************"
return Clads[0]
if __name__ == "__main__":
try :
CLDTRS_NUMBER = int(sys.argv[1])
## print "\n\t**** Welcome to the Deadly Arena Survivor ****\n"
## print "\n",CLDTRS_NUMBER," Cladiators will fight and \n",CLDTRS_NUMBER -1 ," Cladiators are going to die ...\n"
## print "\tONLY ONE SHALL SURVIVE...\n"
## print "\tBUT who???\n"
## print " ohhh , HERE THEY ARE .. \n"
cladiators = PrepareCladiators(CLDTRS_NUMBER)
## print cladiators, "\n\n!!! HAIL Ceasar !!! \nthey say loudly..."
print CLDTRS_NUMBER,Survivor(cladiators)
except (IndexError ,ValueError ):
print "Please place one integer value as arguement\n"
|
This is my solution the Josephus problem where n = 2 https://gist.github.com/564863