Q1
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
struct node {
struct node *next;
int data;
};
// Check if something is prime
int is_prime(int value) {
if (value <= 1) {
return 0;
}
for (int i = 2; i < value; i++) {
if (value % i == 0) {
return 0;
}
}
return 1;
}
// first_prime should return the first prime number in the given linked list
int first_prime(struct node *head) {
struct node *current = head;
//int prime = -1;
while (current != NULL) {
if (is_prime(current->data)) {
return current->data;
}
current = current->next;
}
return -1;
}
////////////////////////////////////////////////////////////////////////
// DO NOT CHANGE THE CODE BELOW //
////////////////////////////////////////////////////////////////////////
int first_prime(struct node *head);
struct node *strings_to_list(int len, char *strings[]);
// DO NOT CHANGE THIS MAIN FUNCTION
int main(int argc, char *argv[]) {
// create linked list from command line arguments
struct node *head = strings_to_list(argc - 1, &argv[1]);
// If you're getting an error here,
// you have returned an uninitialized value
printf("%d\n", first_prime(head));
return 0;
}
// DO NOT CHANGE THIS FUNCTION
// create linked list from array of strings
struct node *strings_to_list(int len, char *strings[]) {
struct node *head = NULL;
for (int i = len - 1; i >= 0; i = i - 1) {
struct node *n = malloc(sizeof (struct node));
assert(n != NULL);
n->next = head;
n->data = atoi(strings[i]);
head = n;
}
return head;
}
Q2
#include <stdio.h>
#define MAX_COLS 100
char min_lowercase(int size, char array[MAX_COLS]);
// This is a simple main function which could be used
// to test your min_lowercase function.
// It will not be marked.
// Only your min_lowercase function will be marked.
int main(int argc, char *argv[]) {
char test_array[MAX_COLS] = {'a', 'B', 'c', 'D', '!'};
int result = min_lowercase(5, test_array);
printf("%c\n", result);
return 0;
}
// Returns the lowercase character with the lowest ASCII value from the array.
char min_lowercase(int size, char array[MAX_COLS]) {
char min_letter = 'z';
for (int i = 0; i < size; i++) {
if (array[i] >= 'a' && array[i] <= 'z' && array[i] < min_letter) {
min_letter = array[i];
}
}
return min_letter;
}
Q3
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
// DO NOT MODIFY THIS STRUCT
struct node {
struct node *next;
int data;
};
////////////////////////////////////////////////////////////////////////////////
// DO NOT CHANGE THESE FUNCTION PROTOTYPES
////////////////////////////////////////////////////////////////////////////////
struct node *delete_nth_even(struct node *head, int n);
struct node *strings_to_list(int len, char *strings[]);
void print_list(struct node *head);
void free_list(struct node *head);
int list_length(struct node *head);
///////////////////////////////////////////////////////////////////////////////
// DO NOT EDIT MAIN
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[]) {
// create linked list from command line arguments
int n = atoi(argv[1]);
struct node *head = strings_to_list(argc - 2, &argv[2]);
struct node *new_head = delete_nth_even(head, n);
print_list(new_head);
free_list(new_head);
return 0;
}
//##############################################################################
// TODO: IMPLEMENT THIS FUNCTION
//##############################################################################
// This function should delete the even node at position n from the start of the list.
struct node *delete_nth_even(struct node *head, int n) {
if (head == NULL) {
return head;
}
struct node *prev = NULL;
struct node *curr = head;
int even_total = 0;
int even_count = 0;
while (curr != NULL) {
if (curr->data % 2 == 0) {
even_total++;
}
curr = curr->next;
}
curr = head;
// iterate till you either find the target node or the end of the list
while (curr != NULL) {
if (curr->data % 2 == 0) {
even_count++;
if ((n > list_length(head) || n > even_total)&& even_count == 1) {
// delete first even
if (prev == NULL) {
head = curr->next;
} else {
prev->next = curr->next;
}
free(curr);
return head;
}
if (even_count == n) {
if (prev == NULL) {
head = curr->next;
} else {
prev->next = curr->next;
}
free(curr);
return head;
}
}
prev = curr;
curr = curr->next;
}
return head;
}
int list_length(struct node *head) {
int length = 0;
for (struct node *curr = head; curr != NULL; curr = curr->next) {
length++;
}
return length;
}
////////////////////////////////////////////////////////////////////////////////
// DO NOT CHANGE BELOW HERE INCLUDING THIS FUNCTION OR THE FUNCTIONS BELOW
////////////////////////////////////////////////////////////////////////////////
// create linked list from array of strings
struct node *strings_to_list(int len, char *strings[]) {
struct node *head = NULL;
for (int i = len - 1; i >= 0; i = i - 1) {
struct node *n = malloc(sizeof (struct node));
assert(n != NULL);
n->next = head;
n->data = atoi(strings[i]);
head = n;
}
return head;
}
// print linked list
void print_list(struct node *head) {
printf("[");
for (struct node *n = head; n != NULL; n = n->next) {
// If you're getting an error here,
// you have returned an invalid list
printf("%d", n->data);
if (n->next != NULL) {
printf(", ");
}
}
printf("]\n");
}
// free linked list
void free_list(struct node *head) {
struct node *curr = head;
while (curr != NULL) {
struct node *temp = curr;
curr = curr->next;
free(temp);
}
}
Q4
// Written by Jake Renzella
#include <stdio.h>
#define MAX_ROWS 100
int vowels_exactly_balanced(int size, char *array[MAX_ROWS]);
// This is a simple main function which could be used
// to test your vowels_exactly_balanced function.
// It will not be marked.
// Only your count_neutral_rows function will be marked.
int main(int argc, char *argv[]) {
char *test_arrray[MAX_ROWS] = {
"abUUcd",
"abcdUU",
"Abaa",
"asdaa",
};
char *test_arrray_2[MAX_ROWS] = {
"abcdaa",
"abcda",
"babau",
};
char *test_arr_3[MAX_ROWS] = {
"fgh",
"j",
"zxcvbnm",
};
int result = vowels_exactly_balanced(4, test_arrray);
printf("The vowels_exactly_balanced function returned: %d\n", result);
result = vowels_exactly_balanced(3, test_arrray_2);
printf("The vowels_exactly_balanced function returned: %d\n", result);
result = vowels_exactly_balanced(3, test_arr_3);
printf("%d\n", result);
return 0;
}
int vowels_exactly_balanced(int size, char *array[MAX_ROWS]) {
if (size <= 1) {
// 0 or 1 row is always balanced
return 1;
}
if (size > MAX_ROWS) {
// Error: size exceeds MAX_ROWS
return 0;
}
// Will store the first non-zero vowel count
int target_vowels = -1;
for (int row = 0; row < size; row++) {
int vowels = 0;
for (int col = 0; array[row][col] != '\0'; col++) {
char c = array[row][col];
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
vowels++;
}
}
if (target_vowels == -1) {
if (vowels > 0) {
target_vowels = vowels;
}
} else if (vowels != target_vowels) {
// Imbalance found, early return
return 0;
}
}
return 1; // No imbalances found
}
Q5
// This program scans in an integer representing a month of the year.
// It prints out a message to say what season the month is in Australia.
//
// Unfortunately, this code contains a number of errors. Please help fix it!
#include <stdio.h>
int main(void) {
int month; // BUG #0 - forgot to declare the variable
printf("Enter the month number (1-12): ");
scanf("%d", &month); // Bug #1 - forgot & before month
if (month < 1 || month > 12) { // BUG #1.5 >= 12 instead of > 12
printf("Invalid month entered.\n");
} else if (month >= 3 && month <= 5) { // Bug #2 - use || instead of &&
printf("It's autumn in Australia.\n");
} else if (month >= 6 && month <= 8) {
printf("It's winter in Australia.\n");
} else if (month >= 9 && month <= 11) {
printf("It's spring in Australia.\n");
} else { // Bug #3 - forgot to handle December, January, and February
printf("It's summer in Australia.\n");
}
return 0;
}
Q6
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
////////////////////////////////////////////////////////////////////////////////
// DO NOT MODIFY THIS STRUCT
////////////////////////////////////////////////////////////////////////////////
struct node {
struct node *next;
int data;
};
// only_evens should create a new linked list `only_evens` that contains
// only the even-valued nodes from the original list
// Unfortunately this function contains a number of errors.
// It's your job to fix them, good luck!
struct node *extract_evens(struct node *head) {
struct node *only_evens = NULL;
struct node *current = head;
// BUG: current is missing the last node in the list
while (current != NULL) {
// BUG: next is not a pointer
struct node *next = current->next;
current->next = NULL;
// BUG: Not accessing data field
if (current->data % 2 == 0) {
// BUG: no null check for an empty list
if (only_evens == NULL) {
only_evens = current;
} else {
// BUG: current is not a pointer
struct node *current_evens = only_evens;
// BUG: traversing past the last node
while (current_evens->next != NULL) {
current_evens = current_evens->next;
}
current_evens->next = current;
}
}
current = next;
}
return only_evens;
}
////////////////////////////////////////////////////////////////////////////////
// DO NOT MODIFY THE CODE BELOW THIS LINE, THIS CODE ALLOWS YOU TO
// TAKE IN A LIST OF NUMBERS TO TEST WHETHER YOUR FUNCTION IS WORKING
////////////////////////////////////////////////////////////////////////////////
struct node *strings_to_list(int len, char *strings[]);
void print_list(struct node *head);
////////////////////////////////////////////////////////////////////////////////
// DO NOT MODIFY THIS FUNCTION
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[]) {
struct node *head = strings_to_list(argc - 1, &argv[1]);
struct node *only_evens = extract_evens(head);
if (only_evens == NULL) {
printf("No even nodes\n");
} else {
print_list(only_evens);
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// DO NOT MODIFY THIS FUNCTION
////////////////////////////////////////////////////////////////////////////////
struct node *strings_to_list(int len, char *strings[]) {
struct node *head = NULL;
for (int i = len - 1; i >= 0; i--) {
struct node *n = malloc(sizeof(struct node));
assert(n != NULL);
n->data = atoi(strings[i]);
n->next = head;
head = n;
}
return head;
}
////////////////////////////////////////////////////////////////////////////////
// DO NOT MODIFY THIS FUNCTION
////////////////////////////////////////////////////////////////////////////////
void print_list(struct node *head) {
struct node *current = head;
while (current != NULL) {
printf("%d", current->data);
if (current->next != NULL) {
printf(" ");
}
current = current->next;
}
printf("\n");
}
Q7
// debug points functions gcd
// written by Sofia De Bellis, z5418801
// 30 Mar 2025
#include <stdio.h>
void find_sum_of_square(int n, int *result);
int main(void) {
int n;
int result;
printf("Enter n: ");
// BUG: * used for scanf
scanf("%d", &n);
// BUG: missing & in function call
find_sum_of_square(n, &result);
printf("The sum of squares from 1 to %d is: %d\n", n, result);
return 0;
}
// Function definition
// This function computes the sum of squares from 1 to n
// and stores the result in the variable pointed to by result
void find_sum_of_square(int n, int *result) {
// BUG: sum not initialized
int sum = 0;
// BUG: i should start from 1 not 0
// BUG: should be <= n
for (int i = 1; i <= n; i++) {
// BUG: ^ should be *
sum += i * i;
}
// BUG: result should be dereferenced
*result = sum;
return;
}
Q8
// This program should create and scan in the elements of a 3x3 2d array,
// then multiply all the odd numbers in the 2d array by 100.
//
// Unfortunately, this code contains a number of errors. Please help fix it!
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
int main(void) {
printf("Enter your numbers:\n");
int array[SIZE][SIZE]; // char instead of int
for (int row = 0; row < SIZE; row++) {
for (int col = 0; col < SIZE; col++) { // loop decrements
scanf("%d", &array[row][col]); // %c instead of $d
}
}
for (int row = 0; row < SIZE; row++) {
for (int col = 0; col < SIZE; col++) {
if (array[row][col] % 2 != 0) { // swapped with the line above and [col] is replaced by another [row], and / instead of %
array[row][col] = array[row][col] * 100;
}
}
}
// ==================== DO NOT NEED TO EDIT BELOW HERE =====================
// There are no bugs in here, this is simply to assist in printing out
// the contents of the 2D array
printf("Converted:\n");
for (int row = 0; row < SIZE; row++) {
for (int col = 0; col < SIZE; col++) {
printf("%d ", array[row][col]);
}
printf("\n");
}
return 0;
}
Q9
#include <ctype.h>
#include <stdio.h>
#define MAX_SIZE 100
void increment_after(char string[MAX_SIZE]);
int main(void) {
char string[MAX_SIZE];
printf("Original String: ");
fgets(string, MAX_SIZE, stdin);
increment_after(string);
printf("New String: %s", string);
return 0;
}
void increment_after(char string[MAX_SIZE]) {
int offarray[MAX_SIZE];
for (int i = 0; string[i] ; i++) {
if (!isalpha(string[i])) continue;
int bigger = 0;
for (int j = i + 1; string[j]; j++) {
if (!isalpha(string[j])) continue;
if (tolower(string[i]) < tolower(string[j])) {
bigger++;
}
}
char start = (isupper(string[i]) ? 'A' : 'a');
int offset = ((bigger + string[i] - start));
if (offset > 25) {
offset = 25;
}
offarray[i] = offset;
}
for (int i = 0; string[i]; i++) {
if (!isalpha(string[i])) continue;
string[i] = offarray[i] + (isupper(string[i]) ? 'A' : 'a');
}
}
Q10
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int num_trains_to_target(int **routes, int routes_size, int *routes_col_size, int source, int target);
int main(int argc, char *argv[]) {
int arg_index = 1;
int n = atoi(argv[arg_index++]);
int **routes = malloc(n * sizeof(int *));
int *routes_col_size = malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
routes_col_size[i] = atoi(argv[arg_index++]);
routes[i] = malloc(routes_col_size[i] * sizeof(int));
for (int j = 0; j < routes_col_size[i]; j++) {
routes[i][j] = atoi(argv[arg_index++]);
}
}
int source = atoi(argv[arg_index++]);
int target = atoi(argv[arg_index++]);
int result = num_trains_to_target(routes, n, routes_col_size, source, target);
if (result == -1) {
printf("Stop %d from stop %d is not reachable.\n", target, source);
} else {
printf("The minimum number of trains to travel from stop %d to stop %d is %d.\n", source, target, result);
}
return 0;
}
int num_trains_to_target(int** routes, int routes_size, int* routes_col_size, int source, int target) {
if (source == target) {
return 0;
}
int max_stop = -1;
for (int i = 0; i < routes_size; i++) {
for (int j = 0; j < routes_col_size[i]; j++) {
if (routes[i][j] > max_stop) {
max_stop = routes[i][j];
}
}
}
if (max_stop < target) {
return -1;
}
int n = routes_size;
int *min_trains_to_reach = malloc((max_stop + 1) * sizeof(int));
for (int i = 0; i <= max_stop; i++) {
min_trains_to_reach[i] = n + 1;
}
min_trains_to_reach[source] = 0;
bool flag = true;
while (flag) {
flag = false;
for (int i = 0; i < routes_size; i++) {
int min = n + 1;
for (int j = 0; j < routes_col_size[i]; j++) {
if (min_trains_to_reach[routes[i][j]] < min) {
min = min_trains_to_reach[routes[i][j]];
}
}
min++;
for (int j = 0; j < routes_col_size[i]; j++) {
if (min_trains_to_reach[routes[i][j]] > min) {
min_trains_to_reach[routes[i][j]] = min;
flag = true;
}
}
}
}
int result = (min_trains_to_reach[target] < n + 1) ? min_trains_to_reach[target] : -1;
free(min_trains_to_reach);
return result;
}
Q11
#include <stdio.h>
#include <stdlib.h>
struct node {
int val;
int height;
struct node *left;
struct node *right;
};
int **get_skyline(int **buildings, int buildings_size, int* buildings_col_size, int *return_size, int **return_col_size);
struct node *create_node(int val, int height, struct node* node);
void insert_node(struct node *node, struct node *left, struct node *right);
int main(int argc, char *argv[]) {
// num buildings is argc - program name / 3
int buildings_size = (argc - 1) / 3;
int **buildings = malloc(buildings_size * sizeof(int *));
int *buildings_col_size = malloc(buildings_size * sizeof(int));
// Parse CLAs
for (int i = 0; i < buildings_size; i++) {
buildings[i] = malloc(3 * sizeof(int));
buildings[i][0] = atoi(argv[i * 3 + 1]);
buildings[i][1] = atoi(argv[i * 3 + 2]);
buildings[i][2] = atoi(argv[i * 3 + 3]);
buildings_col_size[i] = 3;
}
int return_size = 0;
int *return_col_size = NULL;
int **result = get_skyline(buildings, buildings_size, buildings_col_size, &return_size, &return_col_size);
printf("Skyline: [");
for (int i = 0; i < return_size; i++) {
if (i == return_size - 1) {
printf("[%d, %d]]\n", result[i][0], result[i][1]);
} else {
printf("[%d, %d], ", result[i][0], result[i][1]);
}
}
return 0;
}
int **get_skyline(int **buildings, int buildings_size, int *buildings_col_size, int *return_size, int **return_col_size) {
// make a new node with x coord as val and height = height if start of the building and 0 or height of next one
// insert a node between two others
int left, right, height;
int n = buildings_size;
if (n < 1){
printf("Less then 1 building\n");
return NULL;
}
//get memory for all nodes x2 buildings
struct node *base = malloc((n * 2) * sizeof(struct node));
struct node *p, *new_left, *new_right;
p = base;
struct node* end_left = create_node(buildings[0][0], buildings[0][2], p++);
struct node* end_right = create_node(buildings[0][1], 0, p++);
end_left->right = end_right;
end_right->left = end_left;
for(int i = 1; i < n; i++){
left = buildings[i][0];
right = buildings[i][1];
height = buildings[i][2];
new_left = NULL;
new_right = NULL;
// searching for place
while (end_right->right && end_right->val <= left) end_right = end_right->right;
// left is in open space
if (!end_right->right && left >= end_right->val){
new_right = create_node(right, 0, p++);
if (end_right->val == left) {
if (height == end_right->left->height) {
new_left = end_right->left;
}
else {
end_right->height = height;
new_left = end_right;
}
}
else {
new_left = create_node(left, height, p++);
end_right->right = new_left;
new_left->left = end_right;
}
new_left->right = new_right;
new_right->left = new_left;
end_left = new_left;
end_right = new_right;
continue;
}
end_left = end_right->left;
// left == old left
if (left == end_left->val){
// new height is higher or same
if (end_left->height <= height){
//there is a point to the left from end_left and it's height is equal
if (end_left->left && end_left->left->height == height){
new_left = end_left->left;
}
// there is no left to the end_left or it's hight != height
else {
new_left = end_left;
new_left->height = height;
}
}
}
// if hights is equal and left is between end_l and end_r
else if (height == end_left->height){
new_left = end_left;
}
// higher
else if (height > end_left->height){
new_left = create_node(left, height, p++);
new_left->left = end_left;
end_left->right = new_left;
}
//lower -> need to find where to start from
if (!new_left){
//scanning down the new "roof"
while (end_right->right && right > end_right->val && height < end_right->height) {
end_right = end_right->right;
}
//end of new building no lower ones found
if (right <= end_right->val){
end_right = end_left->right;
continue;
}
//end of all old buildings
if (!end_right->right){
new_right = create_node(right, 0, p++);
end_right->height = height;
end_right->right = new_right;
new_right->left = end_right;
end_right = end_left->right;
continue;
}
new_left = end_right;
// confined to one cell
if (right < end_right->right->val) {
new_right = create_node(right, end_right->height, p++);
new_left->height = height;
insert_node(new_right, new_left, end_right->right);
end_right = end_left->right;
continue;
}
new_left->height = height;
}
// suppose to have a new_left node for all possible cases by now
if (!new_left){
printf("Error new_left node hasn't been defined\n");
free(base);
exit(1);
}
// searching for a place for new_right node, deleting everything between new_left and new_right
while (end_right->right && right >= end_right->val) {
end_right = end_right->right;
}
if (right < end_right->val){
new_right = create_node(right, end_right->left->height, p++);
insert_node(new_right, new_left, end_right);
} else {
new_right = create_node(right, 0, p++);
new_left->right = new_right;
new_right->left = new_left;
}
if (new_left->height > end_left->height) {
end_left = new_left;
}
end_right = end_left->right;
}
struct node* start = NULL;
// finding the start of Llist
while (end_left->left) {
end_left = end_left->left;
}
start = end_left;
if (!start) {
printf("Error: start node is NULL\n");
free(base);
exit(1);
}
int ret_len = 1;
while (end_left->right){
ret_len++;
end_left = end_left->right;
}
int **result = malloc(ret_len * sizeof(int*));
result[0] = malloc(ret_len * 2 * sizeof(int));
for (int i = 1; i < ret_len; i++) result[i] = result[0] + (i * 2);
end_left = start;
for (int i = 0; i < ret_len; i ++){
result[i][0] = end_left->val;
result[i][1] = end_left->height;
end_left = end_left->right;
}
*return_size = ret_len;
free(base);
*return_col_size = malloc(sizeof(int) * (*return_size));
for (int i = 0 ; i < *return_size ; i++){
(*return_col_size)[i] = 2;
}
return result;
}
struct node *create_node(int val, int height, struct node* node) {
node->val = val;
node->height = height;
node->right = NULL;
node->left = NULL;
return node;
}
void insert_node(struct node* node, struct node* left, struct node* right){
left->right = node;
node->left = left;
right->left = node;
node->right = right;
return;
}