The goal of this homework assignment is to allow you to explore building sets using a dynamic array, a linked list, and a bitset and then utilizing this abstract data type to solve the infamous palindromic permutation programming challenge.

In high-level languages such as Python, we have a built-in implementation of sets which support a variety of methods:

``````# Define a set
>>> s = set([5, 7, 4])
>>> s
{4, 5, 7}

# Add values to set
>>> s.add(0)
>>> s.add(1)
>>> s
{0, 1, 4, 5, 7}

# Check if set contains value
>>> 4 in s
True
>>> 0 in s
True
>>> 7 in s
True
>>> 9 in s
False

# Remove values from set
>>> s.remove(4)
>>> s.remove(7)
>>> s
{0, 1, 5}
``````

Because C does not have any builtin implementations of a set, you are to implement three different versions:

1. `ArraySet`: This uses a dynamic array and binary search internally to implement the set.

2. `ListSet`: This uses a linked list, linear search, and recursion internally to implement the set.

3. `BitSet`: This uses a bitset with bit operations internally to implement the set.

For this assignment, you are to do your work in the `homework05` folder of your assignments GitHub repository and push your work by noon Wednesday, September 27.

## Activity 0: Preparation¶

Before starting this homework assignment, you should first perform a ```git pull``` to retrieve any changes in your remote GitHub repository:

``````\$ cd path/to/repository                   # Go to assignments repository

\$ git switch master                       # Make sure we are in master branch

\$ git pull --rebase                       # Get any remote changes not present locally
``````

Next, create a new branch for this assignment:

``````\$ git checkout -b homework05              # Create homework05 branch and check it out
``````

### Task 1: Skeleton Code¶

To help you get started, the instructor has provided you with the following skeleton code:

``````# Go to assignments repository
\$ cd path/to/assignments/repository

# -----------------------------------------------------
# MAKE SURE YOU ARE NOT INSIDE THE homework05 DIRECTORY
# -----------------------------------------------------
# MAKE SURE YOU ARE AT THE TOP-LEVEL DIRECTORY
# -----------------------------------------------------

# Download skeleton code tarball
\$ curl -LO https://www3.nd.edu/~pbui/teaching/cse.20312.fa23/static/tar/homework05.tar.gz

# Extract skeleton code tarball
\$ tar xzvf homework05.tar.gz
``````

Once downloaded and extracted, you should see the following files in your `homework05` directory:

``````homework05
\_ Makefile                 # This is the Makefile for building all the project artifacts
\_ bin                      # This contains the project binary executables and test scripts
\_ benchmark.py         # This is the Python script for benchmarking the palindromic program
\_ test_arrayset.sh     # This is the shell script for testing the ArraySet library
\_ test_bitset.sh       # This is the shell script for testing the BitSet library
\_ test_listset.sh      # This is the shell script for testing the ListSet library
\_ test_palindromic.sh  # This is the shell script for testing the palindromic program
\_ include                  # This contains the project header files
\_ ds                   # This contains the project data structure header files
\_ arrayset.h       # This is the C header file for the ArraySet library
\_ bitset.h         # This is the C header file for the BitSet library
\_ listset.h        # This is the C header file for the ListSet library
\_ lib                      # This contains the project library files
\_ src                      # This contains the project source code
\_ arrayset.c           # This is the C source code for the ArraySet library
\_ bitset.c             # This is the C source code for the BitSet library
\_ listset.c            # This is the C source code for the ListSet library
\_ palindromic.c        # This is the C source code for the palindromic program
\_ tests                    # This contains the project unit tests
\_ unit_arrayset.c      # This is the unit test for the ArraySet library
\_ unit_bitset.c        # This is the unit test for the BitSet library
\_ unit_listset.c       # This is the unit test for the ListSet library
``````

### Task 2: Initial Import¶

Now that the files are extracted into the `homework05` folder, you can commit them to your git repository:

``````# Go into homework05 folder
\$ cd homework05

# Add and commit initial skeleton files
\$ git add Makefile                            # Mark changes for commit
\$ git add bin/*.sh bin/*.py                   # Mark changes for commit
\$ git add include/ds/*.h                      # Mark changes for commit
\$ git add lib/.gitkeep                        # Mark changes for commit
\$ git add src/*.c                             # Mark changes for commit
\$ git add tests/*.c tests/*.input             # Mark changes for commit
\$ git commit -m "Homework 05: Initial Import" # Record changes
``````

The details on what you need to implement are described in the following sections.

### Task 3: `Makefile`¶

The Makefile contains all the rules or recipes for building the project artifacts (e.g. `palindromic`, `libds.a`, `unit_arrayset`, `unit_bitset`, `unit_listset`, etc.):

``````CC=       gcc
CFLAGS=   -Wall -std=gnu99 -g -Iinclude
AR=       ar
ARFLAGS=  rcs
LD=       gcc
LDFLAGS=  -Llib

all:      bin/palindromic

test:
@\$(MAKE) -sk test-all

test-all: test-arrayset test-listset test-bitset test-palindromic

# TODO: Pattern rule for object files

# TODO: Rule for lib/libds.a

# TODO: Rule for bin/palindromic

bin/unit_arrayset:  tests/unit_arrayset.o lib/libds.a
\$(LD) \$(LDFLAGS) -o \$@ \$^

bin/unit_listset:   tests/unit_listset.o lib/libds.a
\$(LD) \$(LDFLAGS) -o \$@ \$^

bin/unit_bitset:    tests/unit_bitset.o lib/libds.a
\$(LD) \$(LDFLAGS) -o \$@ \$^

test-arrayset:      bin/unit_arrayset
bin/test_arrayset.sh

test-listset:       bin/unit_listset
bin/test_listset.sh

test-bitset:        bin/unit_bitset
bin/test_bitset.sh

test-palindromic:   bin/palindromic
bin/test_palindromic.sh

clean:
rm -f bin/unit_* bin/palindromic lib/*.a src/*.o tests/*.o
``````

For this task, you will need to add rules for building the static library `lib/libds.a` and the program `bin/palindromic`. Be sure to have a recipe for any intermediate object files that libraries require as shown in the DAG below:

#### Makefile Variables¶

You must use the `CC`, `CFLAGS`, `LD`, `LDFLAGS`, `AR`, and `ARFLAGS` variables when appropriate in your rules. You should also consider using automatic variables such as `\$@` and `\$<` as well.

Once you have a working `Makefile`, you should be able to run the following commands:

``````# Build all TARGETS
\$ make
gcc -Wall -std=gnu99 -g -Iinclude -c -o src/palindromic.o src/palindromic.c
gcc -Wall -std=gnu99 -g -Iinclude -c -o src/arrayset.o src/arrayset.c
gcc -Wall -std=gnu99 -g -Iinclude -c -o src/listset.o src/listset.c
gcc -Wall -std=gnu99 -g -Iinclude -c -o src/bitset.o src/bitset.c
ar rcs lib/libds.a src/arrayset.o src/listset.o src/bitset.o
gcc -Llib -o bin/palindromic src/palindromic.o lib/libds.a

# Run all tests
\$ make test
Testing arrayset...
...

# Remove generated artifacts
\$ make clean
rm -f bin/unit_* bin/palindromic lib/*.a src/*.o tests/*.o
``````

Note: The tests will fail if you haven't implemented `ArraySet`, `Bitset`, or `ListSet` libraries, or the `palindromic` program.

#### Warnings¶

You must include the `-Wall` flag in your `CFLAGS` when you compile. This also means that your code must compile without any warnings, otherwise points will be deducted.

After completing the `Makefile` and verifying that you can produce all the specified artifacts, you may begin implementing the [data structure]s and applications for this assignment.

## Activity 1: ArraySet Library (2 Points)¶

For the first activity, you are to complete the `ArraySet` library, which implements a set using an ordered dynamic array. That is, to maintain a unique collection of values, you will store values in the internal dynamic array in ascending order. This will allow you to perform binary search to check if a value is already in the `ArraySet`.

As can be seen above, the `ArraySet` is an ordered dynamic array. This means that you will need to resize the internal `data` array to make room for new values if the `size` reaches the internal `capacity` and shift the values in the internal `data` array.

### Task 1: `include/ds/arrayset.h`¶

The `include/ds/arrayset.h` file is the header file for the `ArraySet` structure, which contains the following structs and function prototypes:

``````/* arrayset.h: Set (Dynamic Array) */

#pragma once

#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

/* Constants */

#define ARRAYSET_DEFAULT_CAPACITY (1<<2)

/* Structures */

typedef struct {
int64_t *data;      // Internal array
size_t   capacity;  // Total number of elements
size_t   size;      // Number of valid elements
} ArraySet;

/* Functions */

ArraySet *  arrayset_create();
void        arrayset_delete(ArraySet *as);

bool        arrayset_contains(ArraySet *as, int64_t value);
void        arrayset_add(ArraySet *as, int64_t value);
void        arrayset_remove(ArraySet *as, int64_t value);
``````

Other programs will `#include` this file in order to use the functions we will be implementing in this library.

Note: For this task, you do not need to modify this file. Instead, you should review it and ensure you understand the provided code.

### Task 2: `src/arrayset.c`¶

The `src/arrayset.c` file contains the C implementation for the `ArraySet` structure. For this task, you will need to implement the following functions:

1. `ArraySet* arrayset_create()`

This function allocates a new `ArraySet` struct and initializes its internal attributes: `data`, `capacity`, and `size`.

Hint: Use malloc or calloc to allocate data on the heap.

2. `void arrayset_delete(ArraySet *as)`

This function deallocates the given `ArraySet` struct along with its internal `data` array.

Hint: Use free to release data allocated on the heap.

3. `bool arrayset_contains(ArraySet *as, int64_t value)`

This function returns `true` if the `value` is in the `ArraySet`, otherwise it returns `false`.

Hint: Use binary search to locate the `value`.

4. `void arrayset_add(ArraySet *as, int64_t value)`

This function adds the `value` to the `ArraySet` while maintaining both uniqueness (ie. two values are the same) and ordering (ie. values are in ascending order).

Hint: Use `arrayset_contains`, determine the `index` where you want to place the new `value`, and then adapt `array_insert` from Lecture 07.

5. `void arrayset_remove(ArraySet *as, int64_t value)`

This function removes the `value` from the `ArraySet`.

Hint: Use `arrayset_contains`, determine the `index` of the `value` you want to remove, and then adapt `array_pop` from Homework 03.

### Task 3: Testing¶

As you implement the functions in `src/arrayset.c`, you should use `bin/test_arrayset.sh` to test each function:

``````# Build unit-test
\$ make bin/unit_arrayset
gcc -Wall -std=gnu99 -g -Iinclude -c -o tests/unit_arrayset.o tests/unit_arrayset.c
gcc -Llib -o bin/unit_arrayset tests/unit_arrayset.o lib/libds.a

# Run test script manually
\$ ./bin/test_arrayset.sh
Testing arrayset...
arrayset_create                          ... Success
arrayset_delete                          ... Success
arrayset_contains                        ... Success
arrayset_add                             ... Success
arrayset_remove                          ... Success

Score 2.00 / 2.00
Status Success
``````

Alternatively, you can both build the artifacts and run the test script by doing the following:

``````# Build and run test scripts
\$ make test-arrayset
...
``````

If one of the functions fails, and you need to debug the unit tests, you can run the `bin/unit_arrayset` command directly:

``````# Display usage message
\$ ./bin/unit_arrayset
Usage: ./bin/unit_arrayset NUMBER

Where NUMBER is right of the following:
0  Test arrayset_create
1  Test arrayset_delete
2  Test arrayset_contains
3  Test arrayset_add
4  Test arrayset_remove

# Run test for arrayset_create
\$ ./bin/unit_arrayset 0

# Run test for arrayset_create using GDB
\$ gdb ./bin/unit_arrayset
...
(gdb) run 0

# Run test for arrayset_create using Valgrind
\$ valgrind --leak-check=full ./bin/unit_arrayset 0
``````

Of course, you are free to create your own test programs to debug and test your `ArraySet` library.

#### Iterative Development¶

You should practice iterative development. That is, rather than writing a bunch of code and then debugging it all at once, you should concentrate on one function at a time and then test that one thing at a time. The provided unit tests allow you to check on the correctness of the individual functions without implementing everything at once. Take advantage of this and build one thing at a time.

## Activity 2: ListSet Library (4 Points)¶

For the second activity, you are to complete the `ListSet` library, which implements a set using an ordered linked list. That is, to maintain a unique collection of values, you will store values in the internal linked list in ascending order. Unlike with the `ArraySet`, you will perform linear search to check if a value is already in the `ListSet`.

As be seen above, the `ListSet` struct is an ordered singly linked list with a dummy node at the front of the sequence. That is, the first `ListSet` struct in the sequence is a dummy and not used to hold any values. It is there to simplify the `listset_add` and `listset_remove` functions by ensuring there is always a previous `ListSet` struct.

### Task 1: `include/ds/listset.h`¶

The `include/ds/listset.h` file is the header file for the `ListSet` structure, which contains the following structs and function prototypes:

``````/* listset.h: Set (Linked List) */

#pragma once

#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

/* Structures */

typedef struct ListSet ListSet;
struct ListSet {
int64_t  data;
ListSet *next;
};

/* Functions */

ListSet *   listset_create(int64_t data, ListSet *next);
void        listset_delete(ListSet *ls);

size_t      listset_size(ListSet *ls);
bool        listset_contains(ListSet *ls, int64_t value);
void        listset_add(ListSet *ls, int64_t value);
void        listset_remove(ListSet *ls, int64_t value);
``````

Note: For this task, you do not need to modify this file. Instead, you should review it and ensure you understand the provided code.

### Task 2: `src/listset.c`¶

The `src/listset.c` file contains the C implementation for the `ListSet` structure. For this task, you will need to implement the following functions:

1. `ListSet* listset_create(int64_t data, ListSet *next)`

This function allocates a new `ListSet` struct and initializes its internal attributes: `data` and `next`.

Hint: Use malloc or calloc to allocate data on the heap.

2. `void listset_delete(ListSet *ls)`

This function recursively deallocates the given `ListSet` struct along with the rest of the sequence.

Hint: Consider the base case and use free to release data allocated on the heap.

3. `size_t listset_size(ListSet *ls)`

This function recursively determines the number of values in the `ListSet` struct.

Hint: Use the internal `listset_size_r` on the first valid `ListSet` struct to recursively traverse through the sequence. The `listset_size_r` function should consider its base case and recursive step.

4. `bool listset_contains(ListSet *ls, int64_t value)`

This function returns `true` if the `value` is in the `ListSet`, otherwise it returns `false`.

Hint: Use linear search in the internal `listset_contain_r` function to recursively locate the `value`. The `listset_contains_r` function should consider its three base cases and its recursive step.

5. `void listset_add(ListSet *ls, int64_t value)`

This function adds the `value` to the `ListSet` while maintaining both uniqueness (ie. two values are the same) and ordering (ie. values are in ascending order).

Hint: Use linear search in the internal `listset_add_r` function to recursively locate where to insert a new `ListSet` struct with the specified `value`. The `listset_add_r` function should consider its three base cases and its recursive step.

6. `void listset_remove(ListSet *ls, int64_t value)`

This function removes the `value` from the `ListSet`.

Hint: Use linear search in the internal `listset_remove_r` function to recursively locate the `ListSet` struct with the specified `value`. The `listset_remove_r` function should consider its two base cases and its recursive step.

#### Recursion¶

Note: All the functions in the `ListSet`, besides `list_create` must be recursive functions. For your convenience, we have provided a few helper recursive functions such as `listset_size_r`, `listset_contains_r`, `listset_add_r`, `listset_remove_r`. These are meant to be called from their non-recursive functions on the first valid `ListSet` struct:

``````size_t    listset_size(ListSet *ls) {
return listset_size_r(ls->next);
}
``````

### Task 3: Testing¶

As you implement the functions in `src/listset.c`, you should use `bin/unit_listset.sh` to test each function:

``````# Build unit-test
\$ make bin/unit_listset
gcc -Wall -std=gnu99 -g -Iinclude -c -o tests/unit_listset.o tests/unit_listset.c
gcc -Llib -o bin/unit_listset tests/unit_listset.o lib/libds.a

# Run test script manually
\$ ./bin/test_listset.sh
Testing listset...
listset_create                           ... Success
listset_delete                           ... Success
listset_size                             ... Success
listset_contains                         ... Success
listset_add                              ... Success
listset_remove                           ... Success

Score 4.00 / 4.00
Status Success
``````

Alternatively, you can both build the artifacts and run the test script by doing the following:

``````# Build and run test scripts
\$ make test
...
``````

If one of the functions fails, and you need to debug the unit tests, you can run the `bin/unit_listset` command directly:

``````# Display usage message
\$ ./bin/unit_listset
Usage: ./bin/unit_listset NUMBER

Where NUMBER is right of the following:

0  Test listset_create
1  Test listset_delete
2  Test listset_size
3  Test listset_contains
4  Test listset_add
5  Test listset_remove

# Run test for listset_create
\$ ./bin/unit_listset 0

# Run test for listset_create using GDB
\$ gdb ./bin/unit_listset
...
(gdb) run 0

# Run test for listset_create using Valgrind
\$ valgrind --leak-check=full ./bin/unit_listset 0
``````

Of course, you are free to create your own test programs to debug and test your `ListSet` library.

## Activity 3: Bitset (1 Points)¶

For the third activity, you are to complete the `BitSet` library, which implements a set using a bitset. That is, to maintain a unique collection of values, you will mark individual bits in an unsigned long integer (i.e. `uint64_t`) that correspond to the values you are tracking.

### Task 1: `include/ds/bitset.h`¶

The `include/ds/bitst.h` file is the header file for the `BitSet` library, which contains the following function prototypes:

``````/* bitset.h: Set (BitSet) */

#pragma once

#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

/* Type Definitions */

typedef uint64_t BitSet;

/* Functions */

bool      bitset_contains(BitSet *bs, int64_t value);
void      bitset_add(BitSet *bs, int64_t value);
void      bitset_remove(BitSet *bs, int64_t value);
size_t    bitset_size(BitSet *bs);
``````

Note: For this task, you do not need to modify this file. Instead, you should review it and ensure you understand the provided code.

### Task 2: `src/bitset.c`¶

The `src/bitset.c` file contains the C implementation for the `BitSet` library. For this task, you will need to implement the following functions:

1. `bool bitset_contains(BitSet *bs, int64_t value)`

This function returns `true` if the `value` is in the `BitSet`, otherwise it returns `false`.

2. `void bitset_add(BitSet *bs, int64_t value)`

This function adds the `value` to the `BitSet`.

3. `void bitset_remove(BitSet *bs, int64_t value)`

This function removes the `value` from the `ListSet`.

4. `size_t bitset_size(BitSet *bs)`

This function returns the number of values in the `BitSet`.

Hint: Use `bitset_contains` on each possible value.

### Task 3: Testing¶

As you implement the functions in `src/bitset.c`, you should use `bin/unit_bitset.sh` to test each function:

``````# Build unit-test
\$ make bin/unit_bitset
gcc -Wall -std=gnu99 -g -Iinclude -c -o tests/unit_bitset.o tests/unit_bitset.c
gcc -Llib -o bin/unit_bitset tests/unit_bitset.o lib/libds.a

# Run test script manually
\$ ./bin/test_bitset.sh
Testing bitset...
bitset_contains                          ... Success
bitset_add                               ... Success
bitset_remove                            ... Success
bitset_size                              ... Success

Score 1.00 / 1.00
Status Success
``````

Alternatively, you can both build the artifacts and run the test script by doing the following:

``````# Build and run test scripts
\$ make test
...
``````

If one of the functions fails, and you need to debug the unit tests, you can run the `bin/unit_bitset` command directly:

``````# Display usage message
\$ ./bin/unit_bitset
Usage: ./bin/unit_bitset NUMBER

Where NUMBER is right of the following:

0  Test bitset_contains
1  Test bitset_add
2  Test bitset_remove
3  Test bitset_size

# Run test for bitset_contains
\$ ./bin/unit_bitset 0

# Run test for bitset_contains using GDB
\$ gdb ./bin/unit_bitset
...
(gdb) run 0

# Run test for bitset_contains using Valgrind
\$ valgrind --leak-check=full ./bin/unit_bitset 0
``````

Of course, you are free to create your own test programs to debug and test your `BitSet` library.

## Activity 4: Palindromic (3 Points)¶

For this activity, you are use your three set implementations to solve the following programming challenge:

Given a word, you are to determine if any permutation of the word is a palindrome, which is a phrase that reads the same forwards and backwards (ignoring case). For instance, "tacocat" is an example of a palindrome.

To do this, you will complete the `bin/palindromic` program, which reads in one word at a time from `stdin` and prints `YEAH` if it is a palindromic permutation, otherwise it prints out `NOPE`:

``````# Check if words are palindromic permutations using ArraySet
\$ ./bin/palindromic -a
tacocat
YEAH
burrito
NOPE
ttaacco
YEAH

# Check if words are palindromic permutations using ListSet
\$ ./bin/palindromic -l
tacocat
YEAH
burrito
NOPE
ttaacco
YEAH

# Check if words are palindromic permutations using BitSet
\$ ./bin/palindromic -b
tacocat
YEAH
burrito
NOPE
ttaacco
YEAH
``````

#### Memory Management¶

In addition to meeting the functional requirements of the assignment (as described above), your program must not exhibit any memory leaks or invalid memory accesses as would be detected by Valgrind.

Be sure to free any memory that has been allocated on the heap and to initialize any allocate memory appropriately.

### Task 1: `src/palindromic.c`¶

The `src/palindromic.c` file contains the C implementation of the `bin/palindromic` program described above. You will need to implement the following functions:

1. `bool is_palindromic_arrayset(const char *s)`

This function returns `true` if the string `s` is a palindromic permutation, otherwise it returns `false`.

2. `bool is_palindromic_listset(const char *s)`

This function returns `true` if the string `s` is a palindromic permutation, otherwise it returns `false`.

3. `bool is_palindromic_listset(const char *s)`

This function returns `true` if the string `s` is a palindromic permutation, otherwise it returns `false`.

Hint: For each of the three functions above, use the corresponding set implementation: `ArraySet`, `ListSet`, `BitSet`.

The functions should be largely the same except for changing the underlying set implementation.

To solve the problem, consider when you would want to add to the set as you process each letter and what you would want to remove. Moreover, consider what the final size of the set should be when you finish processing all the letters.

To ignore case, consider using tolower.

Note: The `main` function will parse the command line options, and then read each line of `stdin`, process it with one of the `is_palindromic` functions above, and finally output the result.

This function is provided to you and you do not need to modify it.

### Task 2: Testing¶

As you implement `src/palindromic.c`, you can test it by running the `test-palindromic` target:

``````# Build artifact and run test
\$ make test-palindromic
bin/test_palindromic.sh
Testing palindromic ...
ArraySet (output)                        ... Success
ArraySet (valgrind)                      ... Success
ListSet  (output)                        ... Success
ListSet  (valgrind)                      ... Success
BitSet   (output)                        ... Success
BitSet   (valgrind)                      ... Success

Score 3.00 / 3.00
Status Success
``````

## Activity 5: Quiz (2 Points)¶

Once you have completed all the activities above, you are to complete the following reflection quiz:

As with Reading 01, you will need to store your answers in a `homework05/answers.json` file. You can use the form above to generate the contents of this file, or you can write the JSON by hand.

To check your quiz directly, you can use the `check.py` script:

``````\$ ../.scripts/check.py
Checking homework05 quiz ...
Q1 0.30
Q2 0.30
Q3 0.30
Q4 0.30
Q5 0.30
Q6 0.20
Q7 0.30

Score 2.00 / 2.00
Status Success
``````

## Leet Point (1 Extra Credit Point)¶

For extra credit, you are to solve the following LeetCode problem in C.

2389. Longest Subsequence With Limited Sum

To receive credit, you must pass on LeetCode and achieve an Accepted submission.

#### Verification¶

To get credit for this Leet Point, show your solution and the LeetCode acceptance page to a TA to verify (or attached a screenshot with both to your Pull Request). You have up until two days after this assignment is due to verify your Leet Point.

#### Self-Service Extension¶

Remember that you can always forgo this Leet Point for two extra days to do the homework. That is, if you need an extension, you can simply skip the Leet Point and you will automatically have until Friday to complete the assignment for full credit.

Just leave a note on your Pull Request of your intentions.

## Submission¶

To submit your assignment, please commit your work to the `homework05` folder of your `homework05` branch in your assignments GitHub repository:

``````#-----------------------------------------------------------------------
# Make sure you have already completed Activity 0: Preparation
#-----------------------------------------------------------------------
...
\$ git add Makefile                            # Mark changes for commit
\$ git commit -m "Homework 05: Activity 0"     # Record changes
...
\$ git add src/arrayset.c                      # Mark changes for commit
\$ git commit -m "Homework 05: Activity 1"     # Record changes
...
\$ git add src/listset.c                       # Mark changes for commit
\$ git commit -m "Homework 05: Activity 2"     # Record changes
...
\$ git add src/bitset.c                        # Mark changes for commit
\$ git commit -m "Homework 05: Activity 3"     # Record changes
...
\$ git add src/palindromic.c                   # Mark changes for commit
\$ git commit -m "Homework 05: Activity 4"     # Record changes
...
\$ git add answers.json                        # Mark changes for commit
\$ git commit -m "Homework 05: Activity 5"     # Record changes
...

\$ git push -u origin homework05               # Push branch to GitHub
``````

#### Pull Request¶

Remember to create a Pull Request and assign the appropriate TA from the Reading 05 TA List.

DO NOT MERGE your own Pull Request. The TAs use open Pull Requests to keep track of which assignments to grade. Closing them yourself will cause a delay in grading and confuse the TAs.