Programming Fundamentals

Information

  • This page contains additional revision exercises for week 10.
  • These exercises are not compulsory, nor do they provide any marks in the course.
  • You cannot submit any of these exercises, however autotests are available for them (Command included at bottom of each exercise).

Revision Video: Linked Lists - Prerequisites

Revision Video: Linked Lists - Creating and traversing a linked list (Coding)

Revision Video: Linked List - Sorted Insert

Revision Video: Linked Lists - Adding elements to a Linked List (Coding)

Revision Video: Linked List - Delete

Revision Video: Linked Lists - Deleting elements from a Linked List (Coding)

Exercise — individual:
List range

Your task is to add code to this function in list_range.c
int get_list_range(struct node *head) {

    // TODO: Find the range of the linked list

    return 0;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

get_list_range is given one argument, head, which is the pointer to the first node in a linked list.

get_list_range should return the value of the range of the list. If the list is empty, the range should be 0.

The range can be calculated as range = max - min

For example if the linked list contains these 8 elements:

10, 13, 8, 17, 19, 7, 9

Then the function should return 12 because the highest value is 19, and the lowest value is 7, therefore range = 19 - 7 = 12

Additionally, if the linked list contains

5

Then the function should return 0 since the max and min values are both 5, then range = 5 - 5 = 0

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_range

Exercise — individual:
Join 2 lists

Your task is to add code to this function in list_join.c
struct node *join_two_lists(struct node *list1, struct node *list2) {

    // TODO: return a pointer to the head of the new list
    
    return NULL;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

join_two_lists is given two pointers, each one to the head of a separate linked list.

join_two_lists should return a pointer to the first node in a list which joins the second list to the end of the first list.

For example, if the following two linked lists were passed in

Then, join_two_lists would append list2 to the end of list1, and return a pointer to list 1. The diagram for this scenario would look like the following. Note, this does NOT create a new list, it simply modifies the first list.

join_two_lists should not call malloc.

join_two_lists should still work if the first list is empty.

join_two_lists should still work if the second list is empty.

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_join

Exercise — individual:
List length difference

Your task is to add code to this function in list_length_difference.c
int get_length_diff(struct node *list1, struct node *list2) {

    // TODO: find the difference in length between the two lists

    return 0;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

get_length_diff is given two pointers, each one to the head of a separate linked list.

get_length_diff returns the difference in length of the two lists, as an integer.

The difference in the length can be calculated as difference = (list 2 length) - (list 1 length)

If both lists are empty, the difference should be 0

For example if the linked list contains these 8 elements:

    List 1 => [5, 2, 7, 4]
    List 2 => [3, 5, 2, 5, 8]

Then the difference would be 1 since the length of list 2 is 5 and the length of list 1 is 4, therefore difference is 5 - 4 = 1

Additionally if we have the following two lists

    List 1 => [5, 2, 7, 4]
    List 2 => [3, 5]

Then the difference would be -2 since the length of list 2 is 2 and the length of list 1 is 4, therefore difference is 2 - 4 = -2

get_length_diff should work if list1 is empty.

get_length_diff should work if list2 is empty.

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_length_difference

Exercise — individual:
Insert in middle

Your task is to add code to this function in list_insert_middle.c
struct node *insert_middle(struct node *head, int new_value) {

    // TODO: Insert new_value as a new node in the middle of 
    // the existing linked list.

    return NULL;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

insert_middle is given a pointer to the head of a linked list and an integer value.

insert_middle returns the difference in length of the two lists, as an integer.

For example, if the function is asked to insert the value 5 and the given list has the following values

    Head => [10, 11, 12, 13]

After the insertion, the list would have the following values

    Head => [10, 11, 5, 12, 13]

insert_middle should return a pointer to the head of the list.

insert_middle should create a new list and insert at the head of this list when the provided list is empty.

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_insert_middle

Exercise — individual:
List count divisible

Your task is to add code to this function in list_count_divisible.c
int count_divisible_six(struct node *head) {

    // TODO: Count the number of nodes with a data
    // value divisible by 6

    return 0;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

count_divisible_six is given a pointer to the head of a linked list.

count_divisible_six should count the number of data values in the linked list which are divisible by 6 with no remainder, and should return this count.

For example, if the given list has the following values

    Head => [10, 12, 14, 15, 18, 19]

The function should return a value of 2 since only the values of 12 and 18 are divisible by 6, with no remainder.

count_divisible_six should work with an empty list.

count_divisible_six should work when no values are divisible by 6.

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_count_divisible

Exercise — individual:
List delete first divisible

Your task is to add code to this function in list_delete_first_divisible.c
struct node *delete_divisible_six(struct node *head) {

    // TODO: Delete the first node which is divisible by 6

    return NULL;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

delete_divisible_six is given a pointer to the head of a linked list.

delete_divisible_six should delete and free the first node in the linked list, which is divisible by 6 with no reminder.

delete_divisible_six should return a pointer to the head of the linked list

For example, if the given list has the following values

    Head => [10, 12, 14, 15, 18, 12]

The function should would remove the first node with a value of 12 since this is the first node divisible by 6. The resultant linked list would have the following values;

    Head => [10, 14, 15, 18, 12]

delete_divisible_six does not need to create a new list, simply modify the existing list.

delete_divisible_six should not call malloc.

delete_divisible_six should work with an empty list.

delete_divisible_six should work with a list where no values are divisible by 6.

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_delete_first_divisible

Exercise — individual:
Filter a 1D array

Download filter_list.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/filter_list/filter_list.c .

Your task is to write a program to find the number of bags from people over a specified height.

More specifically, your program should do the following.

  1. Scan in 5 pairs of height and number of bags, and store these pairs in an array of structs.
  2. Ask the user for a minimum height to filter by
  3. Find the number of bags, from people who were greater than or equal to that height

This program has some stater code which includes the following struct.

struct passenger {
    double height;
    int num_bags;
};

The starter code also creates an array for you to store data in.

struct passenger my_array[SIZE];

Some examples of this program working are below:

dcc filter_list.c -o filter_list
./filter_list
Enter height & number of bags: 150.0 1
Enter height & number of bags: 160.0 2
Enter height & number of bags: 170.0 3
Enter height & number of bags: 180.0 1
Enter height & number of bags: 190.0 2
Select height: 170.0
Total of 6 bags from people over 170.000000
dcc filter_list.c -o filter_list
./filter_list
Enter height & number of bags: 150.0 1
Enter height & number of bags: 160.0 1
Enter height & number of bags: 170.0 1
Enter height & number of bags: 180.0 1
Enter height & number of bags: 190.0 1
Select height: 200.0
Total of 0 bags from people over 200.000000

Assumptions/Restrictions/Clarifications.

Your program should match the output shown above exactly.

You can assume you will always be given the correct data type during input.

You can assume a height is always a positive and non-zero number.

You can assume the number of bags is non-negative.

Your program should still work when a person has no baggage.

Testing

You can autotest your program with the following command

1511 autotest filter_list filter_list.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest filter_list

Exercise — individual:
Find totals of rows

Download find_totals.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/find_totals/find_totals.c .

Your task is to add code to this function in find_totals.c:

int find_totals(int arr[SIZE][SIZE], int size) {

    // TODO: Find the number of rows with a 
    // sum equal to exactly 10

    return 0;
}

Given a 2d arrays of integers, your task is to find the number of rows where the sum of the integers equates to exactly 10.

You can assume the given array is always of size 5

You can assume the array always has the same number of rows and columns (The array is always square)

Only this specific function will be called in marking, the main function is only provided for your testing, however you can create more functions it is helpful.

For example, if the following 2D array was given

The output should be exactly

./find_totals
2 rows had a sum of 10

This output is becasue rows 2 and 3 each have a sum of exactly 10.

Your function should work when there are arrays with no rows equal to 10.

Testing

You can autotest your program with the following command

1511 autotest find_totals find_totals.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest find_totals

Exercise — individual:
Insert after lowest

Download insert_after_lowest.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/list_insert_after_lowest/insert_after_lowest.c .

Your task is to add code to this function in insert_after_lowest.c:

struct node *insert_after_lowest(struct node *head, int data) {

    // TODO: Insert a new node with the value, 'data' 
    // after the node with the lowest data.

    return NULL;
}

Given a linked list, your task is to insert a new node, with a specific value, after the node with the lowest values in the linked list.

insert_after_lowest is given a pointer to a linked list and the data values that is to be added.

insert_after_lowest should return a pointer to the linked list

This program uses the familiar data type below

struct node {
    int          data;
    struct node *next;
};

Only this specific function will be called in marking, the main function is only provided for your testing, however you can create more functions if it is helpful.

insert_after_lowest should find the lowest value in the linked list, and insert a new node directly after it.

For example, if the linked list had the values

    Head => [4, 2, 6]

And the function was asked to add the value 99, the list after modification would look as the following

    Head => [4, 2, 99, 6]

The below shows the output when the program is run with the example given in the starter code main function.

dcc insert_after_lowest.c -o insert_after_lowest
./insert_after_lowest
4 -> 2 -> 6 -> X
4 -> 2 -> 99 -> 6 -> X

insert_after_lowest should still insert the new node if the list is empty.

insert_after_lowest should only ever insert ONE node after the first instance of the lowest value, even if there are multiple nodes with the same lowest value.

Testing

You can autotest your program with the following command

1511 autotest insert_after_lowest insert_after_lowest.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_insert_after_lowest

Exercise — individual:
Insert in alternating order

Download insert_alternating.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/list_insert_alternating/insert_alternating.c .

Your task is to write a program which will read values until EOF, and insert these values into a linked list in an alternating order.

Specifically, your program should read integers from the terminal, until EOF, and insert the first value to the head of the list, then the second value is to the tail of the list, then the third value is added to the head of the list etc.

A minimal starter program is given to you, this program should use the familiar data type

struct node {
    int data;
    struct node *next;
};

You may also find the given create_node function helpful in you implementation.

Your program should use the provided print_list function to print the list after EOF is received.

For example, if your program was given the following inputs

    1 2 3 4 5

The resultant linked list should be as follows

    Head => [5, 3, 1, 2, 4]

This is because;

  • 1 was added to the head of an empty list
  • 2 was added to the tail of the list
  • 3 was added to the head of the list
  • 4 was added to the tail of the list
  • 5 was added to the head of the list

An example program usage is shown below

dcc insert_alternating.c -o insert_alternating
./insert_alternating
1
2
3
4
5

5 -> 3 -> 1 -> 2 -> 4 -> X
dcc insert_alternating.c -o insert_alternating
./insert_alternating
1
1
1
2
2
3
3

3 -> 2 -> 1 -> 1 -> 1 -> 2 -> 3 -> X
dcc insert_alternating.c -o insert_alternating
./insert_alternating

X

Your program should be able to accept an unlimited number of values

Your program should print an empty list if no values were inputted

Testing

You can autotest your program with the following command

1511 autotest insert_alternating insert_alternating.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_insert_alternating

Exercise — individual:
Find adjacent point distances

Download adjacent_distances.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/adjacent_distances/adjacent_distances.c .

Your task is to add code to this function in adjacent_distances.c:

void adjacent_distances(struct coordinate arr[SIZE], int size) {
    // TODO: Print the distances between adjacent coordinates

    // Your function should NOT return anything
    // Your function SHOULD print the distances
}

Your task is to print the Euclidean distance between adjacent coordinates in an array of coordinates.

Specifically, given a 1D array of structs, where each struct contains an x and y coordinate, you need to calculate and print the distance between coordinates stored next to each other in the array.

This program uses the following struct to store coordinates

struct coordinate {
    int x;
    int y;
};

Coordinates are stored in an array of struct coordinates, always of size 5. This can be seen in the starter program. Note; Some example values are given to the array of structs for your testing

struct coordinate array1[SIZE];

For this array of size 5, you must calculate and print the Euclidean distance between coordinates in

  • Index 0 & Index 1
  • Index 1 & Index 2
  • Index 2 & Index 3
  • Index 3 & Index 4

The euclidean distance can be calculated using the provided e_dist function in the starter code. This function takes in two struct coordinate and returns the distance between them as a double.

You must implement the function given to you, the function will be called directly in marking and the main function will be ignored. You may create extra function if you find that helpful.

For example, the output of the test input given in the main function, would be

dcc adjacent_distances.c -o adjacent_distances
./adjacent_distances
Dist: 1.414214
Dist: 7.000000
Dist: 9.899495
Dist: 9.219544

Your program must produce this output exactly

Testing

You can autotest your program with the following command

1511 autotest adjacent_distances adjacent_distances.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest adjacent_distances

Exercise — individual:
Clamp a 2D array

Download array_clamping_max.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/array_clamping_max/array_clamping_max.c .

Your task is to add code to this function in array_clamping_max.c:

void clamp_max(int arr[SIZE][SIZE], int size, int max) {
    // TODO: Make sure all values are <= max
    // Change any values that are > max
}

Given a 2D array of integers and a maximium value, you must make sure all values within the 2D array are less than or equal to that maximium value. If a value is greater than the max value, you should change the value to be equal to the max value.

For example if the given array was as follows, and the max value was set to 10

Then the array should be changed to be

Your function will be called directly in marking, any changes in the main function will not be used. You may use additional functions if you find it helpful.

You can assume the array is always square and the size is always 5.

The array values given can be any valid integer.

You are not required to print the array, this is handled separately.

You are only required to implement the clamp_max function.

The below shows the output using the example main function

dcc adjacent_distances.c -o adjacent_distances
./adjacent_distances
Before:
  9   3   2   5   2 
  2  12   5   1  11 
  4   4   7   7   6 
 10   0   4  15   0 
  2   9   0   4   0 
After:
  9   3   2   5   2 
  2  10   5   1  10 
  4   4   7   7   6 
 10   0   4  10   0 
  2   9   0   4   0 

Your program must produce this output exactly

Testing

You can autotest your program with the following command

1511 autotest adjacent_distances adjacent_distances.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest array_clamping_max

Exercise — individual:
Delete negatives

Download list_delete_negatives.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/list_delete_negatives/list_delete_negatives.c .

Your task is to add code to this function in list_delete_negatives.c:

struct node *delete_negatives(struct node *head) {

    // TODO: Delete any nodes in the linked list 
    // with a data value < 0

    return NULL;
}

Given a linked list, your task is to delete any nodes which have a value strictly less than 0. Any nodes which are deleted must be properly free'd.

This program uses the familiar data type below

struct node {
    int data;
    struct node *next;
};

list_delete_negatives is given a pointer to a linked list.

list_delete_negatives should return a pointer to the head of the linked list.

Only this specific function will be called in marking, the main function is only provided for your testing, however you can create more functions if it is helpful.

Your function should operate normally with an empty linked list.

Your function should not change the list if there are no negative numbers within the list.

You function should not call malloc.

Your function should not have any memory leaks and should pass a leak-check.

For example, if the linked list had the values

    Head => [3, 4, -5, 10, -10]

Your function should return a pointer to a linked list with the following values

    Head => [3, 4, 10]

Additionally, if the linked list had the values

    Head => [-2, -2, 6]

Your function should return a pointer to a linked list with the following values

    Head => [6]

The below shows the output when the program is run with the example given in the starter code main function.

dcc list_delete_negatives.c -o list_delete_negatives
./list_delete_negatives
4 -> -2 -> 6 -> X
4 -> 6 -> X

Testing

You can autotest your program with the following command

1511 autotest list_delete_negatives list_delete_negatives.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_delete_negatives

Exercise — individual:
Delete Duplicates

Download list_delete_duplicates.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/list_delete_duplicates/list_delete_duplicates.c .

Your task is to add code to this function in list_delete_duplicates.c:

struct node *delete_duplicates(struct node *head) {

    // TODO: delete any adjacent duplicate values

    return NULL;
}

Given a linked list, delete any values which are adjacent duplicates in the linked list.

This program uses the familiar data type below

struct node {
    int data;
    struct node *next;
};

delete_duplicates is given a pointer to a linked list.

delete_duplicates should return a pointer to the head of the linked list.

delete_duplicates should only remove duplicate values which are next to each other in the list (adjacent).

delete_duplicates can delete more than 1 successive duplicate value.

delete_duplicates should remove all but the first instance of the value in a set of duplicates, such that the value only appears once in that part of the list.

The same value can appear multiple times in the linked list, provided they are not adjacent.

delete_duplicates can remove the same value multiple times in the list.

See the examples for more details

Example 1

For example, if the linked list had the values

    Head => [2, 3, 3, 5, 6]

After removing duplicates, the list would become

    Head => [2, 3, 5, 6]

Example 1

For example, if the linked list had the values

    Head => [10, 11, 11, 11, 11, 12]

After removing duplicates, the list would become

    Head => [10, 11, 12]

Example 3

For example, if the linked list had the values

    Head => [10, 11, 11, 25, 11, 11]

After removing duplicates, the list would become

    Head => [10, 11, 25, 11]

Only this specific function will be called in marking, the main function is only provided for your testing, however you can create more functions if it is helpful.

Your function should operate normally with an empty linked list.

Your function should not change the list if there are no duplicate numbers within the list.

You function should not call malloc.

Your function should not have any memory leaks and should pass a leak-check.

The below shows the output when the program is run with the example given in the starter code main function.

dcc list_delete_duplicates.c -o list_delete_duplicates
./list_delete_duplicates
2 -> 4 -> 4 -> 6 -> X
2 -> 4 -> 6 -> X

Testing

You can autotest your program with the following command

1511 autotest list_delete_duplicates list_delete_duplicates.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_delete_duplicates

Exercise — individual:
List range

Your task is to add code to this function in list_range.c
int get_list_range(struct node *head) {

    // TODO: Find the range of the linked list

    return 0;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

get_list_range is given one argument, head, which is the pointer to the first node in a linked list.

get_list_range should return the value of the range of the list. If the list is empty, the range should be 0.

The range can be calculated as range = max - min

For example if the linked list contains these 8 elements:

10, 13, 8, 17, 19, 7, 9

Then the function should return 12 because the highest value is 19, and the lowest value is 7, therefore range = 19 - 7 = 12

Additionally, if the linked list contains

5

Then the function should return 0 since the max and min values are both 5, then range = 5 - 5 = 0

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_range

Exercise — individual:
Join 2 lists

Your task is to add code to this function in list_join.c
struct node *join_two_lists(struct node *list1, struct node *list2) {

    // TODO: return a pointer to the head of the new list
    
    return NULL;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

join_two_lists is given two pointers, each one to the head of a separate linked list.

join_two_lists should return a pointer to the first node in a list which joins the second list to the end of the first list.

For example, if the following two linked lists were passed in

Then, join_two_lists would append list2 to the end of list1, and return a pointer to list 1. The diagram for this scenario would look like the following. Note, this does NOT create a new list, it simply modifies the first list.

join_two_lists should not call malloc.

join_two_lists should still work if the first list is empty.

join_two_lists should still work if the second list is empty.

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_join

Exercise — individual:
List length difference

Your task is to add code to this function in list_length_difference.c
int get_length_diff(struct node *list1, struct node *list2) {

    // TODO: find the difference in length between the two lists

    return 0;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

get_length_diff is given two pointers, each one to the head of a separate linked list.

get_length_diff returns the difference in length of the two lists, as an integer.

The difference in the length can be calculated as difference = (list 2 length) - (list 1 length)

If both lists are empty, the difference should be 0

For example if the linked list contains these 8 elements:

    List 1 => [5, 2, 7, 4]
    List 2 => [3, 5, 2, 5, 8]

Then the difference would be 1 since the length of list 2 is 5 and the length of list 1 is 4, therefore difference is 5 - 4 = 1

Additionally if we have the following two lists

    List 1 => [5, 2, 7, 4]
    List 2 => [3, 5]

Then the difference would be -2 since the length of list 2 is 2 and the length of list 1 is 4, therefore difference is 2 - 4 = -2

get_length_diff should work if list1 is empty.

get_length_diff should work if list2 is empty.

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_length_difference

Exercise — individual:
Insert in middle

Your task is to add code to this function in list_insert_middle.c
struct node *insert_middle(struct node *head, int new_value) {

    // TODO: Insert new_value as a new node in the middle of 
    // the existing linked list.

    return NULL;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

insert_middle is given a pointer to the head of a linked list and an integer value.

insert_middle returns the difference in length of the two lists, as an integer.

For example, if the function is asked to insert the value 5 and the given list has the following values

    Head => [10, 11, 12, 13]

After the insertion, the list would have the following values

    Head => [10, 11, 5, 12, 13]

insert_middle should return a pointer to the head of the list.

insert_middle should create a new list and insert at the head of this list when the provided list is empty.

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_insert_middle

Exercise — individual:
List count divisible

Your task is to add code to this function in list_count_divisible.c
int count_divisible_six(struct node *head) {

    // TODO: Count the number of nodes with a data
    // value divisible by 6

    return 0;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

count_divisible_six is given a pointer to the head of a linked list.

count_divisible_six should count the number of data values in the linked list which are divisible by 6 with no remainder, and should return this count.

For example, if the given list has the following values

    Head => [10, 12, 14, 15, 18, 19]

The function should return a value of 2 since only the values of 12 and 18 are divisible by 6, with no remainder.

count_divisible_six should work with an empty list.

count_divisible_six should work when no values are divisible by 6.

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_count_divisible

Exercise — individual:
List delete first divisible

Your task is to add code to this function in list_delete_first_divisible.c
struct node *delete_divisible_six(struct node *head) {

    // TODO: Delete the first node which is divisible by 6

    return NULL;
}

This question uses the following familiar data type.

struct node {
    int          data;
    struct node *next;
};

delete_divisible_six is given a pointer to the head of a linked list.

delete_divisible_six should delete and free the first node in the linked list, which is divisible by 6 with no reminder.

delete_divisible_six should return a pointer to the head of the linked list

For example, if the given list has the following values

    Head => [10, 12, 14, 15, 18, 12]

The function should would remove the first node with a value of 12 since this is the first node divisible by 6. The resultant linked list would have the following values;

    Head => [10, 14, 15, 18, 12]

delete_divisible_six does not need to create a new list, simply modify the existing list.

delete_divisible_six should not call malloc.

delete_divisible_six should work with an empty list.

delete_divisible_six should work with a list where no values are divisible by 6.

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_delete_first_divisible

Exercise — individual:
Filter a 1D array

Download filter_list.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/filter_list/filter_list.c .

Your task is to write a program to find the number of bags from people over a specified height.

More specifically, your program should do the following.

  1. Scan in 5 pairs of height and number of bags, and store these pairs in an array of structs.
  2. Ask the user for a minimum height to filter by
  3. Find the number of bags, from people who were greater than or equal to that height

This program has some stater code which includes the following struct.

struct passenger {
    double height;
    int num_bags;
};

The starter code also creates an array for you to store data in.

struct passenger my_array[SIZE];

Some examples of this program working are below:

dcc filter_list.c -o filter_list
./filter_list
Enter height & number of bags: 150.0 1
Enter height & number of bags: 160.0 2
Enter height & number of bags: 170.0 3
Enter height & number of bags: 180.0 1
Enter height & number of bags: 190.0 2
Select height: 170.0
Total of 6 bags from people over 170.000000
dcc filter_list.c -o filter_list
./filter_list
Enter height & number of bags: 150.0 1
Enter height & number of bags: 160.0 1
Enter height & number of bags: 170.0 1
Enter height & number of bags: 180.0 1
Enter height & number of bags: 190.0 1
Select height: 200.0
Total of 0 bags from people over 200.000000

Assumptions/Restrictions/Clarifications.

Your program should match the output shown above exactly.

You can assume you will always be given the correct data type during input.

You can assume a height is always a positive and non-zero number.

You can assume the number of bags is non-negative.

Your program should still work when a person has no baggage.

Testing

You can autotest your program with the following command

1511 autotest filter_list filter_list.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest filter_list

Exercise — individual:
Find totals of rows

Download find_totals.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/find_totals/find_totals.c .

Your task is to add code to this function in find_totals.c:

int find_totals(int arr[SIZE][SIZE], int size) {

    // TODO: Find the number of rows with a 
    // sum equal to exactly 10

    return 0;
}

Given a 2d arrays of integers, your task is to find the number of rows where the sum of the integers equates to exactly 10.

You can assume the given array is always of size 5

You can assume the array always has the same number of rows and columns (The array is always square)

Only this specific function will be called in marking, the main function is only provided for your testing, however you can create more functions it is helpful.

For example, if the following 2D array was given

The output should be exactly

./find_totals
2 rows had a sum of 10

This output is becasue rows 2 and 3 each have a sum of exactly 10.

Your function should work when there are arrays with no rows equal to 10.

Testing

You can autotest your program with the following command

1511 autotest find_totals find_totals.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest find_totals

Exercise — individual:
Insert after lowest

Download insert_after_lowest.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/list_insert_after_lowest/insert_after_lowest.c .

Your task is to add code to this function in insert_after_lowest.c:

struct node *insert_after_lowest(struct node *head, int data) {

    // TODO: Insert a new node with the value, 'data' 
    // after the node with the lowest data.

    return NULL;
}

Given a linked list, your task is to insert a new node, with a specific value, after the node with the lowest values in the linked list.

insert_after_lowest is given a pointer to a linked list and the data values that is to be added.

insert_after_lowest should return a pointer to the linked list

This program uses the familiar data type below

struct node {
    int          data;
    struct node *next;
};

Only this specific function will be called in marking, the main function is only provided for your testing, however you can create more functions if it is helpful.

insert_after_lowest should find the lowest value in the linked list, and insert a new node directly after it.

For example, if the linked list had the values

    Head => [4, 2, 6]

And the function was asked to add the value 99, the list after modification would look as the following

    Head => [4, 2, 99, 6]

The below shows the output when the program is run with the example given in the starter code main function.

dcc insert_after_lowest.c -o insert_after_lowest
./insert_after_lowest
4 -> 2 -> 6 -> X
4 -> 2 -> 99 -> 6 -> X

insert_after_lowest should still insert the new node if the list is empty.

insert_after_lowest should only ever insert ONE node after the first instance of the lowest value, even if there are multiple nodes with the same lowest value.

Testing

You can autotest your program with the following command

1511 autotest insert_after_lowest insert_after_lowest.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_insert_after_lowest

Exercise — individual:
Insert in alternating order

Download insert_alternating.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/list_insert_alternating/insert_alternating.c .

Your task is to write a program which will read values until EOF, and insert these values into a linked list in an alternating order.

Specifically, your program should read integers from the terminal, until EOF, and insert the first value to the head of the list, then the second value is to the tail of the list, then the third value is added to the head of the list etc.

A minimal starter program is given to you, this program should use the familiar data type

struct node {
    int data;
    struct node *next;
};

You may also find the given create_node function helpful in you implementation.

Your program should use the provided print_list function to print the list after EOF is received.

For example, if your program was given the following inputs

    1 2 3 4 5

The resultant linked list should be as follows

    Head => [5, 3, 1, 2, 4]

This is because;

  • 1 was added to the head of an empty list
  • 2 was added to the tail of the list
  • 3 was added to the head of the list
  • 4 was added to the tail of the list
  • 5 was added to the head of the list

An example program usage is shown below

dcc insert_alternating.c -o insert_alternating
./insert_alternating
1
2
3
4
5

5 -> 3 -> 1 -> 2 -> 4 -> X
dcc insert_alternating.c -o insert_alternating
./insert_alternating
1
1
1
2
2
3
3

3 -> 2 -> 1 -> 1 -> 1 -> 2 -> 3 -> X
dcc insert_alternating.c -o insert_alternating
./insert_alternating

X

Your program should be able to accept an unlimited number of values

Your program should print an empty list if no values were inputted

Testing

You can autotest your program with the following command

1511 autotest insert_alternating insert_alternating.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_insert_alternating

Exercise — individual:
Find adjacent point distances

Download adjacent_distances.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/adjacent_distances/adjacent_distances.c .

Your task is to add code to this function in adjacent_distances.c:

void adjacent_distances(struct coordinate arr[SIZE], int size) {
    // TODO: Print the distances between adjacent coordinates

    // Your function should NOT return anything
    // Your function SHOULD print the distances
}

Your task is to print the Euclidean distance between adjacent coordinates in an array of coordinates.

Specifically, given a 1D array of structs, where each struct contains an x and y coordinate, you need to calculate and print the distance between coordinates stored next to each other in the array.

This program uses the following struct to store coordinates

struct coordinate {
    int x;
    int y;
};

Coordinates are stored in an array of struct coordinates, always of size 5. This can be seen in the starter program. Note; Some example values are given to the array of structs for your testing

struct coordinate array1[SIZE];

For this array of size 5, you must calculate and print the Euclidean distance between coordinates in

  • Index 0 & Index 1
  • Index 1 & Index 2
  • Index 2 & Index 3
  • Index 3 & Index 4

The euclidean distance can be calculated using the provided e_dist function in the starter code. This function takes in two struct coordinate and returns the distance between them as a double.

You must implement the function given to you, the function will be called directly in marking and the main function will be ignored. You may create extra function if you find that helpful.

For example, the output of the test input given in the main function, would be

dcc adjacent_distances.c -o adjacent_distances
./adjacent_distances
Dist: 1.414214
Dist: 7.000000
Dist: 9.899495
Dist: 9.219544

Your program must produce this output exactly

Testing

You can autotest your program with the following command

1511 autotest adjacent_distances adjacent_distances.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest adjacent_distances

Exercise — individual:
Clamp a 2D array

Download array_clamping_max.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/array_clamping_max/array_clamping_max.c .

Your task is to add code to this function in array_clamping_max.c:

void clamp_max(int arr[SIZE][SIZE], int size, int max) {
    // TODO: Make sure all values are <= max
    // Change any values that are > max
}

Given a 2D array of integers and a maximium value, you must make sure all values within the 2D array are less than or equal to that maximium value. If a value is greater than the max value, you should change the value to be equal to the max value.

For example if the given array was as follows, and the max value was set to 10

Then the array should be changed to be

Your function will be called directly in marking, any changes in the main function will not be used. You may use additional functions if you find it helpful.

You can assume the array is always square and the size is always 5.

The array values given can be any valid integer.

You are not required to print the array, this is handled separately.

You are only required to implement the clamp_max function.

The below shows the output using the example main function

dcc adjacent_distances.c -o adjacent_distances
./adjacent_distances
Before:
  9   3   2   5   2 
  2  12   5   1  11 
  4   4   7   7   6 
 10   0   4  15   0 
  2   9   0   4   0 
After:
  9   3   2   5   2 
  2  10   5   1  10 
  4   4   7   7   6 
 10   0   4  10   0 
  2   9   0   4   0 

Your program must produce this output exactly

Testing

You can autotest your program with the following command

1511 autotest adjacent_distances adjacent_distances.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest array_clamping_max

Exercise — individual:
Delete negatives

Download list_delete_negatives.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/list_delete_negatives/list_delete_negatives.c .

Your task is to add code to this function in list_delete_negatives.c:

struct node *delete_negatives(struct node *head) {

    // TODO: Delete any nodes in the linked list 
    // with a data value < 0

    return NULL;
}

Given a linked list, your task is to delete any nodes which have a value strictly less than 0. Any nodes which are deleted must be properly free'd.

This program uses the familiar data type below

struct node {
    int data;
    struct node *next;
};

list_delete_negatives is given a pointer to a linked list.

list_delete_negatives should return a pointer to the head of the linked list.

Only this specific function will be called in marking, the main function is only provided for your testing, however you can create more functions if it is helpful.

Your function should operate normally with an empty linked list.

Your function should not change the list if there are no negative numbers within the list.

You function should not call malloc.

Your function should not have any memory leaks and should pass a leak-check.

For example, if the linked list had the values

    Head => [3, 4, -5, 10, -10]

Your function should return a pointer to a linked list with the following values

    Head => [3, 4, 10]

Additionally, if the linked list had the values

    Head => [-2, -2, 6]

Your function should return a pointer to a linked list with the following values

    Head => [6]

The below shows the output when the program is run with the example given in the starter code main function.

dcc list_delete_negatives.c -o list_delete_negatives
./list_delete_negatives
4 -> -2 -> 6 -> X
4 -> 6 -> X

Testing

You can autotest your program with the following command

1511 autotest list_delete_negatives list_delete_negatives.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_delete_negatives

Exercise — individual:
Delete Duplicates

Download list_delete_duplicates.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/23T1/activities/list_delete_duplicates/list_delete_duplicates.c .

Your task is to add code to this function in list_delete_duplicates.c:

struct node *delete_duplicates(struct node *head) {

    // TODO: delete any adjacent duplicate values

    return NULL;
}

Given a linked list, delete any values which are adjacent duplicates in the linked list.

This program uses the familiar data type below

struct node {
    int data;
    struct node *next;
};

delete_duplicates is given a pointer to a linked list.

delete_duplicates should return a pointer to the head of the linked list.

delete_duplicates should only remove duplicate values which are next to each other in the list (adjacent).

delete_duplicates can delete more than 1 successive duplicate value.

delete_duplicates should remove all but the first instance of the value in a set of duplicates, such that the value only appears once in that part of the list.

The same value can appear multiple times in the linked list, provided they are not adjacent.

delete_duplicates can remove the same value multiple times in the list.

See the examples for more details

Example 1

For example, if the linked list had the values

    Head => [2, 3, 3, 5, 6]

After removing duplicates, the list would become

    Head => [2, 3, 5, 6]

Example 1

For example, if the linked list had the values

    Head => [10, 11, 11, 11, 11, 12]

After removing duplicates, the list would become

    Head => [10, 11, 12]

Example 3

For example, if the linked list had the values

    Head => [10, 11, 11, 25, 11, 11]

After removing duplicates, the list would become

    Head => [10, 11, 25, 11]

Only this specific function will be called in marking, the main function is only provided for your testing, however you can create more functions if it is helpful.

Your function should operate normally with an empty linked list.

Your function should not change the list if there are no duplicate numbers within the list.

You function should not call malloc.

Your function should not have any memory leaks and should pass a leak-check.

The below shows the output when the program is run with the example given in the starter code main function.

dcc list_delete_duplicates.c -o list_delete_duplicates
./list_delete_duplicates
2 -> 4 -> 4 -> 6 -> X
2 -> 4 -> 6 -> X

Testing

You can autotest your program with the following command

1511 autotest list_delete_duplicates list_delete_duplicates.c

When you think your program is working, you can use autotest to run some simple automated tests:

1511 autotest list_delete_duplicates