Vous êtes sur la page 1sur 6

CMU 15-251 Spring 2017

Homework 1
Writing session on Wednesday January 25

0. (SOLO) Read very carefully the course policies on the course webpage http://www.cs.cmu.
edu/~./15251/policy.html. This is a required component of the course. You will be asked
to acknowledge that you have read and understand the course policies.

1. (SOLO) Identify which of the following proofs are correct and which ones are not. Dont
just explain why the claim is wrong; rather, explain how the argument violates the notion of
a correct proof. In particular, you have to point out specifically which step of the argument
is wrong. If you think a proof is correct, you do not need to elaborate.
Note that in this problem, we are not evaluating the style of the proofs (i.e. how clearly
they are written). We are just interested in the correctness of the arguments.

(a) Claim: Every natural number is either prime or a perfect square.


Proof: As the inductive hypothesis, use Pn =every number less than or equal to n is
a prime or a perfect square.
P1 is certainly true, since 1 is a perfect square. Now consider n. If n is prime we are
done. Otherwise, n can be factored as n = rs with r and s less than or equal to n 1.
By the inductive hypothesis, r and s are perfect squares, r = u2 and s = v 2 . Then
n = rs = u2 v 2 = (uv)2 .
(b) Well show that 251 is a magic number.
Claim: For all positive integers n, we have 251n1 = 1.
Proof: If n = 1, 251n1 = 25111 = 2510 = 1. And by induction, assuming that the
theorem is true for 1, 2, . . . , n, we have

251n1 251n1 11
251(n+1)1 = 251n = = = 1;
251n2 1
so the theorem is true for n + 1 as well.
(c) Claim: For all negative integers n, 1 3 + (2n + 1) = n2 .
Proof: The proof will be by induction on n.
Base Case: 1 = (1)2 . It is true for n = 1.
Inductive Hypothesis: Assume that 1 3 + (2n + 1) = n2 .
Inductive Step: We need to prove that the statement is also true for n 1 if it is true for
n, that is, 1 3 + (2(n 1) + 1) = (n 1)2 . Starting from the left hand side,

1 3 + (2(n 1) + 1) = (1 3 (2n + 1)) + (2(n 1) + 1)


= n2 + (2(n 1) + 1) (Inductive Hypothesis)
2
= n + 2n 1
= (n 1)2 .

Therefore, the statement is true.

1
(d) Claim: Every positive integer n 2 has a unique prime factorization.
Proof: We will prove by strong induction on n.
Base Case: 2 is a prime itself. It is true for n = 2.
Inductive Hypothesis: Assume that the statement is true for all 2 k n.
Inductive Step: We must prove that the statement is true for n + 1. If n + 1 is prime,
then it itself is a unique prime factorization. Otherwise, n + 1 can be written as x y
where 2 x, y n. From the inductive hypothesis, both x and y have unique prime
factorizations. The product of unique prime factorizations is unique, therefore, n + 1
has a unique prime factorization.

2. (SOLO) You have a jar filled with beans. Some are black and some are white. You also have
a supply of beans of each color outside the jar. We carry out the following process. We reach
in and pick two beans out of the jar. If they are both black we remove them and add a white
bean from our external supply of beans. If they are both white we put one back and remove
the other. If one is white and one is black we put the black one back and remove the white
one. We continue until there is only one bean left.
What is the color of this last bean?
The answer depends on the initial situation. What we want is a precise description of the
circumstances under which the last bean is guaranteed to be white and a description of the
circumstances under which the last bean is guaranteed to be black.
Does this question have anything to do with what we have discussed in class?

3. (SOLO)
If u and v are strings over an alphabet , we let uv denote the string obtained by concatenating
u and v. For example, if u = 101 and v = 00, then uv = 10100. Let L be a language over the
alphabet = {0, 1} that is defined recursively as follows:

 L;
u, v L = 0u1v L;
u, v L = 1u0v L.

The only strings in L are the ones that can be constructed inductively by applying the above
rules. Prove that L is the language consisting of all strings that have an equal number of 0
symbols and 1 symbols. In other words, if K denotes the language consisting of all strings
with an equal number of 0s and 1s, then you need to show that L = K. To do this, you
should argue L K and K L.

4. (SOLO) Fix an alphabet . In this question, we consider languages over the alphabet .
Recall that languages are sets, so they can be combined and manipulated using standard set
operations. For example, if L1 and L2 are two languages, then their union L1 L2 is also a
language. We define three additional operations on languages below.
Given two languages L1 and L2 , we define their concatenation, denoted L1 L2 , as the language

L1 L2 = {uv : u L1 , v L2 }.

Given a language L, we define the star of L, denoted L , as the language

L = {u1 u2 . . . uk : k 0 and ui L for all i {1, 2, . . . , k}}.

2
(Above, if k = 0, then u1 u2 . . . uk = .) Lastly, given a language L, we define its reversal,
denoted LR , as the language
LR = {w : wR L},
where the reversal of a string w = a1 a2 . . . an is defined as the string wR = an an1 . . . a1 . For
example, 010001R = 100010.
We define the notion of an awesome language recursively as follows.

is awesome;
{w} for each w is awesome;
if L1 and L2 are awesome, then L1 L2 is awesome;
if L1 and L2 are awesome, then L1 L2 is awesome;
if L is awesome, then L is awesome.

Prove that being awesome is closed under the reversal operation. That is, prove that if L is
awesome, then LR is also awesome.

5. (OPEN) If u is a string over an alphabet and n is a non-negative integer, we define un to


be the word obtained by concatenating u with itself n times. For example, if u = 101, then
u3 = 101101101 and u0 = .
Let be some arbitrary finite alphabet. Let u and v be two non-empty words with the
property that uv = vu. Show that there must be a non-empty word w and positive integers
i and j such that u = wi and v = wj .

6. (OPEN) There are 251 Bad Guys and 251 Good Guys. The 251 Bad Guys line themselves
up in a room, each carrying a white hat and a black hat. One by one, Good Guys come into
the room. When Good Guy i comes in (1 i 250), one of the hatless Bad Guys waves his
hand. (The Bad Guys get to choose who waves.) Good Guy i then gets to tell the waving
Bad Guy to put on either his black hat or his white hat. Following this, the Good Guy leaves,
never to be seen again (i.e., he cannot communicate with the future incoming Good Guys).
After the first 250 Good Guys have entered the room the game changes. At this point, only
one Bad Guy is hatlesslets call him the Bad Captain. The Bad Captain must put on a
hat now, but he gets to decide the color. Finally, the last Good Guy enters the roomlets
call him the Good Captain. In some sense, his task is to guessbased on the hat colors
he seeswho the Bad Captain is. More precisely, the Good Captain must announce some
subset J of the Bad Guys, and J must be guaranteed to contain the Bad Captain. The
Good Captain then pays a price of |J| dollars. For example, the Good Captain is allowed to
pick J to be all 251 Bad Guys. However, this costs a lot: $251. Its possible for the Good
Guys to do better.
The Good Guys are trying to use a strategy that guarantees theyll never pay more than
some C dollars. (They can decide on a strategy together before the game starts.) The Bad
Guys are trying to use a strategy that forces the Good Guys to pay as much as possible.
Find and prove a strategy for the Good Guys that keeps their cost C as small as you can.
You certainly do not have to prove your C is as small as possible (in fact, we personally dont
know how to do this). You should just strive to get C small. Getting it in the low triple-digits
is a reasonable start. Getting it in the low double-digits would be a lot better.

3
(Remark: this problem doesnt have anything to do with what we covered in class. Its basically
just a puzzle. However, it is characteristic of some of the types of problems that actually arise
in theoretical computer science. Indeed, at a mystery date in the future we will describe how
this exact problem arose. . . )
7. (PROG) In this question we ask you to write some relatively simple Python programs/functions.
If you dont know Python syntax, no problem. It is very easy to pick up and there are
many resources available online. For example the 15-112 course webpage is a great resource:
http://www.kosbie.net/cmu/fall-16/15-112/schedule.html. You only need to know the
very basics, so dont get too carried away.
You might be wondering the motivation behind this programming question. At this point
the motivation will not be very clear, but we want you to get used to some concepts that will
show up later on in the semester (probably in week 4). Our hope is that this question will
make some of the challenging concepts that we will cover in the future easier to digest.
Here is an example of a very simple Python function which correctly determines if the input
integer is a prime number.

def isPrime(N):
if (N < 2): return False
for factor in range(2,N):
if (N % factor == 0): return False
return True

This creates on object of type function whose name is isPrime. We can view this as a program.
When we call isPrime with an input, the code inside it gets executed. The string encoding
of this function object will be its (source) code as text. So hisPrimei is the string

"def isPrime(N):\n if (N < 2): return False\n for factor in range(2,N):


\n if (N % factor == 0): return False\n return True"

In Python, you can obtain this string using triple quotes as follows:

"""def isPrime(N):
if (N < 2): return False
for factor in range(2,N):
if (N % factor == 0): return False
return True"""

(a) Write a function called isRecursive that takes a string as input. We assume that the
input string corresponds to an encoding of a valid Python function (so you do not need
to do a check for this). The function returns True if the input function is recursive, and
False otherwise.
For this question, you might find the built-in string operations and methods useful. See
https://www.cs.cmu.edu/~112/notes/notes-strings.html. This question is meant
to be relatively straightforward: just check whether the function name appears in the
function body. This is technically a buggy solution, but we wont care about it.
Learning objective: In your programming experience, you may have never written a
function that takes the source code of another function as input. We want you to get
comfortable with this idea.

4
(b) Create a string that corresponds to the encoding of your isRecursive function, hisRecursivei.
Call isRecursive(hisRecursivei) and observe the output.
Learning objective: The interesting/weird thing here is that we are calling a function by
giving its own source code as input. The point of this part of the question is to realize
that, though strange at first, there is absolutely nothing wrong with doing such a thing.
(c) Write a function called complement that takes a string as input. We assume that the
input string corresponds to an encoding of a valid Python function f . Furthermore, we
assume that f always returns a Boolean value (i.e., it always returns True or False). The
function complement creates the encoding of a new function g that does the opposite of
f : on any input x, if f (x) returns True, then g(x) returns False, and if f (x) returns False,
then g(x) returns True. The encoding of this function g is then returned by complement.
We do not care about the name of the function being returned.
Learning objective: This part is similar in nature to part (a). We are creating a function
(complement) that takes as input the source code of a function. We are then able to
modify this source code in meaningful ways.
(d) In Python, you can define a function inside another function. Here is an example:
def f(N):
def g(M):
return (2*M + 1)
return (g(N) + g(N+1))
Below we define a function called isEqual which takes as input two encodings of Python
functions f 1 and f 2. Both f 1 and f 2 are assumed to take as input a natural number.
The function isEqual returns True if f 1(N ) = f 2(N ) for all N {0, 1, 2, . . . , 999}, and
returns False otherwise. In other words, isEqual is trying to decide whether f 1 and f 2
compute the same computational problem. It doesnt actually do that since we dont
check input values larger than 999, but there is no way we can check all possible input
values in a finite amount of time. So we will be content with checking values up to 1000.
def isEqual(fn1, fn2):
exec(fn1)
exec(fn2)
for x in range(1000):
if(locals()[f1](x) != locals()[f2](x)): return False
return True
You do not need to understand the exact syntax used above, but we hope you have a
reasonable guess about how the function works. Here, there is an implicit assumption
to keep the code clean: the name of the function corresponding to f n1 is f 1 (so f n1 is
a string whose first 5 characters are def f1). We have the same assumption for f n2.
To understand the first couple of lines, note that the function exec executes the input
string as code. So exec(f n1) actually defines the function f 1 locally inside isEqual.
Your task is to write a function called autograderIsPrime which takes as input a string
corresponding to the encoding of a function named f 1. It then checks if f 1 is a correct
primality testing function/program. To do this, you should be calling the isEqual func-
tion inside the autograderIsPrime function, where the first input to isEqual is f 1 and
the second input is the string encoding of a correct primality testing function named

5
f 2. This string must be defined locally inside autograderIsPrime. Do not use global
variables.
Learning objectives: In this question, we want you to realize that in a function/program,
we can create the source code of another function from scratch and make use of it. Note
that the function does not (and should not) run this source code; we are merely creating
a string.
The second thing to notice is that if we actually had an isEqual function that works per-
fectly correctly, then we would also have an autograder function for primality testing that
works perfectly correctly. (However our isEqual function is buggy since it only checks
values up to 1000.) In this kind of a situation, we say that solving autograderIsPrime
reduces to solving isEqual.

8. (SOLO - BONUS) Solve the Infected Chessboard Problem seen in class. What is the
smallest number of initially infected squares required to infect an n n board? Does it
depend on n? If so, how?
Note: Bonus problems should be typed up and sent to the instructors by email. You have 2
weeks to submit after the homework is published.
Bonus problems are not worth many points. They are mainly for your spiritual growth!