Read this entire document before beginning to write your solutions!
You should work on this lab with your partner and submit one lab report with both your names on it. The report should be submitted via email. It should consist of a single attachment which is one Python file.
Warmups.
Write a function is_even that takes as input a number and returns a Boolean value indicating whether or not the input expression is an even number. Example behavior:
>>> is_even(17) False >>> is_even(204) True
Write a read-evaluate-print-loop function find_max_repl that prompts the user to enter five numbers and prints the largest of those five numbers. Example behavior:
>>> find_max_repl() Enter the first number: 43 Enter another number: 50 Enter another number: 19 Enter another number: 87 Enter another number: 1 Largest number entered: 87
Checksums.
Recall the function presented in lecture to compute the sum of the digits of a number:
def sum_digits(n):
sum = 0
x = n
while x > 0:
sum = sum + (x % 10)
x = x / 10
return sum
Also, recall the idea of using the sum of the digits of a number as a
way of verifying that a number received via electronic communication
has been transmitted correctly. For example, if we wish to send the
number of 213, we would would send 2136 using the last digit as
a checksum (or check digit) that the recipient can use
to verify the first three digits received.
We can use the sum_digits function to compute this checksum, except
that we want the checksum to be only one digit long. For example, for
the number 815, the sum of the digits is 14, but the one-digit
checksum is 5 since it is the sum of the digits 1 and 4.
Write a function compute_check_digit that takes as input a number and returns a one-digit checksum corresponding to that number. You can go about this at least two different ways. I recommend making your function repeatedly call the sum_digits function until the result is a single digit. Example behavior:
>>> compute_check_digit(815) 5 >>> compute_check_digit(9182) 2 >>> compute_check_digit(44) 8
Write a function append_check_digit that takes a number as input and returns a larger number consisting of the original number with a check digit appended. For example:
>>> append_check_digit(44) 448 >>> append_check_digit(815) 8155 >>> append_check_digit(9182) 91822
>>> check_check_digit(91822) True >>> check_check_digit(449) False
The Collatz-Ulam Conjecture. Recall this simple algorithm from our first lab:
input n
if n is even then:
output n / 2
else:
output 3 * n + 1
Implement the above algorithm as a function called ulam. Example behavior:
>>> ulam(5) 16 >>> ulam(16) 8
Things get more interesting when you try taking the output from the ulam function and plugging it back in as input. If you do this repeatedly, it is often surprising how many times repetitions it requires before the function lands at 1. For example, given the number 3 as a starting point, you can see it requires 7 steps:
3 → 10 → 5 → 16 → 8 → 4 → 2 → 1
Write a function called collatz to count how many repetitions of ulam are required until a 1 is encountered. Example behavior:
>>> collatz(1) 0 >>> collatz(3) 7 >>> collatz(4) 2 >>> collatz(6) 8
Write a function collated_collatz that takes a number as an input and prints a table of values indicating the result of collatz function for each number from 1 up to and including the input limit. Example behavior:
>>> collated_collatz(5) n collatz(n) ---------------- 1 0 2 1 3 7 4 2 5 5
Experiment with your collatz and collated_collatz functions. Do you observe any discernible pattern with the values of collatz(n) as n increases? How does this problem relate to the idea that complex behavior can arise from simple components? In what ways, if any, does your investigation call into question whether the collatz function is an algorithm in the formal sense discussed at the beginning of the semester? Answer these questions in the form a Python comment (i.e. with lines beginning with # in your program file).
Extra credit. Add the function:
def collatz_ratio(n):
return float(collatz(n)) / n
to your program. Write a function find_max_collatz_ratio that
takes two parameters, start and stop and returns the
number in the range from start (inclusive) to stop
(exclusive) for which collatz_ratio is largest. Use your
function to find the the five largest ratios (and the numbers that
generate those ratios) between 1 and 1000.
The game of Nim.
Nim is a very simple two-player, zero-sum game. There are many variants. The variant we consider is as follows: there are 21 pebbles in a pile on the ground. The two players take turns removing either one or two pebbles at a time. The player who removes the last pebble loses (and the other player wins).
Write a Python program that plays Nim. One player is expected to be a human user; the other player is the computer itself. You should write at least three functions (though you are welcome to write more) to implement the game. My solution uses three functions: nim (the game itself), human_nim_move which prompts the user to choose either 1 or 2 pebbles to remove and returns the selected number, and computer_nim_move which returns 1 or 2 according to the number of pebbles that are remaining and the "whim" of the computer. You do not need to make your computer play particularly intelligently. In this transcript the computer is randomly selecting 1 or 2 each time around (unless there is only 1 pebble left!).
Your game should use Python's random number generator to determine, each time the game is played, whether the computer or the human is to make the first move. To make use of the random number generator, include the line:
import randomin your Python program. You can then choose a random value between 1 and 2 by using:
random.randrange(1,3)
Extra credit:
You may find it useful to experiment with my solution - you can download this module and import it into Python.