How to repeat the steps - python

In my program I have total of 3 steps.
To find the mean
Split the given list using the mean value
If the threshold value > epsilon then update mean value and repeat the step 2 again with updated mean value, else finished.
I have achieved above two steps anyhow. Third step I have achieved only half and struggling in how to repeat the step 2 till the threshold value will be less than epsilon.
My code is below:
import numpy as np
store_list = [1,2,3,1,2,3,1]
# Step 1
mean_value = np.mean(store_list)
print("Mean Value : " + str(mean_value))
# Step 2
small_list = [i for i in store_list if i <= mean_value]
big_list = [i for i in store_list if i > mean_value]
print(small_list)
print(big_list)
toe_1 = np.mean(small_list)
toe_2 = np.mean(big_list)
print("toe value 1 : " + str(toe_1))
print("toe value 2 : " + str(toe_2))
toe_sum = np.sum([toe_1, toe_2])
toe_cap = np.divide(toe_sum, 2)
print("toe cap : " + str(toe_cap))
# Step 3
new_threshold = np.subtract(mean_value, toe_cap)
print(new_threshold)
epsilon_value = 0.1
if new_threshold > epsilon_value:
mean_value = toe_cap
print("new mean : " + str(mean_value))
My output of above is:
Mean Value : 1.8571428571428572
[1, 1, 1]
[2, 3, 2, 3]
toe value 1 : 1.0
toe value 2 : 2.5
toe cap : 1.75
new threshold : 0.1071428571428572
new mean : 1.75
In this case I have to repeat the step 2 again considering new mean. I am new to Python.

I'm not able to numpy but i can imagine that all you need is a recursive runner function, i don't want to break the structure of your code, therefore i did not try to optimize the code. You can try the following code, i tried, it works:
import numpy as np
def step2(store_list, mean_value):
small_list = [i for i in store_list if i <= mean_value]
big_list = [i for i in store_list if i > mean_value]
toe_1 = np.mean(small_list)
toe_2 = np.mean(big_list)
toe_sum = np.sum([toe_1, toe_2])
toe_cap = np.divide(toe_sum, 2)
return small_list, big_list, toe_1, toe_2, toe_cap
def step3(mean_value, toe_cap):
new_threshold = np.subtract(mean_value, toe_cap)
print(new_threshold)
epsilon_value = 0.1
if new_threshold > epsilon_value:
return True, toe_cap
else:
return False, mean_value
def my_run(store_list, mean_value):
small_list, big_list, toe_1, toe_2, toe_cap = step2(store_list, mean_value)
print(small_list)
print(big_list)
print("toe value 1 : " + str(toe_1))
print("toe value 2 : " + str(toe_2))
print("toe cap : " + str(toe_cap))
condition, mean_value = step3(mean_value, toe_cap)
if condition:
print("new mean : " + str(mean_value))
my_run(store_list, mean_value)
def main():
store_list = [1, 2, 3, 1, 2, 3, 1]
mean_value = np.mean(store_list)
print("Mean Value : " + str(mean_value))
my_run(store_list, mean_value)
if __name__ == '__main__':
main()

There are 2 types of loops in python. for loops and while loops. You can achieve a "loop" by doing recursion which is just calling a function inside the same function, having a correct exit statement, like this:
def print_10_times(num, count=0):
if count < 10:
print(num)
count += 1
print_10_times(num, count)
print_10_times(5) # will print '5' 10 times
Although there are easier ways to do loops in python. The easiest loop to do when you know how many loops you will need to do beforehand, is the for loop. The above example could be executed like this:
def print_10_times(num):
for i in range(10):
print(num)
print_10_times(5) # will print '5' 10 times
The other loop you can do is the while loop. To use it you will have to have a correct exit statement in the beggining of it. If you wanted to execute the above example with a while loop it would have to look something like this:
def print_10_times(num):
i = 0
while i < 10:
print(num)
print_10_times(5) # will print '5' 10 times
For you code to work you will need to have an exit statement for every loop you'd want to use. For example maybe you wanted those 3 steps to run 2 times. You could do this:
import numpy as np
store_list = [1,2,3,1,2,3,1]
for i in range(2):
# Step 1
mean_value = np.mean(store_list)
print("Mean Value : " + str(mean_value))
# Step 2
small_list = [i for i in store_list if i <= mean_value]
big_list = [i for i in store_list if i > mean_value]
print(small_list)
print(big_list)
toe_1 = np.mean(small_list)
toe_2 = np.mean(big_list)
print("toe value 1 : " + str(toe_1))
print("toe value 2 : " + str(toe_2))
toe_sum = np.sum([toe_1, toe_2])
toe_cap = np.divide(toe_sum, 2)
print("toe cap : " + str(toe_cap))
# Step 3
new_threshold = np.subtract(mean_value, toe_cap)
print(new_threshold)
epsilon_value = 0.1
if new_threshold > epsilon_value:
mean_value = toe_cap
print("new mean : " + str(mean_value))
But this will output the same thing 2 times.
I have achieved above two steps anyhow. Third step I have achieved only half and struggling in how to repeat the step 2 till the threshold value will be less than epsilon.
You can do this with a simple while loop:
import numpy as np
store_list = [1,2,3,1,2,3,1]
# Step 1
mean_value = np.mean(store_list)
print("Mean Value : " + str(mean_value))
# Step 2
toe_cap = 3
e = np.exp(1)
while toe_cap > e:
small_list = [i for i in store_list if i <= mean_value]
big_list = [i for i in store_list if i > mean_value]
print(small_list)
print(big_list)
toe_1 = np.mean(small_list)
toe_2 = np.mean(big_list)
print("toe value 1 : " + str(toe_1))
print("toe value 2 : " + str(toe_2))
toe_sum = np.sum([toe_1, toe_2])
toe_cap = np.divide(toe_sum, 2)
print("toe cap : " + str(toe_cap))
# Step 3
new_threshold = np.subtract(mean_value, toe_cap)
print(new_threshold)
epsilon_value = 0.1
if new_threshold > epsilon_value:
mean_value = toe_cap
print("new mean : " + str(mean_value))
This loop will end when toe_cap is smaller than e (Euler's number). I assigned toe_cap a value greater than e so that the loop is run at least 1 time.
There is no problem with this because the toe_cap value isn't used in any calculations and is only reassigned in the end of the loop. It's purpose here is to be used to have a correct exit statement.
If there is any possibility that the toe_cap value will never go below e, then you would have to add a different exit statement, probably according to the number of loops that you think will be enough.

Related

Issue with Nested If/While/If statement

As a D&D aficionado, I have written out a script to perform any attack and damage rolls for any specified die, including what happens in the event of a critical attack roll (20).
from random import randint
atk_roll = 20
hit_mod = 6
atk_hit = atk_roll + hit_mod
die = 'd10'
dmg_mod = 4
rolls = 1
def dice_roller(x, y, z):
y1 = int(y.strip('d'))
dict = {}
results = []
step = 1
while step <= z:
die = randint(1,y1)
results.append(die)
step += 1
if atk_roll == 20:
total = (sum(results)+dmg_mod) + (y1*z)
pct_dmg = total / (((y1*z)+dmg_mod) + (y1*z))
else:
total = sum(results) + dmg_mod
pct_dmg = total / ((y1*z)+dmg_mod)
dict.update({'Attack Roll: ' + f'{atk_roll} + {hit_mod} = {x}':
{'Damage Roll: ' + f'{z}' + y:
{'Rolls': results, 'Total Damage': total, 'Pct_Damage': f'{pct_dmg:.0%}'}}})
print(dict)
print(dice_roller(atk_hit, die, rolls))
{'Attack Roll: 20 + 6 = 26': {'Damage Roll: 1d10': {'Rolls': [4], 'Total Damage': 18, 'Pct_Damage': '75%'}}}
None
The issue becomes when I introduce a new "if/else" statement to account for a missed attack. The only roll that does not work is a critical roll:
from random import randint
atk_roll = 20
hit_mod = 6
atk_hit = atk_roll + hit_mod
die = 'd10'
dmg_mod = 4
rolls = 1
ac = 15
def dice_roller(x, y, z):
y1 = int(y.strip('d'))
dict = {}
results = []
step = 1
if x >= ac:
while step <= z:
die = randint(1,y1)
results.append(die)
step += 1
if atk_roll == 20:
total = (sum(results)+dmg_mod) + (y1*z)
pct_dmg = total / (((y1*z)+dmg_mod) + (y1*z))
else:
total = sum(results) + dmg_mod
pct_dmg = total / ((y1*z)+dmg_mod)
dict.update({'Attack Roll: ' + f'{atk_roll} + {hit_mod} = {x}':
{'Damage Roll: ' + f'{z}' + y:
{'Rolls': results, 'Total Damage': total, 'Pct_Damage': f'{pct_dmg:.0%}'}}})
print(dict)
else:
print('Your attack missed')
print(dice_roller((atk_hit), die, rolls))
{}
None
When I change the value of "atk_roll" in the second script back to "randint(1,20)", the code works exactly as intended, noting when an attack misses or returning the dictionary of values if the attack hits. I cannot for the life of me figure out why the code is returning a blank dict only when "atk_roll" = 20. Does it have something to do with the nesting syntax of if/while/if? Thanks!
In the second code snippet you provided: the if-else block if ask_roll == 20:
will always be taken and therefore your dictionary will not be populated with values as the atk_roll value is always 20. This is because your dict is being populated in the following else.
This differs from your first piece of code as dict is updated every time the function is called as its located outside of any conditional statements.
I would need more details about what your code does to provide a detailed solution but I will attempt to give a high-level solution. If you are trying to update the dictionary regardless if your atk_roll is equal to 20 then the update should be outside the nested else block in your conditional statement checking if atk_roll is equal to 20. This code snippet is included below.
if atk_roll == 20:
total = (sum(results)+dmg_mod) + (y1*z)
pct_dmg = total / (((y1*z)+dmg_mod) + (y1*z))
else:
total = sum(results) + dmg_mod
pct_dmg = total / ((y1*z)+dmg_mod)
dict.update({'Attack Roll: ' + f'{atk_roll} + {hit_mod} = {x}':
{'Damage Roll: ' + f'{z}' + y:
{'Rolls': results, 'Total Damage': total, 'Pct_Damage': f'{pct_dmg:.0%}'}}})

Solving a simple function with step and which outputs max value & argument of a function

I am writing a program which solves a function in an interval 0:9 where step size is 0.005. This program requires 1800 calculations and a way to find the max value of a function and x argument which was used.
What would be the recommended way and loops to use in order calculate function 1800 times (9/0.005), find the max value of it and output related argument value which was used in calculation for the max value?
My idea was that there should be 2 lists generated, one for the range/interval (1800 items) and other for calculated values (also 1800). Which would then find max in 'calculated array' and related x argument in the other array, using list index or some other method..
from operator import itemgetter
import math
myfile = open("result.txt", "w")
data = []
step=0.005
rng=9
lim=rng/step
print(lim)
xs=[x * step for x in range(rng)]
lim_int=int(lim)
print(xs)
for i in range(lim_int):
num=itemgetter(i)(xs)
x=math.sin(num)* math.exp(-num/100)
print(i, x)
data.append(x)
for i in range(rng):
text = str(i)
text2 = str(data[i])
print(text, text2)
myfile.write(text + ' ' + text2 + '\n')
i=1
while i < rng:
i=i+1
num2=itemgetter(i)(xs)
v=math.sin(num2)* math.exp(-num2/100)
if v==max(data):
arg=num2
break
print('largest function value', max(data))
print('function argument value used', arg)
myfile.close()
Numpy is the widely used performant package for this:
import numpy as np
x = np.arange(0, 9, 0.005)
f = np.sin(x)*np.exp(-x/100)
print("max is: ", np.max(f))
print("index of max is: ", np.argmax(f))
output:
max is: 0.98446367206362
index of max is: 312
If for some reason you want a native python solution (without using list methods max and index), you can do something like this:
step = 0.005
rng = 9
lim = int(rng/step)
x = [x_i*step for x_i in range(lim + 1)]
f = [math.exp(-x_i/100)*math.sin(x_i) for x_i in x]
max_ind = 0
f_max = f[max_ind]
for j, f_x in enumerate(f):
if f_x > f_max:
f_max = f_x
max_ind = j

How to structure python programs? Tried making it more structured, now runs 13 times slower

Im very new to programming, I wrote a simple program for a school project and wanted to make the code "prettier" by not just having the program be one giant function but instead be made up of multiple smaller functions with a singe purpose. I seemed to have messed up royally since the program now runs 13 times slower. How should I structured the program to make it run faster and just in general make programs easier to write, read and edit?
Here are the two programs:
First program (for reference values runs in ≈0:20):
import numpy as np
import matplotlib.pyplot as plt
def graf(a,b,H,p):
GM = 39.5216489684
x_0 = a + np.sqrt(a**2 - b**2)
v_0 = np.sqrt(GM*(2/x_0 - 1/a))
konstant_period = np.sqrt(a**3)*H
h = 1/H
'''starting position given by an elliptic orbit '''
stor_x_lista = [x_0]
stor_y_lista = [0]
hastighet_x = [0]
hastighet_y = [v_0]
liten_x_lista = []
liten_y_lista = []
''' a loop that approximates the points of the orbit'''
t = 0
tid_lista = []
n = 0
while n < konstant_period:
hastighet_x.append(hastighet_x[n] - h*GM* stor_x_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_x_lista.append(stor_x_lista[n] + h*hastighet_x[n])
hastighet_y.append(hastighet_y[n] - h*GM*stor_y_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_y_lista.append(stor_y_lista[n] + h*hastighet_y[n])
'''smaller list of points to run faster'''
if n % p == 0:
liten_x_lista.append(stor_x_lista[n])
liten_y_lista.append(stor_y_lista[n])
tid_lista.append(t)
n += 1
t += h
''' function that finds the angle'''
vinkel = []
siffra = 0
while siffra < len(liten_x_lista):
if liten_y_lista[siffra ] >= 0:
vinkel.append( np.arccos( liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2)))
siffra += 1
elif liten_y_lista[siffra] < 0 :
vinkel.append( np.pi + np.arccos( -liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2) ))
siffra += 1
'''get rid of line to find periodic function'''
mod_lista = []
modn = 0
while modn < len(vinkel):
mod_lista.append(vinkel[modn] - (2*np.pi*tid_lista[modn])/np.sqrt(a**3))
modn += 1
'''make all inputs have period 1'''
squeeze_tid = []
squeezen = 0
while squeezen < len(tid_lista):
squeeze_tid.append(tid_lista[squeezen]/np.sqrt(a**3))
squeezen += 1
del mod_lista[-1:]
del tid_lista[-1:]
del squeeze_tid[-1:]
plt.plot(squeeze_tid,mod_lista)
plt.title('p(t) där a = ' + str(a) + ' och b = ' + str(b))
plt.show
Second more split up program (for reference values runs in ≈4:20):
import numpy as np
import matplotlib.pyplot as plt
'''function that generates the points of the orbit'''
def punkt(a,b,H,p):
GM = 39.5216489684
x_0 = a + np.sqrt(a**2 - b**2)
v_0 = np.sqrt(GM*(2/x_0 - 1/a))
konstant_period = np.sqrt(a**3)*H
h = 1/H
'''starting position given by an elliptic orbit '''
stor_x_lista = [x_0]
stor_y_lista = [0]
hastighet_x = [0]
hastighet_y = [v_0]
liten_x_lista = []
liten_y_lista = []
''' a loop that approximates the points of the orbit'''
t = 0
tid_lista = []
n = 0
while n < konstant_period:
hastighet_x.append(hastighet_x[n] - h*GM* stor_x_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_x_lista.append(stor_x_lista[n] + h*hastighet_x[n])
hastighet_y.append(hastighet_y[n] - h*GM*stor_y_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_y_lista.append(stor_y_lista[n] + h*hastighet_y[n])
'''smaller list of points to run faster'''
if n % p == 0:
liten_x_lista.append(stor_x_lista[n])
liten_y_lista.append(stor_y_lista[n])
tid_lista.append(t)
n += 1
t += h
return (liten_x_lista,liten_y_lista,tid_lista)
''' function that finds the angle'''
def vinkel(a,b,H,p):
'''import lists'''
liten_x_lista = punkt(a,b,H,p)[0]
liten_y_lista = punkt(a,b,H,p)[1]
tid_lista = punkt(a,b,H,p)[2]
'''find the angle'''
vinkel_lista = []
siffra = 0
while siffra < len(liten_x_lista):
if liten_y_lista[siffra ] >= 0:
vinkel_lista.append( np.arccos( liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2)))
siffra += 1
elif liten_y_lista[siffra] < 0 :
vinkel_lista.append( np.pi + np.arccos( -liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2) ))
siffra += 1
return (vinkel_lista, tid_lista)
def periodisk(a,b,H,p):
'''import lists'''
tid_lista = vinkel(a,b,H,p)[1]
vinkel_lista = vinkel(a,b,H,p)[0]
'''get rid of linear line to find p(t)'''
mod_lista = []
modn = 0
while modn < len(vinkel_lista):
mod_lista.append((vinkel_lista[modn] - (2*np.pi*tid_lista[modn])/np.sqrt(a**3)))
modn += 1
'''make all inputs have period 1'''
squeeze_tid = []
squeezen = 0
while squeezen < len(tid_lista):
squeeze_tid.append(tid_lista[squeezen]/np.sqrt(a**3))
squeezen += 1
del mod_lista[-1:]
del tid_lista[-1:]
del squeeze_tid[-1:]
return (squeeze_tid,mod_lista)
'''fixa 3d-punkt av p(a,b) a är konstant b varierar??? '''
def hitta_amp(a):
x_b = []
y_b = []
n_b = 0.1
while n_b <= a:
x_b.append(n_b)
y_b.append(punkt(a,n_b,10**5,10**3))
return 0
def graf(a,b,H,p):
plt.plot(periodisk(a,b,H,p)[0],periodisk(a,b,H,p)[1])
plt.show
I would assume the thing that is going wrong is that the program is running the same, slow code multiple times instead of just running it once and then accessing the data. Is the problem that everything is done locally and nothing is stored globally or is it something else?
Just as a heads up, the only thing I know about programming is basic syntax, I have no clue how to actually write and run programs. I ran all the code in spyder if that affects anything.
plt.plot(periodisk(a,b,H,p)[0],periodisk(a,b,H,p)[1])
This code runs periodisk twice with the same arguments, thus at this point we know we run things at least 2 times slower.
You should do some_var = periodisk(a,b,H,p) and then some_var[0], some_var[1]. Or just use unpacking:
plt.plot(*periodisk(a,b,H,p))
tid_lista = vinkel(a,b,H,p)[1]
vinkel_lista = vinkel(a,b,H,p)[0]
Again doing the same thing twice (total: 4*time of (current) vinkel function). Again, smart assignment to fix this:
vinkel_lista, tid_lista = vinkel(a,b,H,p)
liten_x_lista = punkt(a,b,H,p)[0]
liten_y_lista = punkt(a,b,H,p)[1]
tid_lista = punkt(a,b,H,p)[2]
And now you repeat yourself thrice. (total: 12 * time of current punkt function)
liten_x_lista, liten_y_lista, tid_lista = punkt(a,b,H,p)
punkt function is like in original, so we arrived as total being 12 times slower - which quite matches your time estimations. :)
You are calling the functions once per returned list, you should only call them once.
When a method returns multiple variables, (e.g. punkt):
def punkt(a,b,H,p):
# Here is all your code
return (liten_x_lista,liten_y_lista,tid_lista)
You must be careful to only call the function once:
result = punkt(a,b,H,p)
liten_x_lista = result[0]
liten_y_lista = result[1]
tid_lista = result[2]
# As opposed to:
liten_x_lista = punkt(a,b,H,p)[0] # 1st call, ignoring results 2 and 3
liten_y_lista = punkt(a,b,H,p)[1] # 2nd call, ignoring results 1 and 3
tid_lista = punkt(a,b,H,p)[2] # 3rd call, ignoring results 1 and 2
Note: I would personally not return a list, but use python's unpacking:
def punkt(a,b,H,p):
# Here is all your code
return liten_x_lista, liten_y_lista, tid_lista
And you'd access it:
liten_x_lista, liten_y_lista, tid_lista = punkt(a,b,H,p)

python access array errors

im working on a an assignment but the few lines keeps on giving me errors that i cannot understand
pick=0
final=0
while True:
if (min_weight>0):
if (sort_ratio[pick]["Weight"]<min_weight):
final = final + sort_ratio[pick]["Cost"]
min_weight = min_weight - sort_ratio[pick]["Weight"]
if (sort_ratio[pick]["Weight"]>min_weight):
pick = pick + 1
if (min_weight == 0):
print (final)
return
the only problem is when the program pass "pick = pick+ 1" it stops and gives "index out of range" error.
Instead of using the increment method i tried to edit the array instead using
sort_ratio.remove(sort_ratio[0]);
but it gives me "cannot interpreted as integer problem"
present code
from operator import itemgetter
import math
raw_input=input;
test_case = int(raw_input());
for inp1 in range (test_case):
min_weight = int(raw_input());
candy_types = int(raw_input());
candy = [];
for inp2 in range (candy_types):
can_weight,can_cost = map(int,raw_input().split());
ratio_candy = (can_cost / int(can_weight));
candy.extend([{"Cost": can_cost, "Ratio": ratio_candy, "Weight": can_weight}]);
sort_ratio = sorted ( candy, key=itemgetter('Ratio'));
pick = 0;
final = 0;
while True:
if (min_weight>0):
if (sort_ratio[pick]["Weight"]<min_weight):
final = final + sort_ratio[pick]["Cost"]
min_weight = min_weight - sort_ratio[pick]["Weight"]
print (final)
print (min_weight)
if (sort_ratio[pick]["Weight"]>min_weight):
pick = pick + 1
if (min_weight==0):
print (final)
break

"Josephus-p‌r‌o‌b‌l‌e‌m" using list in python

I wanted to know if it will be possible to solve the Josepheus problem using list in python.
In simple terms Josephus problem is all about finding a position in a circular arrangement which would be safe if executions were handled out using a skip parameter which is known beforehand.
For eg : given a circular arrangement such as [1,2,3,4,5,6,7] and a skip parameter of 3, the people will be executed in the order as 3,6,2,7,5,1 and position 4 would be the safe.
I have been trying to solve this using list for some time now, but the index positions becomes tricky for me to handle.
a=[x for x in range(1,11)]
skip=2
step=2
while (len(a)!=1):
value=a[step-1]
a.remove(value)
n=len(a)
step=step+skip
large=max(a)
if step>=n:
diff=abs(large-value)
step=diff%skip
print a
Updated the question with code snippet, but i don't think my logic is correct.
Quite simply, you can use list.pop(i) to delete each victim (and get his ID) in a loop. Then, we just have to worry about wrapping the indices, which you can do just by taking the skipped index mod the number of remaining prisoners.
So then, the question solution becomes
def josephus(ls, skip):
skip -= 1 # pop automatically skips the dead guy
idx = skip
while len(ls) > 1:
print(ls.pop(idx)) # kill prisoner at idx
idx = (idx + skip) % len(ls)
print('survivor: ', ls[0])
Test output:
>>> josephus([1,2,3,4,5,6,7], 3)
3
6
2
7
5
1
survivor: 4
In [96]: def josephus(ls, skip):
...: from collections import deque
...: d = deque(ls)
...: while len(d)>1:
...: d.rotate(-skip)
...: print(d.pop())
...: print('survivor:' , d.pop())
...:
In [97]: josephus([1,2,3,4,5,6,7], 3)
3
6
2
7
5
1
survivor: 4
If you do not want to calculate the index, you can use the deque data structure.
My solution uses a math trick I found online here: https://www.youtube.com/watch?v=uCsD3ZGzMgE
It uses the binary way of writing the number of people in the circle and the position where the survivor sits. The result is the same and the code is shorter.
And the code is this:
numar_persoane = int(input("How many people are in the circle?\n")) #here we manually insert the number of people in the circle
x='{0:08b}'.format(int(numar_persoane)) #here we convert to binary
m=list(x) #here we transform it into a list
for i in range(0,len(m)): #here we remove the first '1' and append to the same list
m.remove('1')
m.append('1')
break
w=''.join(m) #here we make it a string again
print("The survivor sits in position",int(w, 2)) #int(w, 2) makes our string a decimal number
if you are looking for the final result only, here is a simple solution.
def JosephusProblem(people):
binary = bin(people) # Converting to binary
winner = binary[3:]+binary[2] # as the output looks like '0b101001'. removing 0b and adding the 1 to the end
print('The winner is',int(winner,2)) #converting the binary back to decimal
If you are looking for the math behind this code, go check out this video:
Josephus Problem(youTube)
it looks worse but easier to understand for beginners
def last(n):
a=[x for x in range(1,n+1)]
man_with_sword = 1
print(a)
while len(a)!=1:
if man_with_sword == a[len(a)-2]: #man_with_sword before last in circle
killed = a[len(a)-1]
a.remove(killed)
man_with_sword=a[0]
elif man_with_sword==a[len(a)-1]: #man_with_sword last in circle
killed = a[0]
a.remove(killed)
man_with_sword=a[0]
else:
i=0
while i < (len(a)//2):
i=a.index(man_with_sword)
killed = a[a.index(man_with_sword)+1]
a.remove(killed)
#pass the sword
man_with_sword=a[i+1] # pass the sword to next ( we killed next)
print (a, man_with_sword) #show who survived and sword owner
i+=1
print (a, man_with_sword,'next circle') #show who survived and sword owner
The total number of persons n and a number k, which indicates that k-1 persons are skipped and a kth person is killed in the circle.
def josephus(n, k):
if n == 1:
return 1
else:
return (josephus(n - 1, k) + k-1) % n + 1
n = 14
k = 2
print("The chosen place is ", josephus(n, k))
This is my solution to your question:
# simple queue implementation<ADT>
class Queue:
def __init__(self):
self.q = []
def enqueue(self,data):
self.q.insert(0,data)
def dequeue(self):
self.q.pop()
def sizeQ(self):
return len(self.q)
def printQ(self):
return self.q
lists = ["Josephus","Mark","Gladiator","Coward"]
to_die = 3
Q = Queue()
# inserting element into Q
for i in lists:
Q.enqueue(i)
# for size > 1
while Q.sizeP() > 1:
for j in range(1,3):
# every third element to be eliminated
Q.enqueue(Q.dequeue())
Q.dequeue()
print(Q.printQ())
def Last_Person(n):
person = [x for x in range(1,n+1)]
x = 0
c = 1
while len(person) > 1:
if x == len(person) - 1:
print("Round ", c, "- Here's who is left: ", person, "Person ", person[x], "killed person", person[0])
person.pop(0)
x = 0
c = c+1
elif x == len(person) - 2:
print("Round ", c, "- Here's who is left: ", person, "Person ", person[x], "killed person", person[x + 1])
person.pop(x+1)
x = 0
c = c + 1
else:
print("Round ", c, "- Here's who is left: ", person, "Person ", person[x], "killed person", person[x + 1])
person.pop(x + 1)
x = x + 1
c = c + 1
print("Person", person[x], "is the winner")
Last_Person(50)

Categories