Week 12 Tutorial Sample Answers

Assignment 2

In this section, we will briefly discuss how assignment 2 is going.

It's week 12 - revision week!


So far in the course we have covered:

Which topics are you struggling with? If you are struggling with any particular topic, perhaps your tutor could revisit that week.

Arrays

In this task, you will determine the total price of all food items of a specified type.

You have been given a function total_price_of_food_type.

You have also been given the definition of a struct: food, and an enum: food_type which tells you some details about a food item:

enum food_type {
  FRUIT,
  VEGETABLE,
  MEAT,
  DAIRY
};

struct food {
  double price;
  enum food_type type;
  char *name;
};

The function total_price_of_food_type is given an array of food structs, where each struct contains:

Add code to the function total_price_of_food_type, so that it returns the total price of all food items in the array that match the specified type.

For example, if the array of food structs contains the following:

{
  { .price = 1.50, .type = FRUIT, .name = "Apple"},
  { .price = 2.75, .type = VEGETABLE, .name = "Broccoli"},
  { .price = 3.00, .type = FRUIT, .name = "Banana"}
}

Calling total_price_of_food_type(foods, 3, FRUIT) should return 4.50, because the total price of all fruit items (Apple and Banana) is 4.50.

// Pantea Aria
// 18/07/2024

enum food_type {
    FRUIT,
    VEGETABLE,
    MEAT,
    DAIRY
};

struct food {
    double price;
    enum food_type type;
    char *name;
};

double total_price_of_food_type(struct food foods[], int n, enum food_type type) {
    double total_price = 0.0;

    for (int i = 0; i < n; i++) {
        if (foods[i].type == type) {
            total_price += foods[i].price;
        }
    }

    return total_price;
}


Linked Lists

Note list_ordered_insert.c uses the following familiar data type:

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

ordered_insert is given two parameters: a list that is sorted in ascending order (smallest to largest), and a value to insert into the list. ordered_insert should create a new node that contains this value and insert it into the list, such that it remains in ascending order.

// ordered_insert should create a new node with the specified value,
// and add it to the list such that the list remains in ascending order.
//
// ordered_insert should return the head of the list.
struct node *ordered_insert(struct node *head, int value) {

    // PUT YOUR CODE HERE (change the next line!)
    return NULL;
}

ordered_insert should return the head of the list.

Examples

For example, if the list was

1 -> 3 -> 4 -> 5 -> X
And the value to be inserted was 2, ordered_insert should create a new node containing the value 2 and insert it into the list between the (1) and (3) nodes.

ordered_insert should return a pointer to the first node in the list, as this is still the head of the list (the head was not changed).

The list should then look like:

1 -> 2 -> 3 -> 4 -> 5 -> X


As another example, if the list was empty:
X
And the value to be inserted was 10, ordered_insert should create a new node containing the value 10 and insert it into the list.

ordered_insert should return a pointer to the new node that was created, as it is now the head of the list.

The list should then look like:

10 -> X
struct node *ordered_insert(struct node *head, int value) {
    struct node *new_node = malloc(sizeof(struct node));
    new_node->data = value;
    
    struct node *prev = NULL;
    struct node *curr = head;
    while (curr != NULL && curr->data < value) {
        prev = curr;
        curr = curr->next;
    }
    
    if (prev == NULL) {
        // inserting at head
        new_node->next = head;
        head = new_node;
    } else {
        prev->next = new_node;
        new_node->next = curr;
    }
    
    return head;
}


Debugging

This program 'won't work'. What's wrong with it? Split off into groups and discuss why. Line numbers are included for reference.
 
1  #include <stdio.h>
2  #include <stdlib.h>
3  
4  // definition for individual bus
5  struct bus {
6      int route_number;
7      struct next_buses *next_bus;
8  };
9  
10 // creates new bus node
11 struct bus *create_bus(int route_number) {
12     struct bus *new_node = malloc(sizeof(struct bus));
13     new_node->route_number = route_number;
14     new_node->next_bus;
15 
16     return new_node;
17 }
18 
19 // What's my bus route again? I think 390X is one of them...
20 // NOTE: argv is given as a stack, i.e. argv[1] is the last bus
21 int main(char *argc[], int argv) {
22     // create bus route from argv
23     struct bus *head = NULL;
24     int counter = 0;
25     while (counter < argc) {
26         struct bus *new_bus = create_bus(argv[counter]);
27         head = new_bus;
28         
29         counter++;
30     }
31 
32     if (head == NULL) {
33         // (1) if no bus route given, i am already home
34         printf("Wait, I'm already home!\n");
35 
36     } else {
37         // (2) if bus route exists, print out bus route
38         printf("To get home, I need to take: ");
39         
40         // iterate over bus route
41         struct bus *current = head;
42         while (current == NULL) {
43             printf("%d -> ", current->route_number);
44             current->next_bus = current;
45         }
46         printf("Home!\nWow, that's a long bus ride!\n");
47     }
48 
49 
50     // To test your program, run: ./program_name 348 370 390X
51     //     Your output should be:
52     //                  To get home, I need to take: 390X -> 370 -> 348 -> Home!
53     //                  Wow, that's a long bus ride!
54     return 0;
55 }
Here is a version without line numbers for easy copying:
 
#include <stdio.h>
#include <stdlib.h>

// definition for individual bus
struct bus {
    int route_number;
    struct next_buses *next_bus;
};

// creates new bus node
struct bus *create_bus(int route_number) {
    struct bus *new_node = malloc(sizeof(struct bus));
    new_node->route_number = route_number;
    new_node->next_bus;

    return new_node;
}

// What's my bus route again? I think 390X is one of them...
// NOTE: argv is given as a stack, i.e. argv[1] is the last bus
int main(char *argc[], int argv) {
    // create bus route from argv
    struct bus *head = NULL;
    int counter = 0;
    while (counter < argc) {
        struct bus *new_bus = create_bus(argv[counter]);
        head = new_bus;
        
        counter++;
    }

    if (head == NULL) {
        // (1) if no bus route given, i am already home
        printf("Wait, I'm already home!\n");

    } else {
        // (2) if bus route exists, print out bus route
        printf("To get home, I need to take: ");
        
        // iterate over bus route
        struct bus *current = head;
        while (current == NULL) {
            printf("%d -> ", current->route_number);
            current->next_bus = current;
        }
        printf("Home!\nWow, that's a long bus ride!\n");
    }


    // To test your program, run: ./program_name 348 370 390X
    //     Your output should be:
    //                  To get home, I need to take: 390X -> 370 -> 348 -> Home!
    //                  Wow, that's a long bus ride!
    return 0;
}
You may want to try running this program when you are finished debugging it! The output may not be your first thoughts!

Sample solution for good_code.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_NUM_LEN 100

// definition for individual bus
struct bus {
    char route_number[MAX_NUM_LEN];
    struct bus *next_bus;
};

// creates new bus node
struct bus *create_bus(char *route_number) {
    struct bus *new_node = malloc(sizeof(struct bus));
    strcpy(new_node->route_number, route_number);
    new_node->next_bus = NULL;

    return new_node;
}

// What's my bus route again? I think 390X is one of them...
// NOTE: argv is given as a stack, i.e. argv[1] is the last bus
int main(int argc, char *argv[]) {
    // create bus route from argv
    struct bus *head = NULL;
    int counter = 1;
    while (counter < argc) {
        struct bus *new_bus = create_bus(argv[counter]);
        new_bus->next_bus = head;
        head = new_bus;
        
        counter++;
    }

    if (head == NULL) {
        // (1) if no bus route given, i am already home
        printf("Wait, I'm already home!\n");

    } else {
        // (2) if bus route exists, print out bus route
        printf("To get home, I need to take: ");
        
        // iterate over bus route
        struct bus *current = head;
        while (current != NULL) {
            printf("%s -> ", current->route_number);
            current = current->next_bus;
        }
        printf("Home!\nWow, that's a long bus ride!\n");
    }

    return 0;
}