Comp Sci analysis Assignment2-Solutions
Comp Sci analysis Assignment2-Solutions
1. For both parts of this question, consult Algorithm 1. Your answers should follow that same style and
format as shown in class.
Algorithm 1
1: //pre: (y == 3) ∧ (n ∈ {1, −1})
2: x ← 2
3: w ← x + y
4: //assert:
5: if n < 0 then
6: w ← −w
7: end if
8: //post: w == 5 · n
(3 marks) (a) Provide an assert statement for line 4. You’ll need to do some planning ahead: read part (b)
to help guide your choice for the assert statement.
(6 marks) (b) Prove that the code satisfies the Partial Correctness property. In particular: assume that the
code terminates, and prove that the following two statements are true:
• (pre is true when line 1 is reached) ⇒ (assert is true when line 4 is reached)
• (assert is true when line 4 is reached) ⇒ (post is true when line 8 is reached)
Solution:
(3) Suppose that pre is true when line 1 is reached, i.e., that y = 3 and
n ∈ {−1, 1} at line 1.
(4) From (3) and the fact that the value of y is not modified in line 2 of the
code, it follows that y = 3 when line 3 is reached.
(6) From (4) and (5), we conclude that x + y = 2 + 3 = 5. This value is assigned
to w on line 3, so the value of w is 5 immediately before line 4.
(7) From (3) and the fact that the value of n is not modified in lines 2-3 of the
code, it follows that n ∈ {−1, 1} immediately before line 4.
(10) Suppose that assert is true when line 4 is reached, i.e., that w = 5 and
n ∈ {−1, 1}.
(11) There are two cases to consider based on the possible values of n:
• Case (a): suppose that n = −1. In this case, since n < 0, the if condition on
line 5 evaluates to true. This means that line 6 is executed. From (10), we
know that w = 5 at line 4, and, since the value of w is not changed on line 5,
the value of w is 5 immediately before line 6. At line 6, the value of w is
changed to −w, so, immediately after line 6, the value of w is −5. As the value
of w is not changed after line 6, the code reaches line 8 with w = −5 = 5 · n.
This proves that post is true when line 8 is reached.
• Case (b): suppose that n = 1. In this case, since n ≥ 0, the if condition on
line 5 evaluates to false. This means that line 6 is not executed, and line 8 is
reached immediately after line 5. From (10), we know that w = 5 at line 4,
and, since the value of w is not changed on line 5, it follows that w = 5 = 5 · n
at line 8. This proves that post is true when line 8 is reached.
1
(1) Let M = 10 and let x 0 = 840.
(2) Let x be an arbitrary number such that x > x 0 , i.e., x > 840.
2
(3) From (2), we know that x > 840. Multiplying both sides by 2x , we get that x2 > 420x.
p
(4) From (2), we know that x > 840, which also means that x > 160. Squaring both sides,
2
we get that x 2 > 160, which means x2 > 80.
2 2
(5) From (3) and (4), we get x2 + x2 > 420x + 80, which we can re-arrange to get
1 2
x 2 − 420x − 80 > 0. Dividing both sides by 10, we get 10 x − 42x − 8 > 0.
1 2
(6) Since 10 x = 51 x 2 − 10
1 2 1 2
x , we can re-write 10 x − 42x − 8 > 0 as
1 2 1 2
− 42x − 8 > 0. Re-arranging gives 51 x 2 − 42x − 8 > 1 2
5 x − 10 x 10 x .
1
(7) Since M = 10 , our conclusion in the previous step shows that 15 x 2 − 42x − 8 ≥ M x 2 ,
which concludes the proof that 15 x 2 − 42x − 8 ∈ Ω(x 2 ).
Solution:
(2) Applying Fact (5.1) with c = 6, we see that 6n log n ∈ Θ(n log n).
(3) Applying Fact (3.1) to the outcome of step (2), we get 6n log n ∈ Ω(n log n).
(4) Applying Fact (4.2) with g(n) = 2n + log3 n to the outcome of step (3), we get
6n log n + 2n + log3 n ∈ Ω(n log n), as desired.
(5) Next, we prove that 6n log n + 2n + log3 n ∈ O(n log n), which is broken into 3 parts (one
for each term of the sum).
(6) For the first term, we prove 6n log n ∈ O(n log n).
(7) Applying Fact (5.1) with c = 6, we see that 6n log n ∈ Θ(n log n). Then applying Fact
(3.1), we get 6n log n ∈ O(n log n).
(9) Applying Fact (5.1) with c = 2, we see that 2n ∈ Θ(n). Then applying Fact (3.1), we get
2n ∈ O(n).
(11) Applying Fact (5.4) to the outcomes of steps (9) and (10), we get 2n ∈ o(n log n). Then
applying Fact (3.4), we get 2n ∈ O(n log n).
(12) For the third term, we prove log3 n ∈ O(n log n).
(13) Applying Fact (5.1) with c = 1, we see that log n ∈ Θ(log n). Then applying Fact (3.1), we
get log n ∈ O(log n).
(14) Applying Fact (1.2), we get log n ∈ o(n0.5 ). Then applying Fact (3.4), we conclude that
log n ∈ O(n0.5 ).
(15) Applying Fact (5.4) to the outcomes of step (14), we get that log2 n ∈ o(n0.5 · n0.5 ) = o(n).
(16) Applying Fact (5.4) to the outcomes of steps (13) and (15), log3 n ∈ o(n log n). Then
applying Fact (3.4), we get log3 n ∈ O(n log n).
(17) Applying Fact (4.1) to the outcomes of steps (7), (11), (16), we get
6n log n + 2n + log3 n ∈ O(n log n), as desired.
(18) Applying Fact (3.1) to the outcomes of steps (4) and (17), we get
6n log n + 2n + log3 n ∈ Θ(n log n), which completes the proof.
(1 mark) (a) For all odd integers n ≥ 3, explain how to construct a "worst-case array" with n entries, by
which we mean: an array that maximizes the number of times the if condition evaluates to
true. For simplicity, have each array entry equal to either 0 or 1.
Solution: For i ∈ {0, . . . , n − 1}, set A[i] = 1 if i even, and set A[i] = 0 if i is odd.
(2 marks) (b) For all odd integers n ≥ 3, how many times does the if statement evaluate to true when
the code is executed on a worst-case array with n entries? For which values of i will the if
condition evaluate to true when the code is executed on a worst-case array? Your answers
should be in terms of n.
Solution: The if statement will evaluate to true (n − 1)/2 times, and this will happen at
all odd array indices, i.e., for each i ∈ {1, 3, . . . , n − 2}.
Solution:
• Line 2 is executed, it counts as 1 step.
• For each i ∈ {0, . . . , n − 1}, there are two cases for the execution of the while loop:
– The loop condition is checked (1 step), it evaluates to true, the if condition is
checked (1 step), it evaluates to true, otherFunction(i) is executed (g(i)
steps), and line 7 is executed (1 step). The total is 3 + g(i) steps.
– The loop condition is checked (1 step), it evaluates to true, the if condition is
checked (1 step), it evaluates to false, and line 7 is executed (1 step). The total
is 3 steps.
• When executing the while loop with i = n, the loop condition is checked (1 step)
and it evaluates to false. This counts as 1 step.
When executing the while loop each i ∈ {0, . . . , n − 1}, notice that 3 steps are always
performed, and in the case where the if condition evaluates to true, an additional g(i)
steps are performed. From part (b) of this question, the if condition evaluates to true for
all odd i ∈ {1, 3, . . . , n − 2}, i.e., when i = 2k + 1 for k ∈ {0, . . . , (n − 3)/2}. So counting for
all i ∈ {0, . . . , n − 1}, the number of steps is:
(n−3)/2
n−1
X X
3 + g(2k + 1)
i=0 k=0
(n−3)/2
n−1
X X
=3 1 + g(2k + 1)
i=0 k=0
(n−3)/2
X
= 3 [(n − 1) − 0 + 1] + g(2k + 1)
k=0
(n−3)/2
X
= 3n + g(2k + 1)
k=0
Adding the two additional steps for Line 2 and when i = n, the final expression for the
worst-case number of steps performed by myFunction(n) is
(n−3)/2
X
2 + 3n + g(2k + 1)
k=0
Algorithm 3 otherFunction(int m)
1: //pre: (m ∈ Z) ∧ (m ≥ 1)
2: j ← 1
3: while j ≤ m do
4: j←j∗3
5: end while
Solution:
• Line 2 is executed, it counts as 1 step.
• For each j ≤ m, the loop condition evaluates to true, and 2 steps are performed: the
loop condition check on line 3, and the execution of line 4. We need to figure out
when the loop condition evaluates to true.
The k’th time that the loop condition is checked, the value of j is 3k−1 . So the
loop condition evaluates to true as long as 3k−1 ≤ m. Solving for k, we get that
k ≤ log3 (m) + 1. Since k must be an integer, we can conclude that k ≤ ⌊log3 (m) + 1⌋.
Since 1 is an integer, we can use a property of the floor function from page 9 to see
that ⌊log3 (m) + 1⌋ = ⌊log3 (m)⌋ + 1. So for all k ∈ {1, . . . , ⌊log3 (m)⌋ + 1}, the loop
condition evaluates to true the k’th time that the loop condition is checked, and 2
steps are performed in the loop execution each time.
• When executing the while loop with j > m, the loop condition is checked (1 step)
and it evaluates to false. This counts as 1 step.
In total, the number of steps is
(m)⌋+1
⌊log3X
2+ 2
k=1
(m)⌋+1
⌊log3X
= 2+2· 1
k=1
= 2 + 2 · (⌊log3 (m)⌋ + 1) − 1 + 1
= 2 + 2 · (⌊log3 (m)⌋ + 1)
= 4 + 2 · ⌊log3 (m)⌋
Solution: From parts (c) and (d), we get that the worst-case number of steps performed
by myFunction is
(n−3)/2
X
2 + 3n + g(2k + 1)
k=0
(n−3)/2
X
= 2 + 3n + 4 + 2 · ⌊log3 (2k + 1)⌋
k=0
(n−3)/2
X (n−3)/2
X
= 2 + 3n + 4 + 2 · ⌊log3 (2k + 1)⌋
k=0 k=0
(n−3)/2
X (n−3)/2
X
= 2 + 3n + 4 · 1 + 2 · ⌊log3 (2k + 1)⌋
k=0 k=0
(n−3)/2
X
= 2 + 3n + 4 · [(n − 3)/2 − 0 + 1] + 2 · ⌊log3 (2k + 1)⌋
k=0
(n−3)/2
X
= 2 + 3n + 2(n − 3) + 4 + 2 · ⌊log3 (2k + 1)⌋
k=0
(n−3)/2
X
= 5n + 2 · ⌊log3 (2k + 1)⌋
k=0
Solution: Using our answer from part (e), we see that the worst-case number of steps
performed by myFunction is
(n−3)/2
X
5n + 2 · ⌊log3 (2k + 1)⌋
k=0
(n−3)/2
X
≤ 5n + 2 · log3 (2k + 1)
k=0
= 5n + 2 · log3 (1) + log3 (3) + . . . + log3 (n − 2)
∈ O(n log n) (since 5n ∈ Θ(n) and 2 · log3 ((n − 2)!!) ∈ Θ(n log2 n))
Definitions
• The symbol Z represents the set of integers {. . . , −2, −1, 0, 1, 2, . . .}.
• The symbol N represents the set of positive integers {1, 2, 3, . . .}.
• The symbol R represents the set of real numbers.
• An integer n is even if there exists an integer k such that n = 2k.
• An integer n is odd if there exists an integer k such that n = 2k + 1.
• The floor of x, denoted by ⌊x⌋, is the largest integer that is less than or equal to x.
• The ceiling of x, denoted by ⌈x⌉, is the smallest integer that is greater than or equal to x.
• For every positive integer x, the double factorial x!! is defined as the product 1 · 3 · 5 · · · (x − 4) · (x − 2) · x when x is
odd, and, defined as the product 2 · 4 · 6 · · · (x − 4) · (x − 2) · x when x is even.
Floors/Ceilings
For any real number x and any real number y ̸= 0:
• −⌊x⌋ = ⌈−x⌉ and −⌈x⌉ = ⌊−x⌋
• for any integer k: ⌊k⌋ = ⌈k⌉ = k
• for any integer k: k + ⌊x/ y⌋ = ⌊k + x/ y⌋
• for any integer k: k + ⌈x/ y⌉ = ⌈k + x/ y⌉
• for any integer k: ⌊(k + 1)/2⌋ = ⌈k/2⌉ and ⌈(k − 1)/2⌉ = ⌊k/2⌋
⌊x/a⌋ ⌈x/a⌉
• for any integers a, b: ⌊ b ⌋ = ⌊ ab
x
⌋ and ⌈ b ⌉ = ⌈ ab
x
⌉
Summation Identities
b n
X X n(n + 1)
1= b−a+1 j=
j=a j=1
2
n n
X n(n + 1)(2n + 1) X n2 (n + 1)2
j =
2
j3 =
j=1
6 j=1
4
n ∞
X q n+1 − 1 X 1
∀q > 0, q ̸= 1, qj = ∀q, 0 < q < 1, qj =
j=0
q−1 j=0
1−q
b
b b b b
X X X X X
( f ( j) + g( j)) = f ( j) + g( j) c · f ( j) = c · f ( j) for any constant c
j=a j=a j=a j=a j=a
In these statements, a, b and c are constants (i.e., they are not functions of n), and f , g, h, f1 , f2 , g1
and g2 are functions that map Z+ → R+ .
Group 1: the hierarchy summarized. For all constants a > 0 and b > 0 and c > 0:
(1.1) if a > 1, then c ∈ o(loga (n))
(1.2) if a > 1, then loga (n) ∈ o(n b )
(1.3) if a < b, then na ∈ o(n b )
(1.4) if b > 1, then na ∈ o(b n )
(1.5) if 1 < a < b, then a n ∈ o(b n )
(1.6) a n ∈ o(n!)
Group 2: transitivity.
(2.1) if f ∈ O(g) and g ∈ O(h), then f ∈ O(h)
(2.2) if f ∈ Ω(g) and g ∈ Ω(h), then f ∈ Ω(h)
(2.3) if f ∈ o(g) and g ∈ o(h), then f ∈ o(h)
(2.4) if f ∈ ω(g) and g ∈ ω(h), then f ∈ ω(h)
Group 4: addition.
(4.1) if f ∈ O(h) and g ∈ O(h), then f + g ∈ O(h)
(4.2) if f ∈ Ω(h), then f + g ∈ Ω(h)
(4.3) if f ∈ o(h) and g ∈ o(h), then f + g ∈ o(h)
(4.4) if f ∈ ω(h), then f + g ∈ ω(h)
Group 5: multiplication.
(5.1) for any constant c > 0, c f ∈ Θ( f )
(5.2) if f1 ∈ O(g1 ) and f2 ∈ O(g2 ) then f1 f2 ∈ O(g1 g2 )
(5.3) if f1 ∈ Ω(g1 ) and f2 ∈ Ω(g2 ) then f1 f2 ∈ Ω(g1 g2 )
(5.4) if f1 ∈ O(g1 ) and f2 ∈ o(g2 ) then f1 f2 ∈ o(g1 g2 )
(5.5) if f1 ∈ Ω(g1 ) and f2 ∈ ω(g2 ) then f1 f2 ∈ ω(g1 g2 )
Solution
Proof.
3 n 3
(1) n ∈ o( 2.5 ) by Fact (1.4) since 2.5 > 1.
3 n
(2) n ∈ O( 2.5 ) by Fact (3.4) applied to the outcome of step (1).