Download as pdf or txt
Download as pdf or txt
You are on page 1of 13

Q1 Dot Product

5 Points

Let us represent n-dimensional vectors as lists of length n of numbers (floats).

Write a Python program that given two vectors a and b returns their dot-product = ∑  ai ​ ⋅
bi ​, by filling in the numbered blanks appropriately in the subparts of this question.

def dotproduct(a, b):

# INPUT a, b lists of float, both of length n

# OUTPUT ans of type float

# OUTPUT ans == sum a_i ⋅ b_i

n = len(a)

ans = ______ # initialisation (1)

# INVARIANT ___________________(2)

for i in range __________________: # range (3)

_______________ # body (4)

# EXIT i == _______ (5)

# Time complexity is O(___) (6)

return ans

Q1.1 Initialisation
0.5 Points

To what value should variable ans be initialised? (use a decimal point, e.g., -1.0)

0.0

Q1.2 Loop Invariant


1 Point

Complete the loop invariant.

∀j(0 ≤ j < i) : ans ==

Q1.3 Loop range


0.5 Points

The range of values for i is


(1, n)

Q1.4 Loop body


1.5 Points

The statements in the loop body are: (you may use multiple lines)

Q1.5 Loop exit condition


0.5 Points

When the loop is exited, the value of i is

when i == n+1

Q1.6 Time complexity


1 Point

The time complexity of this program is

Q2 Making change
7 Points

If you have an unlimited supply of ₹500, ₹200, and ₹100 notes, how many different ways are
there to make change for a given amount of money? For example, there are three ways of
making change for ₹400:

(i) ₹200 + ₹200,

(ii) ₹200 + ₹100 + ₹100,

(iii) ₹100 + ₹100 + ₹100 + ₹100.


Note that the ordering of the notes does not matter, e.g. ₹100 + ₹200 + ₹100 is still included
in case (ii) above.

Complete the following algorithm for this problem. Assume that the amount is always a
multiple of ₹100.
[Hint: To make change for e.g. ₹2100, I can either (a) use at least one ₹500 note and then
make change for ₹1600, or (b) make change for ₹2100 using only ₹200 and ₹100 notes.]

change521 : N → N

change521(n) = {
__(1)__ if n < 500,
​ ​

__(2)__ otherwise
Given a natural number n divisible by 100, change521(n) gives the number of different
ways to make ₹n using ₹500, ₹200, and ₹100 notes.

Your algorithm may use the following helper functions, which you should also complete:

change21(n) = __(3)__

change21(n) gives the number of different ways to make ₹n using ₹200 and ₹100 notes.

change1(n) = __(4)__

change1(n) gives the number of different ways to make ₹n using ₹100 notes.

Q2.1 Base case


1 Point

What should be returned by change521(n) if n < 500? (Write only a single mathematical
expression; no explanation needed)

return change21

Q2.2 Recursive case


2 Points

What should be returned by change521(n) if n ≥ 500?

(Write only a mathematical expression; no explanation needed)

If 500 notes are used then:

x == (n//500)

y == n%500

if x ==0:

return (0, change21(y))

elif x == 1:

return (1, change21(y)), (0, change21(n))

else:

return (2, change21(y)), (1, change21(n - 500)), (0, change21(n))


Q2.3 Body of change21
1.5 Points

Complete the definition of the mathematical function change21(n). You may use multiple
lines.

def change21(n):

# returns tuples which is (((number of 200 notes), (number of 100 notes for that case)),
further cases)

x = n//200

y = n%200

if x ==0:

return (0, change1(n))

elif x == 1:

return (1, change1(n%200)), (0, change1(n))

else:

return (2, change1(n%200)), (1, change1(n - 200)), (0, change1(n))

Q2.4 Body of change1


1.5 Points

Complete the definition of the mathematical function change1(n). You may use multiple
lines.

def change1(n):

x = n//100

return x

Q2.5 Generalizing the program


1 Point

What is the smallest modification to the algorithm that will make all three functions
change521(n), change21(n), change1(n) give the correct results even if n is not a
multiple of 100? (This need not be the most efficient way to handle that case.)

State which function you will change and to what you will change it.

we will add 1 change bit to change1(n)

instead of returning n//100

return (n//100),("change = ", n%100)

and so in all functions above one extra term of change in last will be added
Q3 Detecting List Element
6 Points

Here is the Python implementation of an algorithm detect to find whether a given integer
k is present in a list L of size n , assuming that the elements in L are stored in increasing
order ( L[i]<L[i+1] for 0 ≤ i<n-1 ).

def detect (L, first, last, k):

# INPUT L is a list of integers

# INPUT integers first and last are the

# first and last index of the search range

# INPUT k is the integer we try to find in list L

# OUTPUT True if k is present in L.

# False if k is not present in L.

# ASSUME that the elements of L are in increasing

# order from first to last

if last < first:

return False

else:

mid = (first + last)//2

if k == L[mid]:

return True

elif k < L[mid]:

return detect (L,first,mid-1,k)

else:

return detect (L,mid+1,last,k)

return False

first and last correspond to the index of the first and last elements of the range in which
to search. So, we would call this function as: detect (LL, 0, n-1, k) to find k in a list
LL of size n .

State the recurrence relation for the time complexity of the detect algorithm for an input
list of size n . Justify your answer.
Use the above recurrence to show that the time complexity of detect (LL, 0, n-1, k)
is O(log n).
th
Assume that we can obtain L[i] (the i element of list L ) in constant time, and we can
pass a list to a function in constant time.

Q3.1 Recurrence relation


3 Points

The Recurrence relation for detect algorithm is the following. Justify (explain) your answer.

we will keep bisecting our range untill we exhaust our range, this is the basic idea
if k = L[mid]

return True(we have found our number in list)

if not then we check to what side of mid is the answer and discard the useless section
of range, this will work provided the list is either increasing or dewcreasing and our list
is increasing

elif k < L[mid]:

return detect (L,first,mid-1,k)

that is if L[mid} is more then our required number, we decrease the last to mid

else:

return detect (L,mid+1,last,k)

that is if L[mid} is less then our required number, we increase the start to mid

when the function is recursively called, this bisection will keep on decreasing the range
untill we get answer or last becomes < start

Q3.2 Time complexity


3 Points

Show that the time complexity of detect is O(log n), where n is the number of elements
in the search range.

let there be 2^k elements, and for worst case we start from first element and go to last
element of list(ie full list)

now T(n) = T(n-1) + 2 (checking that if mid = required and checking first inequality

we will be able to proceed this way of bisecting k more times

T(n) = 1 + 2k(by induction, T(0) requires just 1 check)

now 2^k = n

log_2(n) = k

T(n) = 2log_2(n) +c

T(n) = O(log(n))

Q4 Permutations
7 Points

Consider the following algorithm (written in English, not Python) to compute all
permutations of a given list. For example, permutations[1,2,3] = [[1,2,3], [2,1,3], [2,3,1], [1,3,2],
[3,1,2], [3,2,1]].

permutations(lst):

If lst is empty:

Return [ [ ] ]

Otherwise:

Let x = lst[0] be the first element

Let rest = [ lst[1], lst[2], ..., lst[n-1] ] be the rest of the elements

Let perms = permutations(rest)

Let out = [ ] be the output list

For each element p of perms:

Let p_ins = insertions(x, p)

Add each element of p_ins to out

Return out

Assume that insertions(x, lst) is a function that takes an element x and a list lst and returns
the list of all possible ways to insert x into lst. For example, insertions(4, [1,2,3]) = [[4,1,2,3],
[1,4,2,3], [1,2,4,3], [1,2,3,4]].

Prove the correctness of this algorithm, i.e. show that the output of permutations(lst) is a list
containing every possible permutation of lst.

Q4.1 Induction variable


1 Point

We will prove the correctness of the algorithm using weak induction on

Q4.2 Base case


1 Point

Justify the correctness of the algorithm when the input is the empty list. (Keep your answer
short)

Q4.3 Induction hypothesis


1 Point

State the induction hypothesis.

Q4.4 Induction step (part 1)


1.5 Points
Assuming the induction hypothesis, explain why every element of the output list is a
permutation of lst. (Keep your answer short)

Q4.5 Induction step (part 2)


1.5 Points

Assuming the induction hypothesis, explain why every possible permutation of lst will appear
in the output list. (Keep your answer short)

Q4.6 A modification
1 Point

If we changed the base case to return the empty list [] if the input list is empty, what would
happen when we evaluate permutations([1]) ?

 It will never terminate


 It cannot be evaluated due to an error
 It will return []

 It will return [1]

 It will return [[1]]

Q5 Polynomial addition
8 Points

Suppose we represent polynomials of degree n

p(x) == cn ​xn + … + c2 ​x2 + c1 ​x + c0 ​

as lists [c0 ​, c1 ​, … cn ​] with the elements being the co-efficients given in lowest-to-highest
exponent order (“Little-Endian”).

Write a program to add two polynomials in x

p1 ​(x) == a0 ​ + a1 ​x + … + am ​xm , and

p2 ​(x) == b0 ​ + b1 ​x + … + bn ​xn

(Note m, n may be different.)

[Hint: you may use ideas from programs addvec and app discussed in class]

def addpoly(p1, p2):

# INPUT type of p1 is list of length m of float

# INPUT type of p2 is list of length n of float

# OUTPUT p3 is list of length k of type float

# where k == _____(1)
# OUTPUT p3 =~= p1 + p2

m = len(p1)

n = len(p2)

p3 = _____ # (2) initialisation

# rest of the function -- see (3)

Q5.1 Output list length


0.5 Points

The value of k (length of output list) is:

max(m, n) + 1

Q5.2 Initialisation
0.5 Points

To what should variable p3 be initialised?

Q5.3 Rest of the function


5 Points

Complete the body of the function addpoly (in Python). You may use multiple lines

Q5.4 Properties
2 Points

What properties are true about addpoly ?


every polynomial has an inverse wrt addpoly

 addpoly is commutative

[ 1 ] is an identity element of addpoly

[ 0 ] is NOT an identity element of addpoly

addpoly is associative

[ ] is an identity element of addpoly

Q6 Polynomial evaluation
7 Points

Now suppose we represent polynomial

p(x) = cn ​xn + … + c1 ​x + c0 ​

as a list [cn ​, cn−1 ​, … , c1 ​, c0 ​] with elements being the co-efficients in highest-to-lowest


exponent order (“Big-Endian”).

Write an efficient iterative program to evaluate a given polynomial at a given value of x,


using Horner’s Rule

cn ​xn + … + c2 ​x2 + a1 ​x + a0 ​

= (… (cn ​ ⋅ x + cn−1 ​) ⋅ x + … + c1 ​) ⋅ x + c0 ​

by filling in the numbered blanks in the subparts of this question.

def horner(p, x):

# INPUT type of x is float

# INPUT type of p is list of float of length n+1

# OUTPUT type is float

# OUTPUT specification: ans == sum c_[n-j] x^j

# over j = 0...n

n = len(p)-1 # degree of polynomial

ans = _____ # (1) highest coeff

# now deal with coefficients of lower exponents

# INVARIANT ans = sum c[n-j] x^j over j = 0...i-1

for i in range __ : #(2) range of i

# loop body see part (3)

# EXIT i == _________________(4)

# Number of addition operations:_____(5)

# Number of multiplication operation:_____(6)

return ans
Q6.1 Initialisation
1 Point

To what should ans be initialised?

Hint: look at the given loop invariant

i−1
ans == ∑j=0 ​ cn−j ​xj

p(0) or c0

Q6.2 Range for iteration


1 Point

What is the range for variable i ?

[Recall n ==n is the degree of the polynomial]

Q6.3 Loop Body


2 Points

Complete the loop body. You may use multiple lines,

Q6.4 Exit value


1 Point

What is the value of i on exit from the loop

Q6.5 Number of additions


1 Point

Exactly how many additions are performed?


Q6.6 Number of multiplications
1 Point

Exactly how many multiplications are performed?

Minor Exam 1  GRADED

STUDENT
Gurharinder Singh

TOTAL POINTS

5.5 / 40 pts

QUESTION 1

Dot Product 1.5 / 5 pts


1.1 Initialisation 0.5 / 0.5 pts

1.2 Loop Invariant 0 / 1 pt

1.3 Loop range 0.5 / 0.5 pts

1.4 Loop body 0 / 1.5 pts

1.5 Loop exit condition 0.5 / 0.5 pts

1.6 Time complexity 0 / 1 pt

QUESTION 2

Making change 1.5 / 7 pts


2.1 Base case 1 / 1 pt

2.2 Recursive case 0 / 2 pts

2.3 Body of change21 0 / 1.5 pts

2.4 Body of change1 0 / 1.5 pts

2.5 Generalizing the program R 0.5 / 1 pt

QUESTION 3

Detecting List Element 1 / 6 pts


3.1 Recurrence relation R 1 / 3 pts

3.2 Time complexity R 0 / 3 pts

QUESTION 4

Permutations 0 / 7 pts
4.1 Induction variable 0 / 1 pt

4.2 Base case 0 / 1 pt

4.3 Induction hypothesis 0 / 1 pt

4.4 Induction step (part 1) 0 / 1.5 pts

4.5 Induction step (part 2) 0 / 1.5 pts

4.6 A modification 0 / 1 pt

QUESTION 5

Polynomial addition 0.5 / 8 pts


5.1 Output list length R 0.5 / 0.5 pts

5.2 Initialisation R 0 / 0.5 pts

5.3 Rest of the function 0 / 5 pts

5.4 Properties 0 / 2 pts

QUESTION 6

Polynomial evaluation 1 / 7 pts


6.1 Initialisation 1 / 1 pt

6.2 Range for iteration 0 / 1 pt

6.3 Loop Body 0 / 2 pts

6.4 Exit value 0 / 1 pt

6.5 Number of additions 0 / 1 pt

6.6 Number of multiplications 0 / 1 pt

You might also like