You are on page 1of 11

CS 300: ADVANCED PROGRAMMING

SPRING 2024

EXAM 1

Module: Haskell

Feb 18, 2024

1
Exam Guidelines
- The exam is due at 4:15 PM.
- We will enable LMS access to you at 4 PM, and you will have 15 minutes (until 4:15PM) to submit
your exam. If you finish your exam early, you will be allowed to leave, but you must return to submit
your exam. However, once you leave the lab, you can only return after 4:05 PM, so you will have 10
minutes to submit your files. Again, it is your responsibility to ensure the safety of your files. If your
system reboots or something unexpected happens, the course staff cannot help you.
- There are a total of 10 questions.

- We have provided you with Code.hs. You will write your code in it.
- Total marks of the exam are 85.
- Please note that the test cases may not cover all the cases for the questions. There may be other
(corner) cases which students have to figure out themselves.

- Plagiarism is strictly prohibited. Students are not allowed to discuss their solutions with others.
However, they may seek help from the course staff ONLY.
- Handwritten notes are allowed.
- We have provided you with the Prelude documentation so you can use built-in functions as you like.

- There will be NO partial marking for any of the questions. This is being done to be fair to all the
students in this course. However, the questions will be graded according to the number of test cases
that are passing. For example: if a 10 marks question has 10 test cases and 5 of them are passing for
a student, then they will get 5/10 for that question.
- You must submit the Code.hs only using the naming format: roll number.hs. For example, if your
roll number is 23100201 then your file name should be ‘23100201.hs’

- Good Luck!

2
Question 1: Kth Smallest Element in a BST (5 Marks)
Given a binary search tree, and an integer k, return the Kth smallest value
of all the values of the nodes in the tree. Assume that the input is always
valid.

K =2 , Output: 2
K = 4, Output: 4

Question 2: String Encode (5 Marks)


Given a string, encode it such that for each consecutive substring of characters
in the input, the function returns the character and count of the substring.
The string can contain alphabets, numbers or even special characters.
Note: an empty string input will return an empty string output. Also, upper
and lowercase alphabets are distinct (“Aa” would be encoded to “A1a1”).
Sample Input: String = ”aabbcc”
Output: ”a2b2c2”
Sample Input: ”xyxxzz”
Output: ”x1y1x2z2”

Question 3: List Rotation (5 Marks)


Given an integer, n, and a list, rotate the list n times where a positive inte-
ger would mean rotating the array to the right and a negative integer would
mean rotating it to the left.
Sample Input: list = [1,2,3,4,5,6,7,8], n = 3
Output: [6,7,8,1,2,3,4,5]
Sample Input: [1,2,3,4,5,6,7,8], n = -3

3
Output: [4,5,6,7,8,1,2,3]

Question 4: Implementing Typeclasses (5 Marks)


Implement the following typeclasses for the LinkedList.
• Functor
• Applicative
• Monad
In applicative, you are supposed to apply each function on the entire LinkedList
and concatenate the resulting LinkedLists. For instance:
ListNode (+1) (ListNode (+3) Null) <*> (ListNode 1 (ListNode 2 Null))
‘shouldBe‘ (ListNode 2 (ListNode 3 (ListNode 4 (ListNode 5 Null))))
In monad, apply function on each value of the LinkedList and concatenate
the results. For example:
ListNode 1 (ListNode 2 Null) >>= ( \x → ListN ode(x + 2)N ull))
shouldBe ListNode 3 (ListNode 4 Null)
Question 5: Palindromes from Pairs (7 Marks)
Given a list of unique strings, return all the palindromes in a list which are
formed by adding any two strings in the given list. The returned list must
be sorted alphabetically by the first character. If two strings have the same
first character, then write the smaller (in length) string first.
Sample Input: list = [”bat”,”tab”,”cat”]
Output: [”battab”,”tabbat”]

Question 6: Decoding Messages (7 Marks)


A message containing letters from A-Z can be encoded into numbers using
the following mapping:
“A” = “1”, “B” = “2” . . . . “Z” = “26”
To decode an encoded message, all the digits must be grouped then mapped
back into letters using the reverse of the mapping above (there may be mul-
tiple ways). For example, ”11106” can be mapped into:
”AAJF” with the grouping (1 1 10 6)
”KJF” with the grouping (11 10 6)
Note that the grouping (1 11 06) is invalid because ”06” cannot be mapped
into ’F’ since ”6” is different from ”06”.
Given a string s containing only digits, return the number of ways to decode

4
it.
Sample Input: string = “19”
Output: 2
Explanation: One way to decode this is ”AI” i.e, (1 9). Other is ”S” i.e,
(19).
Sample Input: string = “2021”
Output: 2
Explanation: One way to decode this is ”TBA” i.e (20 2 1). Other is ”TU”
i.e, (20 21).

Question 7: Insert Interval (10 Marks)


You are given an array of non-overlapping intervals where intervals[i] =
[start i, end i] represent the start and the end of the ith interval and inter-
vals are sorted in ascending order by start i. You are also given an interval
newInterval = [start, end] that represents the start and end of another inter-
val.
Insert newInterval into intervals such that intervals are still sorted in ascend-
ing order by start i and intervals still do not have any overlapping intervals.
You have to merge overlapping intervals, if necessary.
Return intervals after the insertion.
Sample Input: [ [1, 2] , [3, 6] ], newInterval = [7, 8]
Output: [ [1, 2] , [3, 6], [7, 8] ]
Sample Input: Array= [ [1, 3] , [6, 9] ], newInterval = [2, 5]
Output: [ [1, 5] , [6, 9] ]

Question 8: Next Permutation (10 Marks)


A permutation of an array of integers is an arrangement of its members into
a sequence or linear order. For example, for arr = [1,2,3], the following are
all the permutations of arr: [1,2,3], [1,3,2], [2, 1, 3], [2, 3, 1], [3,1,2], [3,2,1].
The next permutation of an array of integers is the next lexicographically
greater permutation of its integer. More formally, if all the permutations of
the array are sorted in one container according to their lexicographical order,
then the next permutation of that array is the permutation that follows it in
the sorted container. If such an arrangement is not possible, return the array
itself.
For example, the next permutation of arr = [1,2,3] is [1,3,2].

5
Similarly, the next permutation of arr = [2,3,1] is [3,1,2].
The next permutation of arr = [3, 2, 1] is [3, 2, 1].

Question 9: Saad’s Energy-Efficient Maze Journey (14 Marks)


In this maze-solving scenario, we have an NxM grid representing a maze with
various paths from the starting point at grid[0][0] to the final destination
at grid[n-1][m-1]. Our intrepid explorer, Saad, is ready to embark on this
journey, but he faces some unique challenges and opportunities.
Saad’s primary concern is his limited energy supply. To successfully reach the
destination, he must carefully manage his energy resources. Additionally, his
movement within the maze is restricted to either moving right or moving
down.
The grid contains two types of values:
• Non-negative values, which represent energy-draining obstacles. When
Saad encounters these, his energy decreases by the specified amount.
• Negative values, which are a source of excitement for Saad. These rep-
resent energy-boosting bonuses. Saad’s energy increases by the absolute
value of the negative number he encounters, but his energy level cannot
exceed his initial supply.
Saad’s ultimate goal is to reach the destination while maximizing the energy
he has left. The success of his journey also depends on the number stored at
grid[n-1][m-1], which must ensure that he remains alive - after dealing with
the number based on its type- upon reaching the endpoint.
However, if Saad encounters insurmountable challenges and cannot reach the
destination with his current energy, he seeks a second chance. Huzaifa, known
for his strict rules, places Saad’s fate back into the hands of luck. In this twist,
the grid undergoes a transformation: the first column and the last row are
removed. Saad restarts his journey from the new starting point, armed once
again with his initial energy supply.
You can assume that initial energy supply is always non-negative and even-
tually, Saad will be able to reach the destination.
We want you to guide Saad safely to his destination while maximizing his
remaining energy.

6
Example 1:

Explanation: The path that Saad takes is 5, -5, 2, 3, 4, 1. Energy trend


is as follows:
• At 5, energy decreases by 5 and updated energy is 10.
• At -5 (bonus), energy increases by 5 and updated energy is 15.
• At 2, energy decreases by 2 and updated energy is 13.
• At 3, energy decreases by 3 and updated energy is 10.
• At 4, energy decreases by 4 and updated energy is 6.
• At 1, energy decreases by 1 and updated energy is 5.
Please note that when Saad goes from -5 to -10, his energy remains the same
because his energy can’t be greater than the initial supply (15). That is why
bonus of 10 is useless for him.
Example 2:
(1) It is not possible for Saad to reach the destination as his energy dies out.
Note that when Saad goes from position [0][0] to [1][0], he dies and can’t
proceed any further - even though there is a bonus ahead- so he has to
look for a different path.
(2) Saad is out of luck again! Please note that Saad does reach the destination
but he doesn’t stay alive after dealing with the number at the destination.
(3) This time Saad reaches the destination. His energy after reaching the
destination is (7 - 2 - 2 = 3).

7
Question 10: Blasts and Fire (17 Marks)
Imagine setting a tree on fire and letting the flames spread until the tree
completely vanishes. We explored this scenario and discovered it’s relatively
straightforward to predict when a tree will disappear after igniting a fire on
one of its nodes. What intrigued us more was considering a LinkedList of
Trees. Yes, you read that correctly—a LinkedList containing Trees. The
fire starts from the longest leaf in one of these trees, based on a given index
indicating from which tree the fire begins. You can assume that there is only
one longest leaf. The index starts at 0, with 0 referring to the first tree in
the LinkedList. You can assume the index will always be valid.
After each time unit, a node’s value decreases by one, and the fire spreads
to its neighboring nodes (either parent and/or children). A node and all its
descendants are destroyed when its value drops to 0. All node values are
non-negative.
Once the longest leaf and the root of a tree catch fire, the flames will spread
to the root of the adjacent tree(s) after one time unit. For example, if the
longest leaf and root of the tree at index 2 catch fire, after one time unit, the
fire will spread to the roots of the trees at indexes 1 and 3, assuming there’s
a tree at index 3. The fire will then spread to the root of the tree at index 0

8
after a one-unit delay once the longest leaf and the root of the tree at index
1 catch fire.
Here are some of the guidelines:
• When deciding between the spread of fire and the effects of an explosion,
prioritize the fire spread. For instance, if a tree yet to catch fire is exposed
to fire from one side and an explosion from another, the fire will take
precedence. As a result, the unaffected tree will catch fire and then
immediately suffer the explosion’s effects, halving all its values (both of
these events happen simultaneously, but we prioritize fire spread).
• Similarly, when choosing between reducing a node’s value due to fire and
the effects of an explosion, reduce the value first. For example, if a tree’s
root is on fire with a value of 8 and its neighbor explodes, first reduce the
value to 7, then apply the explosion effect, halving it to 3.5, and apply
floor rounding after the division, so the final value becomes 3..
• If explosions occur from both neighbors simultaneously, divide the values
by 4.
• If an explosion triggers a chain reaction of explosions across neighboring
trees, these should occur simultaneously. For instance, if the tree at index
0 causes an explosion, leading to another at index 1, and then to another
at index 2, all explosions should be considered to happen at the same
moment.
Your task is to determine the time at which the entire LinkedList has com-
pletely vanished.
Consider an example where a LinkedList contains four trees, and a fire starts
from the longest leaf (node with a value of 19) of the tree at index 2.

9
After 4 time units, the fire spreads to the neighboring trees at indexes 1 and
3. The list is updated accordingly.

Then, 3 time units later, the fire reaches the tree at index 0. This occurs 1
time unit after the longest leaf of the tree at index 1 catches fire, requiring 2
time units for the fire to travel from the root to the longest leaf. The list is
updated again to reflect this situation.

After an additional 2 time units, the value of the root node at index 1 drops
to zero, causing a blast.

Consequently, all the values of the nodes in the tree at index 0 and at index
2 are halved. Because we don’t have any tree at index 1, trees - in the above

10
tree - at indexes 0 and 2 will become neighbors. Therefore, 9 (4+3+2) time
units after the fire starts in the LinkedList, the state of the LinkedList is as
follows.

Furthermore, 1 time unit later, the value of the root node of the tree at index
1 falls to 0, resulting in another blast.

Again, trees - in the above tree - at indexes 0 and 2 will become neighbors.

Subsequently, 1 time unit after that, the values of the root nodes of both of
these trees become zero.
Thus, the entire LinkedList vanishes after a total of 11 time units.

11

You might also like