cs1101s_1617s1_final
cs1101s_1617s1_final
(Semester 1 AY2016/2017)
INSTRUCTIONS TO STUDENTS
1. This assessment paper contains FIVE (5) questions and comprises TWENTY-TWO (22)
printed pages, including this page.
2. The full score of this paper is 80 marks.
3. This is a CLOSED BOOK assessment, but you are allowed to use TWO double-sided A4
sheets of written or printed notes.
4. Answer ALL questions within the space provided in this booklet.
5. Where programs are required, write them in the Source Week 10 language.
6. Write legibly with a pen or pencil. UNTIDINESS will be penalized.
7. Do not tear off any pages from this booklet.
8. Write your Student Number below USING A PEN. Do not write your name.
Student No.:
A.2. [1 mark]
Let n be the length of the input list xs. Describe the runtime of your function last_member
with respect to n using Q notation.
A.3. [1 mark]
Let n be the length of the input list xs. Describe the space consumption of your function
last_member with respect to n using Q notation.
Page 2 of 22
CS1101S
B. [5 marks]
We represent a set of numbers using a list of distinct numbers sorted in ascending order.
Complete the function, is_subset(S, T), to determine whether set S is a subset of set T,
which is true only if every element in S is also an element of T. We assume that 0 ≤ NS and
0 ≤ NT, where NS and NT are the number of elements in S and T respectively. If NS = 0, then S
is always a subset of T. Your function’s runtime should have an order of growth of O(NT).
function is_subset(S, T) {
if (is_null(S)) {
} else if (is_null(T)) {
} else {
Page 3 of 22
CS1101S
C.
You are given the following function, mystery(xs), that takes a list xs as argument and
returns a pair:
function mystery(xs) {
if (is_null(xs)) {
return pair(null, null);
} else {
let tmp = mystery(tail(xs));
let ys = pair(head(xs), tail(tmp));
let zs = head(tmp);
return pair(ys, zs);
}
}
C.1. [3 marks]
Given the following application of mystery, what would be the values of head(p) and
tail(p)?
let p = mystery(list(1, 2, 3, 4, 5, 7, 8));
head(p); // what is the returned value?
tail(p); // what is the returned value?
Value of head(p):
Value of tail(p):
C.2. [2 marks]
Given the following application of mystery and the returned values of head(p) and
tail(p), what should be the value of input?
let input = ???;
let p = mystery(input);
head(p); // returns value equal to list("A", "Q", "R").
tail(p); // returns value equal to list("T", "U", "P").
Value of input:
Page 4 of 22
CS1101S
D. [4 marks]
Write a function, mutable_append(xs, ys), which is similar to the built-in function
append, but in the result of mutable_append, every pair in the result list is an existing
pair of the input lists (i.e. no new pair is created). The given lists xs and ys can be destroyed
in the process.
function mutable_append(xs, ys) {
Page 5 of 22
CS1101S
E. [6 marks]
Recall from the lectures that a tree of numbers is a list whose elements are numbers or trees of
numbers. Write a function, transform_tree(t), that takes a tree of numbers t and returns
a new tree of numbers s, such that display_tree(s) displays a sequence of numbers that
is the reverse of display_tree(t). The display_tree function definition is shown
below:
function display_tree(tree) {
if (is_null(tree)) {
;
} else if (is_list(head(tree))) {
display_tree(head(tree));
display_tree(tail(tree));
} else {
display(head(tree));
display_tree(tail(tree));
}
}
Example:
let tree1 = ...; // a tree of numbers
let tree2 = transform_tree(tree1);
display_tree(tree1); // displays a sequence of numbers
display_tree(tree2); // displays a reverse of the above
Note that the new tree should not be produced by flattening the input tree.
function transform_tree(t) {
Page 6 of 22
CS1101S
F. [5 marks]
Write a function, shorten_stream(s, k), that takes in a stream s and a non-negative
integer number k, and returns a stream that contains the first k elements of s. If the length of
s is less than or equal to k, then the result stream will just behave like s. Note that s may be
an infinite stream.
function shorten_stream(s, k) {
Page 7 of 22
CS1101S
A. [4 marks]
Complete the following box-and-pointer diagram for the above representation of the example
network.
A_node "A"
B_node "B"
C_node "C"
D_node "D"
E_node "E"
Page 8 of 22
CS1101S
B. [2 marks]
Write a function, is_linked(x, y), that takes in nodes x and y, and returns true if and
only if there is a direct link from node x to node y.
Examples:
is_linked(B_node, C_node); // returns true
is_linked(B_node, D_node); // returns false
is_linked(C_node, E_node); // returns false
function is_linked(x, y) {
C. [3 marks]
Recall that for any proper node x, if there is a link from x to node y, then there is a link from
node y to x. Write a function is_proper(x) that takes a node x as argument and returns
true if the node x is proper and false otherwise.
function is_proper(x) {
Page 9 of 22
CS1101S
D. [4 marks]
In this question, you can assume that all nodes are proper. Write a function,
is_connected(x, y), that takes in nodes x and y, and returns true if and only if there
exists a chain of one or more links that connects node x to node y. Note that
is_connected(x, x) is always true.
Examples:
is_connected(B_node, C_node); // returns true
is_connected(A_node, D_node); // returns true
is_connected(A_node, E_node); // returns false
is_connected(E_node, E_node); // returns true
(Hint: beware of cycles in the network.)
function is_connected(x, y) {
Page 10 of 22
CS1101S
Example 1:
Consider the function
function plus(x, y) {
return x + y;
}
In order to display the result of the addition of 1 and 2, we can use plus_cps as follows:
plus_cps(1, 2, display); // displays the value 3
Example 2:
function length(xs) {
if (is_null(xs)) {
return 0;
} else {
return 1 + length(tail(xs));
}
}
Page 11 of 22
CS1101S
A. [4 marks]
Make use of the functions plus_cps in order to compute the sum of three given numbers.
Your function sum_cps needs to be written in CPS.
}
sum_cps(1, 2, 3, display); // displays the value 6
B. [4 marks]
Recall the factorial function:
function factorial(n) {
if (n <= 0) {
return 1;
} else {
return n * factorial(n – 1);
}
}
Write the factorial function in CPS.
}
factorial_cps(5, display); // displays the value 120
Page 12 of 22
CS1101S
C. [6 marks]
Consider the iterative version of the factorial function:
function fact_iter(n, acc) {
if (n <= 0) {
return acc;
} else {
return fact_iter(n – 1, n * acc);
}
}
function factorial_iter(n) {
return fact_iter(n, 1);
}
factorial_iter(5); // returns 120
}
function factorial_iter_cps(n, ret) {
return fact_iter_cps(n, 1, ret);
}
factorial_iter_cps(5, display); // displays 120
(ii) [2 marks] From your solution, can you characterize iterative functions with respect to
CPS? Compare the original continuation function with the continuation function that is passed
to the recursive call.
Page 13 of 22
CS1101S
global
env
g:=
p:
Page 14 of 22
CS1101S
global
env
g:=
p:
Page 15 of 22
CS1101S
B. [4 marks]
Programming languages such as Erlang were designed for applications that run continuously
for a long time, for example telephone switch systems. Such languages support changing
function values permanently, while programs run, in order to enhance their functionality and
fix bugs. The language designers need to make sure that all references to the function value
lead to the new implementation.
Recall that the meta-circular interpreter for the Source language represents compound functions
by tagged lists whose body element contains the parse tree of the respective function.
function make_compound_function(parameters, body, env) {
return list("compound_function",
parameters, body, env);
}
function function_body(f) {
return list_ref(f, 2);
}
We would like to add a primitive function hot_reload that takes two compound functions
as arguments. The function hot_reload replaces the body of the first function by the body
of the second function, without affecting the parameters and the environment of the function.
Example:
function h(x) { return x + 1; }
let p = pair(h, null);
display(head(p))(3); // displays 4
hot_reload(h, x => x * 2);
display(head(p))(3); // displays 6
You can assume that the primitive function hot_reload gets as arguments two compound
functions (as described above) that have the same number of parameters.
Page 16 of 22
CS1101S
function Smart_Room(aircon) {
this.aircon = aircon;
}
The argument aircon of the constructor of the Smart_Room class is an Appliance object,
which has the methods turn_on and turn_off.
Smart rooms are equipped with sensors that detect when the first user enters the room and when
the last user leaves the room.
Smart_Room.prototype.first_user_enters = function() {
this.aircon.turn_on();
};
Note that the method turn_on of Appliance objects makes sure the Appliance is on,
regardless whether it was off or on already.
Smart_Room.prototype.last_user_leaves = function() {
this.aircon.turn_off();
};
Note that the method turn_off of Appliance objects makes sure the Appliance is off,
regardless whether it was on or off already.
A. [5 marks]
In this question, you can assume a given function is_daylight_present() without
arguments. This function has access to an outdoor light sensor and returns true if the sensor
detects enough daylight and false otherwise.
Page 17 of 22
CS1101S
Smart_Room_With_Light.Inherits(Smart_Room);
Smart_Room_With_Light.prototype.first_user_enters =
function() {
// WRITE HERE
};
Smart_Room_With_Light.prototype.last_user_leaves =
function() {
// WRITE HERE
};
Page 18 of 22
CS1101S
B. [7 marks]
In this question, you should make use of a Timer class. Whenever a Timer object is created
with a given number of seconds t and a function f as arguments, the function f is called with
no arguments after t seconds.
Example:
var my_timer =
new Timer(10, function() { alert("belated hello"); });
// 10 seconds after this program is evaluated,
// an alert window will pop up with the message "belated hello"
You need to write a program to describe the behavior of a bathroom that is equipped with
ventilation. Instances of your Smart_Bathroom class should behave like
Smart_Room_With_Light objects, except:
(1) The constructor has an additional argument ventilation, which is an Appliance.
(2) After the first person enters the room, the room’s ventilation should be on.
(3) Ten seconds after the last person leaves the room, the room’s ventilation should
turn off, if no one is inside the room at that time.
In your solution, make best use of the class Smart_Room_With_Light described in Part
A of this question.
this.person_inside = false;
}
Smart_Bathroom.Inherits(Smart_Room_With_Light);
Smart_Bathroom.prototype.first_user_enters =
function() {
// WRITE HERE
Page 19 of 22
CS1101S
};
Smart_Bathroom.prototype.last_user_leaves =
function() {
// WRITE HERE
};
Page 20 of 22
CS1101S
Page 21 of 22
CS1101S
Page 22 of 22