Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
First time posting in this community. I recently started to learn Python (2 weeks) and as a way to practice a classmate gave me a task: "Write a program that checks if an integer is a vampire number.
For an integer to be a vampire number(v) it needs to meet these 4 criteria:
1)Has a pair number of digits. Lets call the number of digits:n
2)You can obtain v by multiplying two integers,x and y, each with n/2 digits. x and y are the fangs.
3)Both fangs cannot end simultaneously in 0.
4)v can be made with all digits from x and y, in any order and only using each digit once.
Example:
21*60=1260 <--Vampire number
210*600=126000 <--Not a vampire number
The first vampire numbers are the following: 1260, 1395, 1435, 1530, 1827, 2187, 6880, 102510, 104260, 105210, 105264, 105750, 108135, 110758, 115672, 116725, 117067, 118440, 120600, 123354, 124483, 125248, 125433, 125460, 125500, 126027, 126846, 129640, ...
So far I've made a program that can achieve the first 3 criteria(I think). I'm looking for help on the last one.
This is what I've got: (Sorry for some stuff in Spanish)
v=int(input("Enter number to test for vampire:"))
#Test for pair number of digits
def nd(a):
nd = 0
while a != 0:
d = a % 10
if d != 0:
nd += 1
a = a // 10
return nd
def DigitosPar(a):
if nd(a)%2==0:
return 1
else:
return 0
#Last digit is 0
def UltimoDigCero(b):
ud = 0
ud = b % 10
if ud==0:
return 1
else:
return 0
if DigitosPar(v)==1:
x=[]
for i in range(int(10**(nd(v)/2-1)),int(10**(int(nd(v))/2))):
x.append(i)
y=x
z=0
posiblex=0
posibley=0
for ia in range(0,len(y)):
for ib in range(0,len(x)):
z=y[ia]*x[ib]
if z==v and not((UltimoDigCero(x[ib])==1 and UltimoDigCero(y[ia])==1)):
posiblex=x[ib]
posibley=y[ia]
print(v,"has as fangs",posiblex,posibley)
if posiblex==0:
print(v, "not a vampire")
else:
print(v, "not a vampire")
Here is fast method to get solutions for numbers that are 6 digits or longer:
import itertools as it
def get_fangs(num_str):
num_iter = it.permutations(num_str, len(num_str))
for num_list in num_iter:
v = ''.join(num_list)
x, y = v[:int(len(v)/2)], v[int(len(v)/2):]
if x[-1] == '0' and y[-1] == '0':
continue
if int(x) * int(y) == int(num_str):
return x,y
return False
def is_vampire(m_int):
n_str = str(m_int)
if len(n_str) % 2 == 1:
return False
fangs = get_fangs(n_str)
if not fangs:
return False
return True
for test_num in range(150000):
if is_vampire(test_num):
print ("{}".format(test_num), end = ", ")
And here is the output when I run this (in IDLE):
>>>
================== RESTART: C:\Users\Joe\Desktop\vampire.py
1260, 1395, 1435, 1530, 1827, 2187, 6880, 102510, 104260, 105210, 105264,
105750, 108135, 110758, 115672, 116725, 117067, 118440, 120600, 123354,
124483, 125248, 125433, 125460, 125500, 126027, 126846, 129640, 129775,
131242, 132430, 133245, 134725, 135828, 135837, 136525, 136948, 139500,
140350, 143500, 145314, 146137, 146952,
==================
>>>
1260 is a vampire number because the divisors can be concatenated into a permutation of 1260. You can do it this way
v=int(input("Enter number to test for vampire:"))
from collections import Counter
def is_anagram(a, b):
if len(a) != len(b):
return False
return Counter(a) == Counter(b)
import math
for x in range(0,int(math.pow(10, len(str(v))/2))):
for y in range(0,int(math.pow(10, len(str(v))/2))):
if (x*y == v):
#print('Fangs: %d %d' % (x, y))
if (is_anagram(str(str(x)+''+str(y)), str(v)) ):
print('Vampire')
To list the first nvampire numbers, you can use the above code as a function and incrementally test the integers.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I have a math/python question, how to change big number in squared root, to small number (but still keeping the value), for example √243 to 9√3?
And I have another question, how to use it in my code?
Code:
import math
dl=int(input("Podaj długość: "))
c=input("Który bok: przypdl, przypkr, przec: ")
def find(x):
global przypkr
global przec
global przypdl
if c=="przec":
przec=x
przypkr=x/2
przypdl=przypkr*math.sqrt(3)
elif c=="przypkr":
przypkr=x
przypdl=x*math.sqrt(3)
przec=x*2
else:
przypdl=x
przypkr=x/math.sqrt(3)
przec=przypkr*2
print(f'przeciwprostokątna: {przec}, krótsza przyprostokątna: {przypkr}, dłuższa przyprostokątna: {przypdl} √{przypdl*przypdl}')
find(dl)
def obw():
print(f'Obwód równa się: {przec + przypkr + przypdl} lub {przec + przypkr} + √{przypdl*przypdl}')
obw()
Use simplify from SymPy package:
Python env: pip install sympy
Anaconda env: conda install sympy
import sympy as sp
expr = sp.sqrt(243)
print(sp.simplify(expr))
Output:
9*sqrt(3)
The way I thought of this is that we can recursively remove square factors from the root.
e.g.
243
/ \
3^2 27
/ \
3^2 3
The final result on the right (i.e. 3) will be the simplified root, since we've removed all the square factors. The numbers on the left (3 * 3 == 9) will be what we take out the root.
First, we need a way of telling whether a number is square. From another question:
import math
def is_square(i: int) -> bool:
return i == math.isqrt(i) ** 2
Next, we need to be able to determine the factors of a number. I put together something rudementary here, although it can certainly be made more efficient (better examples here):
def factors(i: int) -> list[int]:
factors = []
for number in range(1, i + 1):
if i % number == 0:
factors.append(number)
return factors
Now, we can generate the factors of a number which are square:
>>> [a for a in factors(20) if is_square(a)]
[1, 4]
Putting this all together, we can generate the number outside the square root. Our base case is when the root is already simplified. This means that its only square factor is 1.
Otherwise, we generate what the number outside should be after removing one factor, and we keep repeating this process.
def outside(i: int) -> int:
square_factors = [a for a in factors(i) if is_square(a)]
# Factors are sorted in increasing order.
# Therefore, take any factor that's not 1
factor = square_factors[-1]
if factor == 1:
return 1
# Double slash usage e.g. 7.0 => 7. Could alternatively use int
return int(math.sqrt(factor) * outside(i // factor))
>>> outside(243)
9 # 9 root 3
>>> outside(20)
2 # 2 root 5
Finally, we need to generate the number inside the root. e.g. If its outside number is 3, we divided the original number by 3^2 == 9 to get the simplified root.
def inside(i: int) -> int:
return i // (outside(i) ** 2)
>>> inside(20)
>>> 5 # 2 sqrt 5
>>> inside(243)
>>> 3 # 9 sqrt 3
Putting this all together:
def simplify(i: int) -> tuple[int, int]:
return outside(i), inside(i)
>>> simplify(243)
(9, 3) # 9 sqrt 3
>>> simplify(10)
(1, 10) # 1 sqrt 10
>>> simplify(20)
(2, 5) # 2 sqrt 5
You could find the largest root that is a divisor of your number and present the remainder as the √xxx part:
def root(N):
for r in range(int(N**0.5)+1,1,-1):
if N % (r*r) == 0:
n = N // (r*r)
return str(r) + f"√{n}"*(n>1)
return f"√{N}"
print(root(50)) # 5√2
print(root(81)) # 9
print(root(96)) # 4√6
print(root(97)) # √97
It is usually better to separate computations from formatting using two single purpose functions:
def unroot(N): # find multiplier and remaining root
m,d = 1,2
while d*d<=N:
if N % (d*d): d += 1 + d%2
else: m,N = m*d,N//(d*d)
return m,N
def rootstr(N): # format into a string
m,n = unroot(N)
return str(m)*(m>1)+f"√{n}"*(n>1)
for N in (50,81,96,97):
print(f"√{N} =",rootstr(N))
√50 = 5√2
√81 = 9
√96 = 4√6
√97 = √97
I'm aware of a few other similar threads, but im not sure how to apply them to my example.
I am trying to attack the countdown number game from a brute force algorithm. This is my first attempt at anything like this, so any tips on how to speed up the process up?
I am testing it for situations where the answer is unsolvable given the initial numbers. This eventually will be paired up with a tkinter interface for the full game.
structure should look like this, where we try every order of abcdef and every operation combo for op1-5
from datetime import datetime
import itertools
import math
starttime = datetime.now()
def permutationG(input, s):
if len(s) == len(input): yield s
for i in input:
if i in s: continue
s=s+i
for x in permutationG(input, s): yield x
s=s[:-1]
def op(operator, number1,number2):
string=str(number1)+str(operator)+str(number2)
return eval(string)
a=11
b=10
c=9
d=8
e=7
f=6
targetnumber = 101234
listofnumbers = ['a','b','c','d','e','f']
listprep = ['+','-','*','/']
stringofnumbers = ''.join(str(e) for e in listofnumbers)
numberlocations =[]
for item in permutationG(listofnumbers,''):
numberlocations.append(item)
numberlocations = set(numberlocations)
myarray = itertools.combinations_with_replacement(listprep, 5)
operatorlist = []
for item in myarray:
#for all different numbers find the different permutations
temp = list(itertools.permutations(item))
operatorlist.extend(temp)
#remove duplicates
finaloplist = list(set(operatorlist))
dist=[math.inf]
currentclosestnumber = 0
count=0
looptime=datetime.now()
print('Starting Loop')
for item in numberlocations:
for ops in finaloplist:
initial_value = op(ops[0],item[0],item[1])
for i in range(2,len(item)):
intcheck2 = int(initial_value) - initial_value
if initial_value != targetnumber and initial_value >= 0 and intcheck2 == 0:
newvalue = op(ops[i-1], initial_value, item[i])
else:
break
initial_value = newvalue
attempt = initial_value
intcheck = int(attempt) - attempt
distance = targetnumber - initial_value
if abs(distance) < abs(dist[0]) and intcheck == 0:
currentclosestnumber = attempt
dist[0]=distance
print(attempt)
if targetnumber == attempt:
break
if targetnumber == attempt:
break
endtime = datetime.now()
stringtime= endtime-starttime
#print('Loops: ', count)
if targetnumber == attempt:
print('FOUNDIT!! Target Number = %s Closest Number = %s Time Elapsed = %s' %(targetnumber, currentclosestnumber, stringtime))
elif targetnumber!=attempt:
print('Heres how close: Target Number = %s Closest Number = %s Time Elapsed = %s' %(targetnumber, currentclosestnumber, stringtime))
This outputs a time of roughly a minute and a half.
Another issue is because of the method I'm using (using eval string manipulation) I have no idea to show where the brackets go in the final formula when printed, or how to fit an eval into the zip at the end to show the numbers instead of the letters.
Any guidance is really appreciated.
Note: I have edited the post with the most recent version of the code. This reduced the time to calculate from 1:30 to 0:45. The major change was instead of one long string of calculations I created a for loop for each sequential operation, with an if statement to make sure that if the current value is negative or a decimal it breaks.
This reduces the number of calculations required significantly.
Here is a slower version but without the bugs.
I don't have time to try to optimize, but my thought is that most of the problem is in creating/destroying garbage in splitting subsets.
If I really wanted this to be fast, I think that you could use a dynamic programming approach.
def subset_splits (a_list):
if 0 == len(a_list):
yield ([], [])
else:
for sublist1, sublist2 in subset_splits(a_list[1:]):
yield ([a_list[0]] + sublist1, sublist2)
yield ([a_list[0]] + sublist2, sublist1)
def reachable (numbers):
if 1 == len(numbers):
yield (numbers[0], numbers[0])
else:
for list1, list2 in subset_splits(numbers):
if 0 == len(list2):
continue
for x1, expr1 in reachable(list1):
for x2, expr2 in reachable(list2):
yield x1+x2, (expr1, '+', expr2)
yield x1*x2, (expr1, '*', expr2)
yield x1-x2, (expr1, '-', expr2)
yield x2-x1, (expr2, '-', expr1)
if 0 != x2:
yield x1/x2, (expr1, '/', expr2)
if 0 != x1:
yield x2/x1, (expr2, '/', expr1)
numbers = [1, 2, 3, 4, 5, 6]
target = 10000
best = numbers[0]
if best == target:
print(("Answer: ", numbers[0], numbers[0]))
else:
print(("Best: ", numbers[0], numbers[0]))
done = False;
for s, t in subset_splits(numbers):
if done:
break
for x, expr in reachable(s):
if x == target:
print(("Answer: ", x, expr))
done = True
break
elif abs(target-x) < abs(target-best):
print(("Best: ", x, expr))
best = x
if done:
break
for x, expr in reachable(t):
if x == target:
print(("Answer: ", x, expr))
done = True
break
elif abs(target-x) < abs(best-x):
print(("Best: ", x, expr))
best = x
The following Python program flips a coin several times, then reports the longest series of heads and tails. I am trying to convert this program into a program that uses functions so it uses basically less code. I am very new to programming and my teacher requested this of us, but I have no idea how to do it. I know I'm supposed to have the function accept 2 parameters: a string or list, and a character to search for. The function should return, as the value of the function, an integer which is the longest sequence of that character in that string. The function shouldn't accept input or output from the user.
import random
print("This program flips a coin several times, \nthen reports the longest
series of heads and tails")
cointoss = int(input("Number of times to flip the coin: "))
varlist = []
i = 0
varstring = ' '
while i < cointoss:
r = random.choice('HT')
varlist.append(r)
varstring = varstring + r
i += 1
print(varstring)
print(varlist)
print("There's this many heads: ",varstring.count("H"))
print("There's this many tails: ",varstring.count("T"))
print("Processing input...")
i = 0
longest_h = 0
longest_t = 0
inarow = 0
prevIn = 0
while i < cointoss:
print(varlist[i])
if varlist[i] == 'H':
prevIn += 1
if prevIn > longest_h:
longest_h = prevIn
print("",longest_h,"")
inarow = 0
if varlist[i] == 'T':
inarow += 1
if inarow > longest_t:
longest_t = inarow
print("",longest_t,"")
prevIn = 0
i += 1
print ("The longest series of heads is: ",longest_h)
print ("The longest series of tails is: ",longest_t)
If this is asking too much, any explanatory help would be really nice instead. All I've got so far is:
def flip (a, b):
flipValue = random.randint
but it's barely anything.
import random
def Main():
numOfFlips=getFlips()
outcome=flipping(numOfFlips)
print(outcome)
def getFlips():
Flips=int(input("Enter number if flips:\n"))
return Flips
def flipping(numOfFlips):
longHeads=[]
longTails=[]
Tails=0
Heads=0
for flips in range(0,numOfFlips):
flipValue=random.randint(1,2)
print(flipValue)
if flipValue==1:
Tails+=1
longHeads.append(Heads) #recording value of Heads before resetting it
Heads=0
else:
Heads+=1
longTails.append(Tails)
Tails=0
longestHeads=max(longHeads) #chooses the greatest length from both lists
longestTails=max(longTails)
return "Longest heads:\t"+str(longestHeads)+"\nLongest tails:\t"+str(longestTails)
Main()
I did not quite understand how your code worked, so I made the code in functions that works just as well, there will probably be ways of improving my code alone but I have moved the code over to functions
First, you need a function that flips a coin x times. This would be one possible implementation, favoring random.choice over random.randint:
def flip(x):
result = []
for _ in range(x):
result.append(random.choice(("h", "t")))
return result
Of course, you could also pass from what exactly we are supposed to take a choice as a parameter.
Next, you need a function that finds the longest sequence of some value in some list:
def longest_series(some_value, some_list):
current, longest = 0, 0
for r in some_list:
if r == some_value:
current += 1
longest = max(current, longest)
else:
current = 0
return longest
And now you can call these in the right order:
# initialize the random number generator, so we get the same result
random.seed(5)
# toss a coin a hundred times
series = flip(100)
# count heads/tails
headflips = longest_series('h', series)
tailflips = longest_series('t', series)
# print the results
print("The longest series of heads is: " + str(headflips))
print("The longest series of tails is: " + str(tailflips))
Output:
>> The longest series of heads is: 8
>> The longest series of heads is: 5
edit: removed the flip implementation with yield, it made the code weird.
Counting the longest run
Let see what you have asked for
I'm supposed to have the function accept 2 parameters: a string or list,
or, generalizing just a bit, a sequence
and a character
again, we'd speak, generically, of an item
to search for. The function should return, as the value of the
function, an integer which is the longest sequence of that character
in that string.
My implementation of the function you are asking for, complete of doc
string, is
def longest_run(i, s):
'Counts the longest run of item "i" in sequence "s".'
c, m = 0, 0
for el in s:
if el==i:
c += 1
elif c:
m = m if m >= c else c
c = 0
return m
We initialize c (current run) and m (maximum run so far) to zero,
then we loop, looking at every element el of the argument sequence s.
The logic is straightforward but for elif c: whose block is executed at the end of a run (because c is greater than zero and logically True) but not when the previous item (not the current one) was not equal to i. The savings are small but are savings...
Flipping coins (and more...)
How can we simulate flipping n coins? We abstract the problem and recognize that flipping n coins corresponds to choosing from a collection of possible outcomes (for a coin, either head or tail) for n times.
As it happens, the random module of the standard library has the exact answer to this problem
In [52]: random.choices?
Signature: choices(population, weights=None, *, cum_weights=None, k=1)
Docstring:
Return a k sized list of population elements chosen with replacement.
If the relative weights or cumulative weights are not specified,
the selections are made with equal probability.
File: ~/lib/miniconda3/lib/python3.6/random.py
Type: method
Our implementation, aimed at hiding details, could be
def roll(n, l):
'''Rolls "n" times a dice/coin whose face values are listed in "l".
E.g., roll(2, range(1,21)) -> [12, 4] simulates rolling 2 icosahedron dices.
'''
from random import choices
return choices(l, k=n)
Putting this together
def longest_run(i, s):
'Counts the longest run of item "i" in sequence "s".'
c, m = 0, 0
for el in s:
if el==i:
c += 1
elif c:
m = m if m >= c else c
c = 0
return m
def roll(n, l):
'''Rolls "n" times a dice/coin whose face values are listed in "l".
E.g., roll(2, range(1,21)) -> [12, 4] simulates rolling 2 icosahedron dices.
'''
from random import choices
return choices(l, k=n)
N = 100 # n. of flipped coins
h_or_t = ['h', 't']
random_seq_of_h_or_t = flip(N, h_or_t)
max_h = longest_run('h', random_seq_of_h_or_t)
max_t = longest_run('t', random_seq_of_h_or_t)
So basically, I need to write a code for the luhn algorithm, but i need to have at least 5 functions
I have written a code to do this, yet I am receiving False results where they should be true. For example, I know that the second and the fourth data pieces in the data file are true for this algorithm, yet all of my outputs are false. Can you help me figure out where I've gone wrong?
This is the code:
def CheckLength(numb):
if len(numb)>12 and len(numb)<17:
return True
else:
return False
def CheckType(numb):
if numb[0]=='4':
return 'Visa'
elif numb[0]=='5':
return 'MasterCard'
elif numb[0]=='6':
return 'Discover'
elif numb[0:2]=='37':
return 'American Express'
else:
return 'Invalid Entry'
def Step1(numb):
total1=0
total2=0
length=len(numb)
for i in range(length-2,-1,-2):
double=eval(numb[i])*2
if double>9:
doublex=str(double)
doubleY=int(doublex[0])+int(doublex[1])
total1+=doubleY
else:
total2+=double
total=total1+total2
return total
def Step2(numb):
total=0
length=len(numb)
for i in range(length-1,-2,-2):
total+=i
return total
def Step3(num1,num2):
total=num1+num2
if total%10==0:
return True
else:
return False
def main():
inFile=open('pa7.cards','r')
cardNum=inFile.readline().strip()
while cardNum!='99999':
step1=Step1(cardNum)
step2=Step2(cardNum)
step3=Step3(step1,step2)
print(step1)
print(step2)
print(step3)
cardNum=inFile.readline().strip()
inFile.close()
main()
This is the data file:
4388576018402626
4388576018410707
37271983
5190828258102121
99999
This is the output i am getting when printing all 3 steps
4
63
False
0
63
False
7
15
False
4
63
False
(My comments as an answer, including suggestions and corrections from #DavidZemens' comments)
In terms of bugs, I think you have:
Step 1 has the return statement inside the loop, so the loop only happens once, then it stops.
def Step1(numb):
for i in range(length-2,-1,-2):
return total
^ -- ^ -- move this left, to where 'for' is
Step 2 is adding up the counter, not the credit card digits, and it's stepping through every other digit instead of every digit:
def Step2(numb):
total=0
length=len(numb)
for i in range(length-1,-1,-1):
total += int(numb[i])
return total
In general code comments, this kind of test:
if len(numb)>12 and len(numb)<17:
return True
else:
return False
is a bit redundant. If (truth test) return True else return False can become return (truth test):
return 12 < len(numb) < 17
and later:
total = num1 + num2
if total%10==0:
return True
else:
return False
can be:
return (num1 + num2) % 10 == 0
This calculation:
double=eval(numb[i])*2
if double>9:
doublex=str(double)
doubleY=int(doublex[0])+int(doublex[1])
total1 += doubleY
is a bit awkward turning the number into text, taking text characters, turning them back into numbers, then adding them up.
What it does is take the number of tens (integer divide by 10) and the remainder (modulo 10), so you could keep it all as numbers with:
double = int(numb[i]) * 2
if double > 9:
total1 += (double // 10) + (double % 10)
eval() is a bad practice, it gives any input complete access to the Python interpreter with no safeguards. In your code, you could use int() instead
Your file loop could be clearer:
def main():
with open('pa7.cards') as inFile:
for cardNum in inFile:
cardNum = cardNum.strip()
step1=Step1(cardNum)
step2=Step2(cardNum)
step3=Step3(step1,step2)
print(step1)
print(step2)
print(step3)
And you might get some benefit by converting the cardNum into a list of numbers once and then working with that, instead of calling int() all over the place.
You can also optimize the two unused functions (assuming you use them elsewhere in the code):
def CheckLength(numb):
return 12 < len(numb) < 17
def CheckType(numb):
"""
returns the type of credit card, based on the first digit or 2 digits
numb; passed as string
"""
n = numb[0] if not numb[0] == '3' else numb[:1]
d = {4:'Visa',
5:'Mastercard',
6:'Discover',
37:'American Express'}
return d.get(int(n), 'Invalid Entry')
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)