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

CSCI 2122 Assignment 3

Due date: 11:59pm, Friday, March 8, 2024, submitted via git

Objectives
The purpose of this assignment is to practice your coding in C, focusing on linked list manipulation and
encapsulation as well as using the module that you create.

This assignment is divided into two problems. In the first problem, you will extend a linked list implemen-
tation by adding an overlap() and a splice() functions, allowing the merging of two lists into one.
In the second problem you will use the list implementation to solve a problem.

Preparation:
1. Complete Assignment 0 or ensure that the tools you would need to complete it are installed.
2. Clone your assignment repository:
https://git.cs.dal.ca/courses/2024-winter/csci-2122/assignment-3/????.git
where ???? is your CSID. Please see instructions in Assignment 0 and the tutorials on Brightspace if
you are not sure how.
Inside the repository there are two directories: linkedlist and splicer, where code is to be written.
You should set up a separate CLion project for each of these directories, like the labs. Inside each directory
is a tests directory that contains tests that will be executed each time you submit your code. Please do
not modify the tests directory or the .gitlab-ci.yml file that is found in the root directory. Mod-
ifying these files may break the tests. These files will be replaced with originals when the assignments are
graded. You are provided with sample Makefile files that can be used to build your program. If you
are using CLion, a Makefile will be generated from the CMakeLists.txt file generated by CLion.

Background: Splicing Lists


A splice operation takes two over-
lapping lists, L1 and L2, and com-
bines into a single list that shares
the common overlap. The overlap of lists L1, and L2
is (i) the maximum number of elements O such that
the last O elements of L1 are the same as the first
O elements of L2, or (ii) the number of elements of
L2 if L2 is a sublist of L1. For example, in Figure 1,
the last three elements of list L1 are the same as the
first three elements of list L2. A splice of the two
lists results in the concatenation of L1 with L2, with
the removal of the duplicate overlap. The order of
the lists is important: List L1 must precede L2. The
result of splice(L2,L1) is a list containing all the ele-
ments of L2 followed by all the elements of L1, be- Figure 1: Splice of two lists
cause the first elements of L1 do not overlap with the last elements
of L2. If L2 is a sublist of L1, then splice(L1,L2) is L1 because, L2 fits into L1. However, splice(L2,L1) is a concat-
enation of L2 and L1 because the second list cannot precede the first. In the cases above, splice(L1,L2) has
an overlap of 3 elements, but splice(L2,L1) has an overlap of 0 elements.
Function Pointers
The C programming language has a feature called function pointers that allows a programmer to store the
address of a function in their program and then call that function. For example, the following function
takes a pointer to a function as a parameter and then calls this function.
int do_operation(int a, int b, int (*operation)(int,int)) {

int result = operation(a, b);

}
In the above example, the function do_operation() takes three parameters: two integers (a and b) and a
pointer to a function (operation). The pointer will point to a function that takes two integers and returns
an integer. The type declaration of a function pointer is slightly convoluted, but the important features
are (i) the return type (int) of the function being pointed to, the parameter name (operation), and the
types of parameters passed to the function (int, int) that is being pointed to. The function call looks like
a regular function call. Below is an example of how to pass a function pointer:
static int add(int a, int b) {
return a + b;
}

int main() {

int result = do_operation(13, 24, &add);

}

Problem 1: Match and Splice


In the linkedlist directory, in linkedlist.c implement the match() and splice() functions
prototyped in linkedlist.h. The description of the functions is given below. A test program
(main.c ) is provided to test your code. Note: Please do NOT modify linkedlist.h or main.c. The
test program is similar to Lab 4 and 5. It reads in a series of commands and applies them to lists.
Required Functions
unsigned int ll_overlap(linked_list_t *list1, linked_list_t *list2,
int (*compare)(void *,void*))
Computes the maximum overlap between list1 and list2. The third argument, compare, is a
pointer to the function that is used to determine if items stored in the list. The function returns
a nonnegative integer denoting the overlap. The compare function pointer points to the function
used to compare the contents of two nodes in the list. This function returns 0 if the contents is
the same and a non-zero value otherwise. For example, the code
int result = compare(node1->data, node2->data);
compares the data of nodes pointed to by node1 and node2, and sets result to 0 if the two nodes
contain equivalent data. See main.c of this problem for an example of a compare() function.

void ll_splice(linked_list_t *list1, linked_list_t *list2,


unsigned int overlap)
Splices list2 into list1, according to the specified overlap. It is assumed that the overlap is accurate,
and does not need to be verified. After this function returns, the list pointed to list1 contains all
the nodes of the spliced list, and the list pointed to by list2 contains all nodes in the overlap.
Test Program Input:
All input is done from stdin. The program reads an integer, followed by a series of commands. The integer
specifies how many lists will be manipulated. Each command begins with the list L where L specifies
the list to be created, destroyed, or modified. The following commands (see example below) are used but
more are provided:
• list <L> new : create a new empty list and use it as list L.
• list <L> destroy : destroy list L.
• list <L> build <W> <word1> <word2> … <wordW>: stores the W words in list L.
• list <L1> overlap <L2> : Computes and stores the overlap between list L1 and list L2.
• list <L1> splice <L2> : Splices list L2 on to list L1.
• list <L> print : display list L.
• Other commands are available. See the code in main.c

Example
Input Output
2 List 0: new list
list 0 new [ ] (0 items)
list 1 new List 1: new list
list 0 build 5 ali ben gem dan eve [ ] (0 items)
list 1 build 5 gem dan eve ali ben List 0: build
list 0 overlap 1 [ ali ben gem dan eve ] (5 items)
list 0 splice 1 List 1: build
list 1 print [ gem dan eve ali ben ] (5 items)
end List 0: Overlap between lists 0 and 1 is 3
List 0: List 1 spliced to the end of list 0
[ ali ben gem dan eve ali ben ] (7 items)
List 1: print
[ gem dan eve ] (3 items)

Test Program Processing


For each command perform the corresponding operation on the list and print out the resulting list.
Test Program Output
All output should be to stdout. For each command, program will print out the result of the operation,
followed by the contents of the list.

Problem 2: The Splicer


Your company has been hired to write software to reassemble pieces of texts found
at archeological digs. Researchers have amassed sections of ancient text from var-
ious sources that they believe to belong to the same document. Your company
needs to develop software that will take these sections of text and reassemble them
into a single document. Your boss has asked you to write a program that reads in zero or more segments
of text and reassembles them. Given the size of the text, you are not allowed to use arrays.
Input
The input consists of one or more segments of text, where each segments consist of one or more words.
Words can be separated by one or more whitespaces. Whitespaces consist of regular spaces, tabs, new-
lines, etc. Hint: scanf() will naturally ignore white space, so use scanf() to read in one word at a
time. Each segment will be terminated by the word “EOS”. The last segment in the text will only have
the terminator word. (See example.)
Processing
Your program should read in the segments and store each segment as a list of words. The set of segments
should be stored in a list L. To assemble the text:
• Remove the first segment T from the list L
• While L is not empty
o Find a segment S from list L such that either overlap(S,T) or overlap(T,S) is maximal. (In the
latter case swap S and T.
o Splice(T,S)
• Output T
Your program should NOT use arrays.
Output
Output the text, separating words by single spaces. Start a new line of text (output a new-line after the
current word) if there are more than 30 characters in the current line. The last line should also be termi-
nated with a new-line. (See example.)

Example
Input Output
Lorem ipsum dolor sit amet, consectetur Lorem ipsum dolor sit amet, consectetur
adipiscing elit. EOS adipiscing elit. Pellentesque sed
Pellentesque sed dolor non arcu imperdiet dolor non arcu imperdiet placerat.
placerat. EOS
dolor sit amet, consectetur adipiscing
elit. Pellentesque sed dolor non EOS
EOS

Hints and Suggestions


• Lab 5 will be very helpful for doing Assignment 3.
• The problems should be done in order.
• The sample solution is about 60 lines of code for problem 1 and 100 lines of code for problem 2. You
may create as much code as needed.
• Do NOT use arrays.
• The library functions I found most useful are: scanf(), printf(), strdup(), and strcmp().
• Be sure to free memory correctly. Part of the quality of solution is good memory management.

Assignment Submission
Submission and testing are done using Git, Gitlab, and Gitlab CI/CD. You can submit as many times as you
wish, up to the deadline. Every time a submission occurs, functional tests are executed, and you can view
the results of the tests. To submit use the same procedure as Assignment 0.
Grading
If your program does not compile, it is considered non-functional and of extremely poor quality, mean-
ing you will receive 0 for the solution.

The assignment will be graded based on three criteria:

Functionality: “Does it work according to specifications?”. This is determined in an automated fashion by


running your program on several inputs and ensuring that the outputs match the expected outputs. The
score is determined based on the number of tests that your program passes. So, if your program passes
t/T tests, you will receive that proportion of the marks.

Quality of Solution: “Is it a good solution?” This considers whether the approach and algorithm in your
solution is correct. This is determined by visual inspection of the code. It is possible to get a good grade
on this part even if you have bugs that cause your code to fail some of the tests.

Code Clarity: “Is it well written?” This considers whether the solution is properly formatted, well docu-
mented, and follows coding style guidelines. A single overall mark will be assigned for clarity. Please see
the Style Guide in the Assignment section of the course in Brightspace.

The following grading scheme will be used:


Task 100% 80% 60% 40% 20% 0%
Functionality
Equal to the number of tests passed.
(20 marks)
overlap() and splice() overlap() and overlap() is im- Flaws in both An attempt
Solution Quality
are implemented cor- splice() are im- plemented cor- overlap() and has been
Problem 1
rectly. splice() is im- plemented cor- rectly splice() have made.
(10 marks)

code does not compile


No code submitted or
plemented efficiently. rectly. bugs.
Implemented cor- Implemented Link lists used Linked lists used An attempt
Solution Quality
rectly, efficiently, and correctly. but there is a but, major flaws has been
Problem 2
proper memory man- bug or two in in implementa- made
(10 marks)
agement done. implementation tion
Code Clarity Code looks profes- Code looks Code is mostly Code is hard to Code is not
(10 marks) sional and follows all good and readable and read and fol- legible
Indentation, for- style guidelines mostly follows mostly follows lows few of the
matting, naming, style guidelines. some of the style guidelines
comments style guidelines
Assignment Testing without Submission
Testing via submission can take some time, especially if the server is loaded. You can run the tests without
submitting your code by using the provided runtests.sh script. Running the script with no arguments
will run all the tests. Running the script with the test number, i.e., 00, 01, 02, 03, … 09, will run that specific
test. Please see below for how run the script.
Get your program ready to run
If you are developing directly on the unix server,
1. SSH into the remote server and be sure you are in the marsdec1 or marsdecx directory.
2. Be sure the program is compiled by running make.

If you are using CLion


1. Run your program on the remote server as described in the CLion tutorials.
2. Open a remote host terminal via Tools → Open Remote Host Terminal

If you are using VSCode


1. Run your program on the remote server as described in VSCode tutorials.
2. Click on the Terminal pane in the bottom half of the window or via Terminal → New Terminal
Run the script
3. Run the script in the terminal by using the command:
./runtest.sh
to run all the tests, or specify the test number to run a specific test, e.g. :
./runtest.sh 07

You will see the test run in the terminal window.

You might also like