In 1960, the great Russian mathematician Andrey Kolmogorov conjectured that the traditional algorithm was optimal, meaning that any algorithm for that task would require order n2 elementary operations. Within a week, a 23-year old student Anatoly Karatsuba (shown above) found a more efficient algorithm, disproving Kolmogorov's conjecture. If you think that what you do as a student can't have a lasting impact, think again!
Kolmogorov published the method in 1962, in the Proceedings of the USSR Academy of Sciences. The article contained two results on multiplication, Karatsuba's algorithm and a separate result by Yuri Ofman; it listed "A. Karatsuba and Y. Ofman" as the authors. Karatsuba himself wasn't even aware of the paper until he received the reprints from the publisher. Google "Karatsuba Multiplication" to see the complete algorithm and discussion of its complexity.
Hint: when a step (in this algorithm) says to divide or asks for the quotient, that means integer division. And when it asks for the remainder, that means use the remainder operation. For example, the quotient of 19 divided by 3 is (19 // 3) and the remainder is (19 % 3). If you need both, you can do it in two steps.
n1 = 5678 n2 = 1234 a = 56 b = 78 c = 12 d = 34 e = 672 f = 2652 g = 6164 h = 2840 i = 6720000 j = 284000 k = 7006652 ans = 7006652Think about what steps 2 and 3 accomplished. Can you generalize this?
How to ask for user input: In your program you'll need to prompt the user to enter two 4-digit integers, using two input statements. The input function is not covered until slideset 3, but it's pretty easy. To get these values into variables n1 and n2, include the following two statements:
n1 = int( input("Enter a 4-digit integer: ") ) n2 = int( input("Enter a 4-digit integer: ") )When the first statement is executed, it will print the prompt "Enter a 4-digit integer: " on the screen, and wait for the user to enter a number. After the user types in a number, say 5678, this number is read by the program as a string, "5678". (The value returned by an input statement is always a string.) Then the function int() will convert that string back into an integer which will be stored in the variable n1. Then, you'll do the same for n2. From there you're good to go.
You can assume that the two numbers entered will represent positive 4-digit integers. Your program doesn't have to check that and doesn't have to work if the user enters bad values. We won't test your program on illegal values.
Don't use eval(): The book sometimes uses the function eval() to convert a string into an integer or float. This function is considered dangerous, especially when applied to user input. eval() passes its argument to the Python interpreter, and a malicious (or careless) user could input a command string that could:
> python Karatsuba.py Enter a 4-digit integer: 5678 Enter a 4-digit integer: 1234 Computed product: 7006652 Expected product: 7006652
The general Karatsuba algorithm is actually recursive; to multiply two n-digit numbers, you first split the numbers in half, yielding four n/2-digit numbers. Then when you're multiplying those, you apply Karatsuba's algorithm recursively, and so on. Instead of n2 elementary operations, this requires appoximately n1.58 operations. We'll talk about recursion later in the semester. For now, you'll have to trust me that this works and yields a substantial improvement in the efficiency of multiplication, especially for large integers.
By the way, Python allows integers of arbitrary size. The built-in integer multiplication routine in Python uses the "grade-school" algorithm if the integers have at most 70 digits and Karatsuba otherwise.
Your file must compile and run before submission. It must also contain a header with the following format:
# File: Karatsuba.py # Student: # UT EID: # Course Name: CS303E # # Date: # Description of Program:
If you submit multiple times to Canvas, it will rename your file name to something like Karatsuba-1.py, Karatsuba-2.py, etc. Don't worry about that; we'll grade the latest version.
Naming Variables: It's typically considered lousy programming practice to use single letter variable names. It's almost always much better to use descriptive names. However, the variables in this problem don't have obvious individual meanings, so go ahead and just use the variable names given.
Commenting: it's always a good idea to comment any part of your code that would be unclear to someone reading it later. However, the individual steps of this algorithm are individually clear, but collectively murky. That is, it's very easy to see what each step does; it's much murkier how they work together to multiply. So there's no need to comment each individual step. But there needs to be an overall comment that says what the algorithm accomplishes.
Output format: As explained in slide set 1, there are multiple ways to run your program. If you run in interactive mode (in the Python loop), the system will automatically display the result of every command (unless the result is None). If that result is a string, it will display with string quotes ('answer'). If you're running the program in batch mode (from the command line, as e.g. python myProgram.py) or explicitly print a string, it won't appear with string quotes. If you run your program in batch mode the only things you'll see displayed are the things you explicitly print; it won't display the results of individual commands. The following is in interactive mode:
>>> string = "my string" >>> string 'my string' >>> print(string) my string >>>If your string output doesn't match what's shown in the assignment sample output because of the presence or absence of string quotes, that may be the reason. Usually, it's not an issue to worry about.
But remember, you must turn in a file that contains the code to do this computation. So it's not adequate to just run the steps in interactive mode. You can do that while you're debugging the steps; but you need a complete program stored in a file for your submission.
Debugging with print statements: Many times over the course of this semester, you'll be asking yourself or others: What is wrong with my program? A good way to figure that out is to add print statements. The current program for example, has 12 steps you have to implement. If you wait until you've completed all 12 and then get the wrong answer, it's pretty hard to figure out where you went wrong. But we showed you above, for one specific example, the value of every intermediate result. So if you print the intermediate results as you generate them, you can focus in on the spot where your computations went wrong. A statement like:
print("a =", a)right after you've computed a will tell you if you're on the right track. It's only a small amount of effort to add the print statements, but it may save you a lot of trouble later on. Note that it's often especially useful to print out the parameters of a function call to see if the values you thought were passed were actually the values passed. Of course, don't forget to comment out or remove the extra print statements before you submit your assignment. To comment out a statement, just add a # character at the front of the line.