Russian Peasant Multiplication Python 3.3 - python

I need help with a program in python 3.3 that is supposed to do Russian peasant multiplication/ancient Egyptian multiplication. The assignment says," If "A" and "B" are the two integers to be multiplied, we repeatedly multiply "A" by 2 and divide "B" by 2, until "B" cannot divide any more and is not zero (integer division). During each set of multiplying "A" and dividing "B", if the value of "B" is an odd number, you add whatever the "A" value is to a total. At the end, the sum of all the "A" values (when "B" is odd) should be equal to the product of the original "A" and "B" inputs. In short, sum up all the "A" values for which "B" is odd and it will be equal (or close) to the product of "A" and "B".
edit
I may have phrased some of the question wrong.
Here is an example:
If "A" is 34, and "B" is 19, multiplying "A" by two and dividing "B" by two each line.
"A" "B"
(34) (19) ("B" is odd, add "A" to total)
(68) (9) ("B" is odd, add "A" to total)
(136) (4) ("B" is even, ignore "A" value)
(272) (2) ("B" is even, ignore "A" value)
(544) (1) ("B" is odd, add "A" to total)
When you sum all the values of "A" for which "B" is odd, you get (34 + 68 + 544 = 646),
which is equal to just multiplying "A" and "B", (34 * 19 = 646).
The part I'm having trouble with is adding "A" to a total whenever "B" is an odd number.
This is what I have so far,
x = int(input("What is the first number? "))
y = int(input("What is the second number? "))
answer = 0
while y != 0:
if (y%2 != 0):
x*2
y//2
answer == answer + x
if (y%2 == 0):
x*2
y//2
print("the product is",(answer))
I'm very new to python and programming, so any help and/or explanations of why its wrong would be greatly appreciated.

you need to add x to answer first, then update x
here is the correct code
x = int(input("What is the first number? "))
y = int(input("What is the second number? "))
answer = 0
while y != 0:
if (y%2 != 0):
answer=answer+x
x=x*2
y=y//2
if (y%2 == 0):
x=x*2
y=y//2
print("the product is",(answer))

I'm not familiar with the algorithm you are trying to implement, but I have made a few modifications to your code.
x = int(input("What is the first number? "))
y = int(input("What is the second number? "))
answer = 0
# != 0 is redundant: y is True if it is not 0
while y:
# no need to have parentheses here
if y % 2:
# this needs to be an assignment, not a check for equality
answer += x # shorthand for answer = answer + x
# These happen every time, so does not need to be inside the if
# these also need to be an assignment, not just an expression
x *= 2
y /= 2
# total was never defined
print("the product is", (answer))

A side note. Frankly, I did not know about the algorithm until now. The more it surprises me it was used by ancient Egyptians or in old Russia. (Actually, I tend to believe that the Russian origin is more probable as it seem that Slavic nations are directly related to old Etrusks).
The old origin surprises me because it actually is a plain hand-made multiplication that you learned in the basic school. The only difference is that the numbers are converted to binary representation first. Rather machine oriented, isn't it? :)
For the numbers in the question, th 34 in decimal representation is equal to 100010 in binary, the 19 in decimal is 10011 in binary. Now the plain basic school multiplication on paper:
100010
x 10011
------------
100010 i.e. 100010 times 1
100010 1000100 times 1
000000 10001000 times 0
000000 100010000 times 0
100010 1000100000 times 1
------------ ^ binary digits of the multiplier
1010000110 (reminder of division by 2)
^ adding the zero means multiplying by 2
i.e. sum only when 1 is the reminder of division
It seems that the one who designed the metod (in ancient times) knew what the binary numbers are.

The last time you add x is when y is equal to 1. If you keep halving until the number
reaches 0, it will take a very large number of iterations (logically, it will take
forever).
Think about 2x2. If you double x to 4, and halve y to 1, x is your answer.
In other words, think of y as how many of x I need to yield answer. Since you can't multiply, only add/double/halve, you have a choice - you can wait until y is 2 and then add doubled value of x, OR you can wait until y is 1 and simply add value of x. The latter is simpler and clearer, that's all.
I think it's clearer in this case to use a while True loop:
def mult2(x, y):
answer = 0
while True:
if y % 2:
answer += x
if y < 1:
break
x *= 2
y //= 2
print("the product is", answer)
Calling function recursively:
def mult2(x, y):
"""aka 'Russian peasant method'; allowed: addition, halving, doubling."""
if y==1:
return x
else:
add = x if y%2 else 0
return mult2(x*2, y//2) + add

the output is a normal mutiplication display. Please share the code where the output is also displayed showing the Russian Peasent method.
Output should be something like this:
If "A" is 34, and "B" is 19,
(34) (19) ("B" is odd, add "A" to total)
(68) (9) ("B" is odd, add "A" to total)
(136) (4) ("B" is even, ignore "A" value)
(272) (2) ("B" is even, ignore "A" value)
(544) (1) ("B" is odd, add "A" to total)
When you sum all the values of "A" for which "B" is odd, you get (34 + 68 + 544 = 646), which is equal to just multiplying "A" and "B", (34 * 19 = 646).

Related

How do I make my function work on negative numbers?

repeat = "y"
while repeat == "y":
#First get the two integers from the user
a = int(input("Enter the first integer: "))
b = int(input("Enter the second integer: "))
#Start the answer with 0
answer = 0
print("A", "B")
print("---")
print(a, b)
#run loop until b is not zero
while b != 0:
#loop while 'b' is odd number
if (b % 2 != 0):
answer = answer + a
print(a*2, b//2)
a = a*2 #double every 'a' integers
b = b//2 #halve the 'b' integers
#loop while 'b' is even number
elif (b % 2 == 0):
print(a*2, b//2)
a = a*2 #double every 'a' integers
b = b//2 #halve the 'b' integers
print("The product is {}.".format(answer))
repeat = input("Would you like to repeat? (y/n)")
print("Goodbye!")
I am writing a program that uses Ancient Egyptian method to multiply. My program works for positive numbers but not negative. How do I fix it so that if both inputted values of user are negative. My result should give the product of any two positive, negative or one negative and positive number. My current program gives the product for any two positive values, or negative a value and positive b value. However, when user enters a negative b value, it produces infinite outputs.
The issue is with the floor division b//2, when b is negative the result will be the lower integer, so -0.5 will be rounded to -1. To avoid it cast to an int a regular division b = int(b / 2).
After removing duplicate code the while loop looks like that
while b != 0:
if b % 2 != 0:
answer = answer + a
print(a * 2, int(b / 2))
a = a * 2
b = int(b / 2)
Edit
To get the correct sign you can check the expected sign after getting the numbers and multiple by 1 or -1 at the end. Since you only check a for the answer you need to work on a positive a
....
answer = 0
sign = 1 if a * b > 0 else -1
a = abs(a)
while b != 0:
....
print("The product is {}.".format(answer * sign))
Welcome to Stack Overflow!!
This is what the program returned when I used -2 on the second integer (b).
A B
---
1 -2
2 -1
4 -1
8 -1
16 -1
If you notice, B stays on -1, while A starts increasing *2 and it does indifinitely because the while loop doesn't break.
Let's look at the code
while b != 0:
#loop while 'b' is odd number
if (b % 2 != 0):
answer = answer + a
print(a*2, b//2)
a = a*2 #double every 'a' integers
b = b//2 #halve the 'b' integers
#loop while 'b' is even number
elif (b % 2 == 0):
print(a*2, b//2)
a = a*2 #double every 'a' integers
b = b//2 #halve the 'b' integers
So on the if section, you do a=a*2 and b=b//2 since b%2!=0 (-1%2 is -1). However, for the while to break, you need to get b=0, and you get that by doing b=b//2. The problem, as Guy said before, is that when you get b=-1 (as you saw on my example), doing -1//2 will give you -1, instead of the supposed 0 that you'll get if you do 1//2. Since you won't get b=0, the program never stops multiplying.
The solution is simple, as guy mentioned, use b=int(b/2)
EDIT for the negative numbers
The reason it gives you the wrong sign when you are using multiplication is this instruction
while b != 0:
#loop while 'b' is odd number
if (b % 2 != 0):
answer = answer + a #<--------------- THE INSTRUCTION
a = a*2 #double every 'a' integers
# b = b//2 #halve the 'b' integers
b = int(b/2)
print(a, b)
answer = answer + a #<--------------- THE INSTRUCTION
since you get your answer by just adding up A, you will have these two wrong scenarios
----> a positive and b negative ->gives you positive (the sign of A) when it should be negative
----> a negative and b negative -> gives you negative (the sign of A) when it should be positive
I tried to find on google how you handled negative numbers with the egyptian method but i didn't find anything, so I guess you can handle that issue with whichever method you prefer.
An alternative to Guy method is multiplying the sign (1 or -1) to the result depending of b, not the multiplication
#------------------Your code-------------------------
#Start the answer with 0
answer = 0
print("A", "B")
print("---")
print(a, b)
#run loop until b is not zero
#------------------The fix proposed-------------------------
#Start the answer with 0
answer = 0
sign = 1 if b > 0 else -1 #---------> the fix
print("A", "B")
print("---")
print(a, b)
#run loop until b is not zero
and at the end, you multiply the sign with the general answer
#------------------Your code-------------------------
elif (b % 2 == 0):
print(a*2, b//2)
a = a*2 #double every 'a' integers
b = b//2 #halve the 'b' integers
print("The product is {}.".format(answer))
repeat = input("Would you like to repeat? (y/n)")
print("Goodbye!")
#------------------The fix proposed-------------------------
elif (b % 2 == 0):
a = a*2 #double every 'a' integers
b = int(b/2) #---->the previous fix to your first problem
print(a,b)
# b = b//2 #halve the 'b' integers
answer=answer*sign #---->The another fix: the multiplication i mentioned
print("The product is {}.".format(answer))
repeat = input("Would you like to repeat? (y/n)")
print("Goodbye!")
With that, you should have the signs working properly
btw, the reason I changed the print insruction that you used to just print (a,b) at the end of the operation of the if sentence is to avoid redundant operations on the program.

is_prime function takes too much time to confirm if number is prime

I created a function that allows users to confirm if a number is prime. The code works great, but loses efficiency when a large number is passed through it. Any tips to cut down on time taken to process when confirming large numbers (i.e. 1999999) is prime?
Here is my code. The timing inefficiencies are a result of python asking the computer to divide number by each element in the list 'x' then placing remainder values into a separate list, to then count the number of occurrences for 0.
def is_prime(number):
x = list(range(1, number + 1,1))
numbers = []
if number < 1:
answer1 = "False. Must be positive integer greater than 1."
# For loop is iterating over list 'x'
for i in x:
# number entered divided by each element in the list to find remainder value. Remainder value
# is added to the list for each result.
numbers.append(number % i)
if number == 1:
answer1 = "False. Must be positive integer greater than 1."
# Count function/attribute used to count occurance of 0 in list 'x'
# If 0 appears more than twice on the list that indicates the number entered has more than two
# factors; thus not prime.
elif number > 1 and numbers.count(0) <= 2:
answer1 = "True"
else:
answer1 = "False"
return answer1

How do I solve the below problem without reverse engineering the sample test cases

I solved the problem below Binary String Problem in Hackerearth the problem which says "Given four integers x,y,a and b. Determine if there exists a binary string having x 0's and y 1's such that the total number of sub-sequences equal to the sequence "01" in it is a and the total number of sub-sequences equal to the sequence "10" in it is b." " with the following code reverse engineering the sample test cases:
import sys
s = sys.stdin.read()
for i in s.split('\n'):
string = i.split(' ')
if len(string) != 4:
print('')
else:
x,y,a,b = string
x = int(x)
y = int(y)
a = int(a)
b = int(b)
if (x*y == a+b):
print('Yes')
else:
print('No')
The explanation provided in the editorial which if x*y==a+b, then it's such a binary string exists, which I had also figured out reverse engineering the test cases but I really could not how the condition satisfies.
One of the sample cases given is x, y, a and b are 3, 2, 4 and 2 respectively, for which string 00110 is a valid string because 3*2=4+2.
But ** 00110 has 01 & 10 how is it having so the number of 01 is not equal to "a" and number of 10 is not equal to "b". Is there any logic or any other side to the problem which I'm missing out?**
You can refer to actual Problem link for further details

Find all positive numbers divisible by 10 and less than n

I need to find all positive numbers that are divisible by 10 and less than n, i found a string with the same question but i have a hard time interpreting it as the user was using java so the codes are very different and confusing.
i tried to make a code by piecing together codes i've checked out but it only works if its divisible by other numbers, if its 10 it would keep going on forever with 0.
n = int(input("Enter a number: "))
x = 0
while x < n :
r = n % 10
if r % 10 != 0 :
x = x + r
print("positive numbers divisible by 10 ", x)
Below is simpler code which will help to get the list of numbers divisible by 10 and less than n:
n = int(input("Enter a number n: "))
divisibleBy10 = []
for i in range(0, n):
if i % 10 == 0:
divisibleBy10.append(i)
print(divisibleBy10)
You can do like this:
n = 100
i = 0
while i<n:
if i%10==0:
print(i)
i+=1
You can also try the following:
# grab the user's input
n = int(input('please enter a number: '))
# set x to 0, so the while loop can stop when 'n' is greater than '0'
x = 0
while n > x:
if n % 10 == 0:
print('{} is divisible by 10.'.format(n))
n -= 1
So basically the loop enters with the value that the user inputs, let's say 10.
Is 10 greater than 0? Yes (while loop executes), the if statement evaluates the remainder with the mod. The value is printed because the if statement evaluates True , the remainder is equal to zero. At last, n is subtracted by 1
Is 9 greater than 0? Yes (while loop executes), the if statement evaluates the remainder with the mod. The value is not printed because the if statement evaluates False , the remainder is not equal to zero. At last, n is subtracted by 1
Is 8 greater than 0? Yes (while loop executes), the if statement evaluates the remainder with the mod. The value is not printed because the if statement evaluates False , the remainder is not equal to zero. At last, n is subtracted by 1
...
And so on until n reaches 0, the while loop stops because 0 is not greater than 0.
This code below tries to reduce the number of loops. If 'x' is extremely large, it helps to optimize the solution. The idea is to not do the divisibility check for each number starting from 1 to n-1. Here, we use the fact that the least positive number divisible by 10 is 10. The next number of interest is 10 + 10 = 20, there by skipping numbers 11 to 19. This helps improve the performance.
x = input('Enter any number ')
y = 10
while y < x:
print(y)
y = y + 10
I think use inline for loop:
print([i for i in range(10,n,10) if i % 4 == 0])

Problem interpreting a "while loop" notation in Python

I am reading and solving through the exercises in the book Introduction to Computation and Programming Using Python by John Guttag (used in the MIT courses) and have a problem understanding why a while loop sets x = 1 at the beginning.
The exercise is asking to find a positive integer that is divisible by both 11 and 12. And the sample solution is:
x = 1
while True:
if x%11 == 0 and x%12 == 0:
break
x = x + 1
print(x, 'is divisible by 11 and 12')
#prints 132, which is divisible by both 11 and 12
I´m sorry that this is such a basic question, but I would appreciate if someone could explain to me the logic of setting x = 1 at the beginning, if x is the value that we are solving for in the first place. Also, I don´t understand the x = x+1 part.
Also, what is the notation I should use to tell a program to do something based on the condition "of all existing integers/values"... (followed by a for or while loop)? Is that what x = 1 possibly refers to?
This program tries to find the first strictly positive integer that is divisible by 11 and 12.
To do so, you need to start somewhere, and that's a positive number x = 1. If we set it to 0, then it will be our result, but we want a strictly positive number.
So we try to see if the new x is divisible, if not, we bump it by one.
A better program would be:
x = 1
while x%11 != 0 or x%12 != 0:
x = x + 1
print(x, 'is divisible by 11 and 12')
The algorithm works by verifying all positive integers one by one. It has to start somewhere, and a good place to start is the first positive integer: 1. Hence x = 1 - means "let's start from 1".
x = x + 1 sets the value of x to the next integer. Imagine for example that x is equal to 42. Then the statement conceptually translates to x = 42 + 1 and in turn: x = 43. That's how the algorithm jumps to the next integer to verify.
If you not set x=1 at the beginning you couldn't use x as variable because it does not exists in current execution scope.
Part with x = x+1 is for growing up x for next loop iteration.
As per the sample code, it starts to check a number which is divisible by both 11 and 12. So it starts with x=1 in a range of [1,ideally infinite). The x=x+1 keeps incrementing x by 1 until it encounters a number which is divisible by both the numbers viz 132, once it does, it breaks the infinite while loop.

Categories