Vous êtes sur la page 1sur 7

ECE 190 Final Exam Day One

Spring 2013
6th May, 2013

All your answers will be submitted electronically


This is a closed book exam.
You may not use a calculator.
You are allowed one handwritten 8.5 x 11" sheet of notes.
Absolutely no interaction between students is allowed.
All problems are worth 25 points but they are not equally difficult
Read problem statements carefully and dont panic!

Problem
number

Max

25

25

25

25

Total

100

Score

Checked by

Instructions for accessing/working on the programming problems


Log into an EWS Linux machine.

Appendixes A and D from the textbook are provided for you on the desktop.

Open a terminal window. Check if directory exam3 exists.

Write your code in the files indicated by the problem statements. Do not rename the files. We
will not grade your problem if it is not saved as required.

We are NOT using a subversion repository for the exam. We will grade the saved files that you
leave in your exam3 directory.

Your code will be at least partly graded by an autograder. You may receive zero points if your
code does not assemble, does not compile, or does not behave as specified.

To begin work on problem X, use the cd command to get to the problemX directory.

To edit the file, type gedit givenfilename &


(Replace givenfilename with the name of the file where you will add your code.)

Save your work.

LC-3 Tools reference information


To assemble your code and produce the object file, type lc3as givenfilename.asm

To run the LC-3 graphical simulator, type lc3sim-tk givenfilename.obj

To run the LC-3 command-line simulator, type lc3sim givenfilename.obj

C Tools reference information


We will use clang compiler when grading your solutions.

To compile your code using clang compiler, type clang -Wall <c file name>

To compile your code using gcc compiler, type gcc -Wall <c file name>

To execute your code, type ./a.out

Problem 1. Detect cycles in a Linked List


Implement the has_cycle function which detects whether or not a linked list contains a cycle. A linked list
with a cycle is a list which contains a sequence of nodes such that one of the nodes in the sequence
points to a previous node in the sequence. For example, the linked list below contains a cycle:
17

13

11

17

Use the following algorithm to solve this problem:


1. Initialize two pointers (tortoise and hare) to point to the head of the list.
2. Advance the tortoise pointer by one step in the list and advance the hare pointer by two steps.
3. If the two pointers are non-null and equal, there is a cycle.
4. Repeat steps 2 and 3 until either pointer is null, in which case there is no cycle.
The following type definition for the nodes in the linked list and function prototype are given in the
problem1/tortoise-hare.h file.
typedef struct node_t {
int data;
struct node_t *next;
} node_t;
int has_cycle(node_t *head);

Implement the has_cycle function in problem1/main.c


has_cycle() should return a 1 if there is a cycle or a 0 if there is no cycle
Just because two nodes have the same data, this does not necessarily mean they are the same
node. Nodes are equal if the actual values of their pointers are the same.
If you change the main() function to create new test cases, make sure to restore to its original.
Do not edit tortoise-hare.h.
Compile: clang Wall main.c o main

Problem 2. C to LC-3 Assembly Conversion: Linked List Rotation


Convert the given C function to an LC-3 subroutine. The function circularly left-rotates a linked list by n
positions. An example of the function's operation for n = 2 is given below.
Input:

HEAD

NULL

HEAD

NULL

Output:

int rotate_list(node_t **head, int n)


{
node_t *current;
if (n == 0 || head == NULL || *head == NULL) {
return 1;
}
current = *head;
while (current->next!=NULL) {
current = current->next;
}
current->next = *head;
while (n > 0) {
n = n-1;
current = current->next;
}
*head = current->next;
current->next = NULL;
return 0;
}

The source code for the function is shown to the


left and the definition of the node_t type is
shown below.
typedef struct node_t {
int data;
struct node_t *next;
} node_t;

Recall that structures merely consist of simple


data types where one element always comes
after another in memory. That is if head points
to an address of x2000, the data value is
contained in x2000 and the next pointer address
is contained within x2001.
Your program should be saved in the
problem2/left-rotation.asm file. The file already
contains an LC-3 assembly implementation of
MAIN that calls the ROTATE_LIST subroutine.
You should not modify the MAIN routine.

data.asm file is provided for convenient testing. It contains a short hard-coded linked list consisting of 6
nodes. As you can see from MAINs implementation, lists head node is stored starting at address x2000.
To receive full credit, your program should correctly run in lc3sim (or lc3sim-tk) and should produce the
correct output. Your subroutine should expect the parameter head to be passed in R0, expect the
parameter n to be passed in R1, and should place the return value in R0. Your subroutine should save
and restore the registers using the callee-save convention. You may not make any assumptions about the
behavior or structure of MAIN beyond the parameter passing explained above.
To test your ROTATE_LIST subroutine using the provided MAIN and data.asm, assemble both leftrotation.asm and data.asm, load them in the lc3 simulator, set PC to x3000, and run it. You can inspect
the list at x2000 and the head pointer at label HEAD to see if the correct changes are made.
Your code will be graded by an autograder for functionality of the ROTATE_LIST subroutine. You may
receive zero points if your code does not assemble or does not behave as specified.

Problem 3. Foldable Tree


A binary tree is foldable if its left and right subtrees are exact mirror reflections of each other. An empty
tree is considered as foldable. For example, the tree on the left is foldable and the one on the right is
not. Write a C function checkFoldable to check whether a given binary tree is foldable or not. It should
return 1 if the tree is foldable and return 0 otherwise. The function prototype and the struct node of the
tree are as follows. This function will be called with pointers to the left and the right children of the root.
int checkFoldable(node* left, node* right);
struct node {
int data;
struct node* left;
struct node* right;
};

10

10

15

22

15

15

36

36

22

36

15

22

22

Use this recursive algorithm for implementing checkFoldable(n1,n2)


Base cases:
o Return 1 if both n1 and n2 are null.
o Return 0 if one of them is null and the other is not.
Recursive step:
o If the data of n1 matches the data of n2 then return
checkFoldable(n1->left,n2->right) AND checkFoldable(n1->right,n2->left))
o Else return 0.
The file problem3/foldable.c has a main() function that builds a binary tree and calls checkFoldable.
If you change main() to test your code on other trees, make sure to restore it to its original.
Of course, your implementation should work for any binary tree.
Compile: clang Wall foldable.c o foldable

Problem 4. MicroSudoku
In MicroSudoku a 4x4 matrix is given with some empty cells and some cells with numbers in the set S={1,
2, 3, 4}. The player has to find numbers to fill the empty cells so that the following check conditions hold
(a) each number in S appears in every row, every column, and each of the four 2x2 sub-matrices, and (b)
none of the numbers repeat (in a row, column, or a submatrix). The figures below show an initial matrix,
the submatrices in bold lines, a solution for the initial matrix, and another matrix which has no solution.

4
1
Initial matrix A

Solution matrix for A

4
4
1

Initial unsolvable matrix B

You are given a function check() that checks the above conditions on a given board. Using this,
implement a recursive function solve(board) for solving MicroSudoku. The recursive algorithm for
solve(board) is as follows:
For every empty cell (i,j) in board
For each value v in S, assign v to board[i][j] . This gives rise to a new board.
Call solve on the new board.
If solve returns success (1) then return 1
If none of the numbers in S when assigned to board[i][j] pass the check, then make it an empty
cell again by resetting board[i][j] to 0 and return. (This will cause the algorithm to backtrack and
change the assignments to an earlier cell.)
If none of the cells are empty and the check() succeeds then return 1 else return 0.

Several initial matrices (or boards) are given as text files in the problem4/boards/. In addition
the following functions are given in problem4/main.c and you should not modify them:
load(board): Loads the 4x4 array called board[4][4] with the numbers from the specified
board text file which is passed as an argument to the main(). A zero (0) is loaded in the array for
empty cells.
print(board): Prints the board specified by board[4][4]. For an empty cell, it prints a dot.
check(board): Returns 1 if board is a solution of MicroSudoku, otherwise it returns 0 (e.g., if any
of the checks fail and/or the board is not filled). So, this function implements all the checks
stated above.
main(): This function loads the appropriate board, prints it, calls the solve function which you
will implement, and prints the result.
Compile: clang Wall main.c o main
Run: ./main boards/1.txt

Vous aimerez peut-être aussi