Question text is in black, solutions in blue.
Q1: 15 points Q2: 30+10 points Q3: 35 points Q4: 15 points Q5: 20 points Total: 100+10 points
For example, S(1) = -1, S(2) = -1 + 3 = 2, and S(3) = -1 + 3 - 5 = -3.
Continuing with examples, S(4) = 4, S(5) = -5, so it looks like S(n) =
(-1)nn. (Or S(n) = n for n even and S(n) = -n for n
odd.)
We prove this by induction. The base case is S(0) = 0, which is
given as part of the definition. For the induction, we assume that
S(n) = (-1)nn and look at S(n+1). It is S(n) +
(-1)n+1(2n+1) = (-1)n(n - (2n+1)) =
(-1)n(-n-1) =
(-1)n+1(n+1) as desired.
The theorem is that the number of squares in this figure,
n2 - 1, is divisible by three if and only if n itself is
not divisible by three. To prove this without induction, we
can compute that if n = 0 (mod 3), n2 - 1 = 2 (mod 3), and
that if n = 1 (mod 3) or n = 2 (mod 3), n2 = 1 (mod 3)
and thus n2 - 1 = 0 (mod 3).
To prove it by induction, we prove it for the base cases n = 0,
1, and 2, and then show that n2 - 1 has the same value mod
3 as does (n+3)2 - 1. The inductive step is true because
(n+3)2 = n2 + 6n + 9 is congruent to
n2.
The consequence of this theorem for P(n) is that P(n) must be
false when n is divisible by three, since any tiling would have to
involve a natural number of rectangles and thus cover a number of
squares divisible by three. When n is not divisible by three,
the theorem only tells us that the number of squares is all right for
the tiling to exist, not that the tiling actually exists. As
we will see, it does exist when n = 1 (mod 3) and does not when n = 2
(mod 3), but we haven't proved that yet.
Note first that this is the inductive step of a proof and does
not need induction to prove! Also, this statement is about tilings
(since P(n) refers only to tilings) and not about the divisibility
fact from part (a).
Assume P(n), so that an n by n block with the lower right square
missing can be tiled with 1 by 3 rectangles. Consider the figure for
P(n+3), an n+3 by n+3 square with the lower right square missing.
View this figure as (1) its top three rows, (2) the left three
columns, excepting the top three rows, and (3) the remainder, which
is an n by n square block with the lower right square missing. We
can tile (1) with n+3 vertical rectangles, cover (2) with n
horizontal rectangles, and cover (3) using the hypothesis P(n). So
we
have covered the figure and P(n+3) is true.
P(1) says that a 1 by 1 square, with the lower right square missing, can be tiled. This "figure" has no squares at all, so it is covered by an empty set of rectangles and P(1) is true. This fact forms the base case of an induction where part (b) is the inductive step, proving that P(n) is true whenever n = 1 (mod 3).
P(2) says that a 2 by 2 square, with the lower right square missing, can be tiled by 1 by 3 rectangles. Since this figure has three squares, we could only tile it with one rectangle, and clearly one rectangle cannot fit into this figure either horizontally or vertically. This fact does not combine with part (b) to prove anything about any values of P(n) other than P(2) itself, since we need true values of P(n) to use the inductive step. We could possibly use part (b) in its contrapositive form, ¬P(n+3) → ¬P(n), but not with ¬P(2) as the premise as 2 is not equal to n+3 for any natural n.
Coloring the figure for P(2) as suggested, and using Java-like zero
based indices for the squares, we get one red and two blue squares,
and no green squares.
This gives an alternate proof that P(2) is false, as if we needed
one, because a 1 by 3 rectangle must cover one square of each color
and thus a figure without an equal number of squares of each color
cannot be tiled.
More interestingly, we can prove that if the figure for P(n) has an
unequal number of squares of each color, so does the figure for
P(n+3). By the same analysis as in part (b), the added squares in
the figure for P(n+3) have an equal number of each color. This
completes an inductive proof that for any natural n with n = 2 (mod
3), the number of squares of each color is unequal and thus P(n) is
false.
It follows, of course, that P(302) is false.
IntTree
object is a tree where the leaves each store
int
values, so that the entire tree stores a set of
int
values, in no particular order.
public class IntTree {
boolean isLeaf;
int leafValue; // only defined if isLeaf is true
IntTree left; // left subtree if isLeaf is false
IntTree right; // right subtree if isLeaf is false
}
A valid IntTree
object is either (1) a leaf, where
isLeaf
is true and leafValue
is an
int
, or (2) a composite tree, where isLeaf
is false and both left
and
right
are valid IntTree
objects.
Nothing else is an IntTree
.
IntTree
objects, that every IntTree
has at least one leaf.
A tree that is a leaf clearly has at least one leaf. If a tree is
composite, the definition tells us that its left and right
subtrees are valid trees. The inductive hypothesis tells us
that each of these trees has at least one leaf, so the tree
itself has at least two leaves and thus at least one.
This is a complete inductive proof for trees -- the final
clause "nothing else is an IntTree
" means that if we
prove P(T) for T a single-node tree, and [P(L) ∧ P(R)]
→ P(T) when T is a composite tree with subtrees L and R, we
have proved P(T) for all valid trees.
t
is an IntTree
,
t.max()
returns the largest leaf value in t
.
Note that as an instance method, this is called from a tree and
does not take a tree (or a node) as an argument. The instance
attributes such as
public int max() {
if (isLeaf) return leafValue;
else return Math.max(left.max(), right.max());}
isLeaf
could be called
this.isLeaf
, etc., but this is not necessary. Many
students wanted to have global variables outside the method, but
a Java method can get its inputs only from its arguments or from
class variables.
IntTree
objects, that your max
method
terminates and returns the maximum leaf value in the tree, when
called from any valid IntTree
.
If the tree is a leaf, its leaf value is clearly the maximum leaf value in the tree (since it is the only value) and our method clearly terminates and returns it in this case. So assume (as inductive hypothesis) that the two subtrees of our calling tree are valid trees and that our recursive calls terminate and return the maximum leaf value in each subtree. Then our code terminates and returns the maximum of these two returned values, which is the maximum leaf value in the calling tree. This completes the induction and proves termination and correctness for all trees.
maxUpTo
for the IntTree
class that takes an
int
argument cap
and returns an
int
. If there is any leaf value in the tree
t
that is less than or equal to cap
,
t.maxUpTo(cap)
should return the largest such
value. If there is no such value, t.maxUpTo(cap)
should return cap + 1
.
public int maxUpTo (int cap) {
if (isLeaf)
if (leafValue <= cap) return leafValue;
else return cap + 1;
else {
int l = left.maxUpTo (cap);
int r = right.maxUpTo (cap);
if ((l <= cap) && (r <= cap)) return Math.max (l, r);
if ((l > cap) && (r <= cap)) return r;
if ((l <= cap) && (r > cap)) return l;
return cap + 1;}}
DFS: Exploring a puts b, c, and d on the stack, with c on top followed
by d. We next explore c, making (a,c) a tree edge, and put d
on the stack again. We then explore d, making (c,d) a tree
edge because we are exploring the last d put on, and
put b on the stack. We then explore that b (the last put on),
making (d,b) a tree edge, and put e on the stack. We finally
explore e, making (b,e) a tree edge, and stop because e is the
goal node. The two non-tree edges are (a,b) and (a,d), and
the path we have discovered is from a through c, d, and b to
e, which happens to be the optimal path of length 8.
BFS: Exploring a puts b, c, and d on the queue, with c at
the front followed by d. We next explore c, making (a,c) a
tree edge, and put d on the queue. We then explore the
first d put on, making (a,d) a tree edge, and put b on
the queue. We then explore the first b put on, making
(a,b) a tree edge and putting e on the queue. We then take
several nodes off the queue, and ignore them because we see
that they have already been explored, until we explore e, make
(b,e) a tree edge, and stop. The non-tree edges are (b,d) and
(c,d). The path we found was from a through b to d, of
distance 9 but "optimal" in the sense of having the smallest
number of edges in any path.
DFS: From a we visit c, from c we visit d, from d we visit c, and from
c we visit either a or d. However this tie is broken, we will
continue forever among a, c, and d without ever visiting b or
e and thus without ever terminating.
BFS: We will explore a and put b on the queue, then later we will
explore b and put e on the queue, then after that we will
explore e and terminate. We will find the same path as the
BFS of part (a), but we will put some additional nodes on the
queue and explore them before we do so.
Exploring a, we put the items (c,1), (d,2), and (b,6) on the priority queue and conclude that f(a), the distance from a to a, is 0. We then explore c, put (d,2) on the PQ, and conclude that f(c) = 1. We then explore d (either of the d items on the queue as they are tied), put (b,5) on the PQ, and conclude that f(d) = 2. We discard the other (d,2) as d has been explored. We then explore b, put (e,8) on the queue, and conclude f(b) = 5. Finally we explore e, conclude that f(e) = 8, and conclude because e is the goal node. Depending on how the PQ resolves the tie for d, we could find either of the two paths of distance 8, the path found by the DFS in part (a) or the path from a through d and b to e.
Last modified 16 November 2010