CS302 2023 Final Exam -- Answers and grading



Question 3 - 20 Points

Part A

Start is 32 and size is 16, so the two recursive calls are going to be:

recursive_sort(v, tmp, 32, 8, 0);
recursive_sort(v, tmp, 40, 8, 0);

So the answers are 32, 8, 40, 8.

Part B

This will call:

recursive_sort(v, tmp, 4, 2, 0);
recursive_sort(v, tmp, 6, 2, 0);

Therefore, the vector will be:

93 49 31 15 26 71 10 59

Part C

The pivot is the median of 86, 54 and 34. The answer is 54. When I call quicksort, here is my input vector:
86 99 86 98 2 47 54 3 36 66 76 14 34

Part D

Here are the swaps:

74 88 88 80 28 74 15 99 74 74 74 88 28
    |  |  |     |       |  |  |     |
    |  |  |     |-------|  |  |     |
    |  |  |----------------|  |     |
    |  |----------------------|     |
    |-------------------------------|

So, the last element in the "low" set is 15, which gets swapped with the initial 74. Then, the recursive calls are start=0, size=6, and start=7, size=6.

Part E

The values are almost sorted, so insertion sort will sort them in O(n) time.

Grading

I turned the first three numbers for part B into your "key". So, for example, the above exam would have the key 934931.


Question 4 - 20 Points

Here are answers for the example:

Grading

For each problem it was 3 points for getting the algorithm correct, and 1 point if your running time matched your algorithm. You had to get the variables correct, and if you put anything but X for network flow, you got it wrong. I did some partial credit -- if you answered Dijkstra's algorithm instead of BFS, you got a point. If you answered MST instead of DFS, you got two points.

Please look in your exam for the correct answers and explanations -- they follow the question.


Question 5 - 8 Points

I'm going to break my answer down into four parts. Each of these was worth 2 points:
  1. Suppose you want to write a program or procedure that takes as its arguments the name of a file containing a program, and the name of a file that will be used as input to the program.
  2. The program/procedure returns "halt" if the program running on the input finishes in a finite amount of time. Otherwise, it returns "infinite loop."
  3. The program/procedure must run in a finit amount of time.
  4. It has been proved that it is impossible to write this program/procedure.
Here's an example of about the minimal answer that got full credit (this was a student's answer and that student got full credit):

Say you have a program that inputs a program and its inputs, and outputs if the program runs on an infinite loop or not, saying "halt" if it halts and "infinite loop" if it is indeed an infinite loop. The program would also have to return in a finite amount of time. Given these constraints, it is impossible to write this program.


Question 6 - 12 Points

Here's the answer for the example problem:

Starting
state
After first
iteration
After second
iteration
Distance to A 0 0 0
Distance to B - 13 13
Distance to C - - -
Distance to D - 57 53
Distance to E - 23 23
Distance to F - 34 33
Distance to G - - 25
Distance to H - 85 64
Back-edge to A - - -
Back-edge to B - A A
Back-edge to C - - -
Back-edge to D - A B
Back-edge to E - A A
Back-edge to F - A B
Back-edge to G - - B
Back-edge to H - A B
1st key on multimap 0 13 23
1st val on multimap A B E

Grading

It was 0.33 or 0.34 per answer. If the answer was numeric, you got half credit if your answer was off by one. I also realized that some students transposed the adjacency matrix, so if you did that, I didn't penalize you.

The key to your question is the value that was at the end of the question. It was a five-digit hash, like 96f46. Below, I show the answers for each of the problems, including when you transposed the adjacency matrix:

Hash 96f46:
             Distances                 Back-Links       Multimap: [Distance,Node]
   A   B   C   D   E   F   G   H     A B C D E F G H
   0   -   -   -   -   -   -   -     - - - - - - - -    [0,A]
   0  68  33  66  52   -   -  88     - A A A A - - A    [33,C][52,E][66,D][68,B][88,H]
   0  47  33  66  41 108   -  67     - C A A C C - C    [41,E][47,B][66,D][67,H][108,F]

If you transposed the adjacency matrix:

             Distances                 Back-Links       Multimap: [Distance,Node]
   A   B   C   D   E   F   G   H     A B C D E F G H
   0   -   -   -   -   -   -   -     - - - - - - - -    [0,A]
   0   -   -   -  91  20  23   4     - - - - A A A A    [4,H][20,F][23,G][91,E]
   0  99  38  84  28  20  23   4     - H H H H A A A    [20,F][23,G][28,E][38,C][84,D][99,B]
------------------------------------------------------------
Hash f2c6b:
             Distances                 Back-Links       Multimap: [Distance,Node]
   A   B   C   D   E   F   G   H     A B C D E F G H
   0   -   -   -   -   -   -   -     - - - - - - - -    [0,A]
   0   -  95  27  94  89   -  24     - - A A A A - A    [24,H][27,D][89,F][94,E][95,C]
   0  53  44  27  25  30   -  24     - H H A H H - A    [25,E][27,D][30,F][44,C][53,B]

If you transposed the adjacency matrix:

             Distances                 Back-Links       Multimap: [Distance,Node]
   A   B   C   D   E   F   G   H     A B C D E F G H
   0   -   -   -   -   -   -   -     - - - - - - - -    [0,A]
   0  18  70   5  89  81  20  89     - A A A A A A A    [5,D][18,B][20,G][70,C][81,F][89,E][89,H]
   0  15  70   5  49  81  20  78     - D A A D A A D    [15,B][20,G][49,E][70,C][78,H][81,F]
------------------------------------------------------------
Hash adcb1:
             Distances                 Back-Links       Multimap: [Distance,Node]
   A   B   C   D   E   F   G   H     A B C D E F G H
   0   -   -   -   -   -   -   -     - - - - - - - -    [0,A]
   0  85   -  49   -   6  31  73     - A - A - A A A    [6,F][31,G][49,D][73,H][85,B]
   0  81   -  19  30   6  31  36     - F - F F A A F    [19,D][30,E][31,G][36,H][81,B]

If you transposed the adjacency matrix:

             Distances                 Back-Links       Multimap: [Distance,Node]
   A   B   C   D   E   F   G   H     A B C D E F G H
   0   -   -   -   -   -   -   -     - - - - - - - -    [0,A]
   0  12  98   -   4  24  43   -     - A A - A A A -    [4,E][12,B][24,F][43,G][98,C]
   0  12  54  23   4  24  43  16     - A E E A A A E    [12,B][16,H][23,D][24,F][43,G][54,C]
------------------------------------------------------------
Hash 7be52:
             Distances                 Back-Links       Multimap: [Distance,Node]
   A   B   C   D   E   F   G   H     A B C D E F G H
   0   -   -   -   -   -   -   -     - - - - - - - -    [0,A]
   0  46  57   -  70  95   -  21     - A A - A A - A    [21,H][46,B][57,C][70,E][95,F]
   0  32  51  59  70  69   -  21     - H H H A H - A    [32,B][51,C][59,D][69,F][70,E]

If you transposed the adjacency matrix:

             Distances                 Back-Links       Multimap: [Distance,Node]
   A   B   C   D   E   F   G   H     A B C D E F G H
   0   -   -   -   -   -   -   -     - - - - - - - -    [0,A]
   0  64  99  39  89  82  86  73     - A A A A A A A    [39,D][64,B][73,H][82,F][86,G][89,E][99,C]
   0  64  85  39  89  44  67  73     - A D A A D D A    [44,F][64,B][67,G][73,H][85,C][89,E]
------------------------------------------------------------
Hash 9c6a9:
             Distances                 Back-Links       Multimap: [Distance,Node]
   A   B   C   D   E   F   G   H     A B C D E F G H
   0   -   -   -   -   -   -   -     - - - - - - - -    [0,A]
   0  28  99   -  94   -  49  56     - A A - A - A A    [28,B][49,G][56,H][94,E][99,C]
   0  28  69   -  38  52  49  40     - A B - B B A B    [38,E][40,H][49,G][52,F][69,C]

If you transposed the adjacency matrix:

             Distances                 Back-Links       Multimap: [Distance,Node]
   A   B   C   D   E   F   G   H     A B C D E F G H
   0   -   -   -   -   -   -   -     - - - - - - - -    [0,A]
   0  88   -  92  77  87  62   -     - A - A A A A -    [62,G][77,E][87,F][88,B][92,D]
   0  88 125  71  77  87  62 101     - A G G A A A G    [71,D][77,E][87,F][88,B][101,H][125,C]


Question 7 - 10 Points

This is for the example question:

Grading

3 points, 4 points, 3 points. At the end of your problem was a five digit hash.

For Part A, if you wrote SAAT, then I took off 0.1 points because you're not following the problem's directions.

For Part B, here were the answers:

6f763: SA BC FT
7961a: SA BC EF
cdf72: SA BC FT
e240b: SA BC FT
fd8ac: SA BC FT
Here was partial credit:
Points         Answer
   3           fd8ac-SASBFT
   3           cdf72-SABCSDFT
   3           7961a-SABCFT
   2           6f763-SACTFT
 1.5           fd8ac-SASBSD
 1.5           e240b-SASBSD
 1.5           e240b-SACT
 1.5           cdf72-SASBSD(192)
 1.5           cdf72-SASBSD
   1           fd8ac-TA,TC,TF
   1           fd8ac-DEBEBCACAT
   1           fd8ac-BC
   1           e240b-SASDBCBEFT
   1           e240b-SABABCCECFFT
   1           e240b-EBCBCA
   1           e240b-ATCTFT
   1           cdf72-ATCTFT
   1           cdf72-ASABCBCECFTF
   1           7961a-SAATSBBCCTSDDEEFFT
   1           6f763-ATCTFT
For Part C, here are the answers:
e240b: 375
cdf72: 172
6f763: 204
fd8ac: 203
7961a: 234
If you were off by 1, you got 2.5. If you were off by less than 10%, you got 1.


Question 8 - 10 Points

This is about as straightforward of a DFS as you can get:

void Graph::DFS(int node, int component)
{
  size_t i;

  if (C[node] != -1) return;
  C[node] = component;
 
  for (i = 0; i < Adj[node].size(); i++) {
    DFS(Adj[node][i], component);
  }
}

Pretty straightforward. I considered the question to be a gift, so it depressed me to see how many poor answers I received.


Question 9 - 10 Points

This is a pretty run-of-the-mill dynamic program:

long long DP::f(int x, int y)
{
  long long rv;

  if (x == A && y == B) return A+B;
  if (Cache[x][y] != -1) return Cache[x][y];
  rv = x*y;
  if (x < A) rv += f(x+1, y);
  if (y < B) rv += f(x, y+1);
  rv %= 1000000009;
  Cache[x][y] = rv;
  return rv;
}


Question 10 - 7 Points

For "step 3" you need to remove the recursion. Since the recursive calls are to higher numbers, you need to start at A and B and go down. You also need to initialize the cache here:

long long DP::g(int a, int b)
{
  size_t i;
  int x, y;
  long long rv;

  Cache.clear();
  Cache.resize(a+1);
  for (i = 0; i < Cache.size(); i++) Cache[i].resize(b+1, -1);
  for (x = a; x >= 0; x--) {
    for (y = b; y >= 0; y--) {
      if (x == a && y == b) {
        rv = a+b;
      } else {
        rv = x*y;
        if (x < a) rv += Cache[x+1][y];
        if (y < b) rv += Cache[x][y+1];
        rv %= 1000000007;
      }
      Cache[x][y] = rv;
    }
  }

  return Cache[0][0];
}


Question 11 - 3 Points

Here you make the realization that when you calculate the values for x, you only need to access row x+1 of the cache. You need to access all of the values for y. The code is the same as above, except for the following changed lines:

        if (x < a) rv += Cache[(x+1)%2][y];
        if (y < b) rv += Cache[x%2][y+1];
        rv %= 1000000007;
      }
      Cache[x%2][y] = rv;

Opposite from the DFS question, I was very happy to see how many really nice answers y'all gave for Question 9!