Programming Fundamentals

Information

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

Exercise
(●●◌)
:

Draw a triangle

Write a program called hollow_triangle.c that reads an integer n from standard input. and prints a pattern of asterisks forming a hollow triangle.

You can assume n is greater than 3.

Make your program match the examples below exactly.

Note: you are not permitted to use an array in this exercise.

Examples

dcc hollow_triangle.c -o hollow_triangle
./hollow_triangle 
Enter size: 4
*
**
* *
****
./hollow_triangle 
Enter size: 5
*
**
* *
*  *
*****
./hollow_triangle
Enter size: 8
*
**
* *
*  *
*   *
*    *
*     *
********
./hollow_triangle
Enter size: 11
*
**
* *
*  *
*   *
*    *
*     *
*      *
*       *
*        *
***********

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

1511 autotest hollow_triangle
Sample solution for hollow_triangle.c
// Written 14/3/2018 by Andrew Taylor (andrewt@unsw.edu.au)
// as a test for COMP1511

// Print a hollow triangle

#include <stdio.h>

int main(void) {

    int size;
    printf("Enter size: ");
    scanf("%d", &size);

    int row = 1;
    while (row <= size) {
        int col = 1;
        while (col <= row) {
            // row == size gives horizontal line
            // row == col gives diagonal line
            // col == 1 gives vertical line
            if (row == size || col == 1 || row == col) {
                printf("*");
            } else {
                printf(" ");
            }
            col = col + 1;
        }
        printf("\n");
        row = row + 1;
    }

    return 0;
}

Exercise
(●●◌)
:

Draw an X

Write a program called x.c that reads an integer n from standard input, and prints an nxn pattern of asterisks and dashes in the shape of an "X".

You can assume n is odd and &gt;= 5.

Make your program match the examples below exactly.

This exercise is designed to give you practice with while loops, if statements and some mathematical operators.

You are not permitted to use an array in this exercise.

Examples

dcc x.c -o x
./x
Enter size: 5
*---*
-*-*-
--*--
-*-*-
*---*
./x
Enter size: 9
*-------*
-*-----*-
--*---*--
---*-*---
----*----
---*-*---
--*---*--
-*-----*-
*-------*
./x
Enter size: 15
*-------------*
-*-----------*-
--*---------*--
---*-------*---
----*-----*----
-----*---*-----
------*-*------
-------*-------
------*-*------
-----*---*-----
----*-----*----
---*-------*---
--*---------*--
-*-----------*-
*-------------*

Assumptions/Restrictions/Clarifications

  • You may assume that you will be given only integers as input
  • You may assume that all input is valid

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

1511 autotest x
Sample solution for x.c
// Written 14/3/2018 by Andrew Taylor (andrewt@unsw.edu.au)
// as a lab example for COMP1511

// Print an nxn "x" pattern of asterisks and spaces
//
// For example here is the output for n == 9
//
// *-------*
// -*-----*-
// --*---*--
// ---*-*---
// ----*----
// ---*-*---
// --*---*--
// -*-----*-
// *-------*

#include <stdio.h>

int main(void) {
    int size, n_numbers_read;
    int row, column;

    printf("Enter size: ");
    n_numbers_read = scanf("%d", &size);

    if (n_numbers_read != 1) {
        // scanf failed to read a number
        return 1;
    }

    if (size < 5 || size % 2 != 1) {
        printf("Error: size has to be odd and >= 5.\n");
        return 1;
    }

    row = 0;
    while (row < size) {
        column = 0;
        while (column < size) {
            if (row == column || row == size - (column + 1)) {
                printf("*");
            } else {
                printf("-");
            }
            column = column + 1;
        }
        printf("\n");
        row = row + 1;
    }

    return 0;
}

Exercise
(●●◌)
:

Perfect Square Numbers

There is no starter code provided for this exercise. Instead, you have to write 2 functions from scratch.

You must implement the following two functions:

  1. is_perfect_square, which takes in

    • an int parameter and
    • returns 1 if that integer is a perfect square number, or 0 otherwise.
  2. count_perfect_squares, which takes in 2 parameters:

    • The first parameter is an integer, which contains the length of the array.
    • The second parameter is an array of integers.
    • The order of these parameters is important.
    • Your first parameter must be an int and your second parameter must be an array.
    • This function should return the total number of perfect squares contained in the array.

For more information about perfect_squares see this link

You may name the function parameters what ever you like.

You may create a main function to test your functions, but this will not be assessed. Your functions will be called directly in automarking.

Assumptions/Restrictions/Clarifications

  • Your program is not required to do any error checking
  • Your functions may use any parameter names you chose, but the name of the functions and order of parameters must match what is described above
  • You must not modify the array within the count_perfect_squares function
  • The array will be fully initialised
  • You can assume length will be at least 0

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

1511 autotest perfect_square
Sample solution for perfect_square.c
// This program was written by YOUR-NAME-HERE (zXXXXXXX)
// on INSERT-DATE-HERE

#include <stdio.h>

#define MAX_SIZE 100

int is_perfect_square(int n) {

    int i = 0;
    while (i * i < n) {
        i++;
    }

    if (i * i == n) {
        return 1;
    }

    return 0;
}

int count_perfect_squares(int length, int array[]) {
    int count = 0;
    for (int i = 0; i < length; i++) {
        if (is_perfect_square(array[i])) {
            count++;
        }
    }

    return count;
}

int main(void) {

    int size;
    scanf("%d", &size);

    int array[MAX_SIZE];

    for(int i = 0; i < size; i++) {
        scanf("%d", &array[i]);
        if (is_perfect_square(array[i])) {
            printf("%d is a perfect square\n", array[i]);
        } else {
            printf("%d is not a perfect square\n", array[i]);
        }
    }


    printf("number of perfect squares: %d\n", 
           count_perfect_squares(size, array));
    return 0;
}

Exercise
(●●◌)
:

Swap the case of letters in a string.

Download swap_case.c here

Or, copy these file(s) to your CSE account using the following command:

1511 fetch-activity swap_case

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

int swap_case(int character) {
    // TODO: Write this function, which should:
    //  - return character in lower case if it is an upper case letter
    //  - return character in upper case if it is an lower case letter
    //  - return the character unchanged otherwise

    return 'x';
}

Edit the C program swap_case.c (linked above) which reads characters from its input and writes the same characters to its output with lower case letters converted to upper case and upper case letters converted to lower case.

Your program should stop only at the end of input.

which:

  • returns the character in lowercase if it is an uppercase letter
  • returns the character in uppercase if it is a lowercase letter
  • returns the character unchanged otherwise

Note: Your program will not pass autotests if it does not contain this function.

Examples

dcc swap_case.c -o swap_case
./swap_case
Are you saying 'Boo' or 'Boo-Urns'?
aRE YOU SAYING 'bOO' OR 'bOO-uRNS'?
In this house, we obey the laws of thermodynamics!
iN THIS HOUSE, WE OBEY THE LAWS OF THERMODYNAMICS!
UPPER !@#$% lower
upper !@#$% LOWER

Assumptions/Restrictions/Clarifications

  • You need only a single int variable. Don't use an array.
  • Make sure you understand this example program which reads characters until end of input.
  • Make sure you understand this example program which reads characters, printing them with lower case letters converted to uppercase.

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

1511 autotest swap_case
Sample solution for swap_case.c
//  Written 3/3/2018 by Andrew Taylor (andrewt@unsw.edu.au)
//  Write stdin to stdout with upper case letters converted to lower case
// and lower case converted to upper case
//

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

int swap_case(int character);

int main(int argc, char *argv[]) {
    int character = getchar();
    while (character != EOF) {
        int swapped_character = swap_case(character);
        putchar(swapped_character);
        character = getchar();
    }

    return 0;
}


int swap_case(int character) {
    if (character >= 'A' && character <= 'Z') {
        return 'a' + character - 'A';
    } else if (character >= 'a' && character <= 'z') {
        return 'A' + character - 'a';
    } else {
        return character;
    }
}

Exercise
(●●◌)
:

Calculate the dot product of two arrays.

Download dot_product.c here

Or, copy these file(s) to your CSE account using the following command:

1511 fetch-activity dot_product

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

// Calculates the dot product of two arrays of the same length.
//
// Parameters:
//  `length`: the length of both arrays
//  `vector1`: The first array
//  `vector2`: The second array
//
// Returns: the dot product of `vector1` and `vector2`.
int dot_product(int length, int vector1[], int vector2[]) {
    // TODO: Complete this function
}

This function takes in two arrays and returns their dot product.

To calculate the dot product of two arrays (v1 and v2) of length n we use the formula

(v1 . v2) = v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + ... + v1[n - 1] * v2[n - 1]

For more information about the dot product see this link

Once your program is working, the output from the provided main function should be:

dcc -o dot_product dot_product.c 
./dot_product 
Result: 106
Result2: -8

Assumptions/Restrictions/Clarifications

  • Your program is not required to do any error checking
  • You must not modify the arrays within the dot_product function.
  • Both arrays will be fully initialised
  • You can assume length will be greater than 0

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

1511 autotest dot_product
Sample solution for dot_product.c
// This program was written by YOUR-NAME-HERE (zXXXXXXX)
// on INSERT-DATE-HERE

#include <stdio.h>

int dot_product(int length, int vector1[], int vector2[]);

// This is a simple main function that you can use to test your array_sum_prod
// function.
// It will not be marked - only your function will be marked.
//
// Note: the autotest does not call this main function!
// It calls your function directly.
// Any changes that you make to this main function will not affect the autotests.
int main(void) {

    //Feel free to modify any of these tests.
    int test_vector1[] = {5, 10, 3};
    int test_vector2[] = {5, 3, 17};
    int test_vector3[] = {-5, 0, 1};

    int result = dot_product(3, test_vector1, test_vector2);

    printf("Result: %d\n", result);

    int result2 = dot_product(3, test_vector2, test_vector3);

    printf("Result2: %d\n", result2);

    return 0;
}



// Calculates the dot product of two arrays of the same length.
//
// Parameters:
//  `length`: the length of both arrays
//  `vector1`: The first array
//  `vector2`: The second array
//
// Returns: the dot product of `vector1` and `vector2`.
int dot_product(int length, int vector1[], int vector2[]) {
    int result = 0;
    for (int i = 0; i < length; i++) {
        result += vector1[i] * vector2[i];
    }

    return result;
}

Exercise
(●●◌)
:

Find largest value in a 2d array.

Download array_2d_max.c here

Or, copy these file(s) to your CSE account using the following command:

1511 fetch-activity array_2d_max

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

// Return the largest number in a 2D square array
// with sides of length side_length.
int array_max(int array[TEST_ARRAY_SIZE][TEST_ARRAY_SIZE], int side_length) {
    // PUT YOUR CODE HERE (you must change the next line!)
    return 42;
}

You are to implement the array_2d_max function which should return the largest value in the array.

The file array_2d_max.c contains a main function which tests it against an array you have been given.

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

1511 autotest array_2d_max
Sample solution for array_2d_max.c
#include <stdio.h>
#define TEST_ARRAY_SIZE 100

// Return the number of "small" values in a square 2D array
// with sides of length side_length.
// A "small" value is greater than -10 and less than +10.
int array_max(int array[TEST_ARRAY_SIZE][TEST_ARRAY_SIZE], int side_length) {
    // PUT YOUR CODE HERE (you must change the next line!)
    int max = array[0][0];
    int i = 0;
    while (i < side_length) {
        int j = 0;
        while (j < side_length) {
            if (array[i][j] > max) {
                max = array[i][j];
            }
            j++;
        }
        i++;
    }
    return max;
}

// This is a simple main function which could be used
// to test your array_max function.
// It will not be marked.

int main(void) {
    int test_array[TEST_ARRAY_SIZE][TEST_ARRAY_SIZE] = {
        { 1,    2,   3,    4  },
        {-1,  -11, -111, -111},
        { 0,   0,   0,    0  },
        { 22, -22,  2,    2  }
    };

    int result;

    result = array_max(test_array, 1);
    printf("Largest value in 1x1 array: %d\n", result);

    result = array_max(test_array, 2);
    printf("Largest value in 2x2 array: %d\n", result);

    result = array_max(test_array, 3);
    printf("Largest value in 3x3 array: %d\n", result);

    result = array_max(test_array, 4);
    printf("Largest value in 4x4 array: %d\n", result);

    return 0;
}

Exercise
(●●◌)
:

Finding Treasure

Download find_treasure.c here

Or, copy these file(s) to your CSE account using the following command:

1511 fetch-activity find_treasure

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

// Finds the location of the 'X' in the 2d array.
//
// Parameters:
//  `map`: a 2d array of chars which contains at most one 'X'.
//  `row_pointer`: A pointer to an integer. 
//      If the map contains an 'X', this pointer should be used to set the 
//      integer to the row number of the 'X'.
//  `col_pointer`: A pointer to an integer. 
//      If the map contains an 'X', this pointer should be used to set the 
//      integer to the column number of the 'X'.
//
// Returns: 1 if the treasure was found, 0 otherwise
int find_treasure(char map[SIZE][SIZE], int *row_pointer, int *col_pointer) {
    // TODO: Complete this function
}

This function should try to find the location of the treasure ('X') in the 2D array map.

If map contains the 'X', then the function should use the row_pointer and col_pointer to write the row and column numbers of the treasure into the integers that they point to.

The function should return a 1 if map contained the treasure, or 0 otherwise.

For reference, the location row == 0, col == 0 is the top left corner of the map.

Once your program is working, the output from the provided main function should be:

dcc find_treasure.c -o find_treasure
./find_treasure
Treasure was found at coordinates (5, 2)!

Assumptions/Restrictions/Clarifications

  • Your program is not required to do any error checking
  • You must not modify the array within the find_treasure function
  • You can assume that the map will be fully initialised, and will contain at most 1 'X'

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

1511 autotest find_treasure
Sample solution for find_treasure.c
// This program was written by YOUR-NAME-HERE (zXXXXXXX)
// on INSERT-DATE-HERE

#include <stdio.h>

#define SIZE 7
#define TRUE 1
#define FALSE !TRUE

int find_treasure(char map[SIZE][SIZE], int *row_pointer, int *col_pointer);

// This is a simple main function that you can use to test your function.
// It will not be marked - only your function will be marked.
//
// Note: the autotest does not call this main function!
// It calls your function directly.
// Any changes that you make to this main function will not affect the autotests.
int main(void) {

    //Feel free to modify the treasure map to test your code:
    char treasure_map[SIZE][SIZE] = {
        {'O', 'O', 'O', 'O', 'O', 'O', 'O'},
        {'O', 'O', 'O', 'O', 'O', 'O', 'O'},
        {'O', 'O', 'O', 'O', 'O', 'O', 'O'},
        {'O', 'O', 'O', 'O', 'O', 'O', 'O'},
        {'O', 'O', 'O', 'O', 'O', 'O', 'O'},
        {'O', 'O', 'X', 'O', 'O', 'O', 'O'},
        {'O', 'O', 'O', 'O', 'O', 'O', 'O'},
    };

    int row;
    int col;

    //Pass in the address of the row and column variables
    int contains_treasure = find_treasure(treasure_map, &row, &col);

    if (contains_treasure) {
        printf("Treasure was found at coordinates (%d, %d)!\n", row, col);
    } else {
        printf("The map contained no treasure :(\n");
    }
   
    return 0;
}



// Finds the location of the 'X' in the 2d array.
//
// Parameters:
//  `map`: a 2d array of chars which contains at most one 'X'.
//  `row_pointer`: A pointer to an integer. 
//      If the map contains an 'X', this pointer should be used to set the 
//      integer to the row number of the 'X'.
//  `col_pointer`: A pointer to an integer. 
//      If the map contains an 'X', this pointer should be used to set the 
//      integer to the column number of the 'X'.
//
// Returns: 1 if the treasure was found, 0 otherwise
int find_treasure(char map[SIZE][SIZE], int *row_pointer, int *col_pointer) {

    int treasure_was_found = FALSE;

    for (int row = 0; row < SIZE; row++) {
        for (int col = 0; col < SIZE; col++) {
            if (map[row][col] == 'X') {
                *row_pointer = row;
                *col_pointer = col;
                treasure_was_found = TRUE;
            }
        }
    }

    return treasure_was_found;
}