Programming Fundamentals

Objectives

  • creating functions
  • manipulating 2D arrays
  • scanning until ctrl-d
  • basic string manipulation

Feedback Week!

In this week's lab, your tutors will go around the class and give you one on one feedback on some code you've written in a previous week.

This is also an opportunity for you to ask any questions you might have about the course content so far!

So, if you'd like, have a think about if there's any particular exercise you'd like to receive feedback for, or any particular content you'd like to ask about.

Reminder: Help sessions

Help sessions are running this week!

These are one of the best ways for you to get one on one help with a tutor for any course content (including Lab Exercises and Assignments).

For the dates and times of the help sessions, see the Help Session Timetable.

To join a help session, or for more information, see the COMP1511 Help Session Microsoft Teams.

For face-to-face help sessions, the lab map can be found Here.

Activities To Be Completed

The following is a list of all the activities available to complete this week...

Worth 1 mark(s) in total:

  • word_square
  • alternating_case
  • simple_snake

Worth 1 mark(s) in total:

  • weather_prediction
  • advanced_addition

Worth 0.5 mark(s) in total:

  • remove_duplicates_function
  • largest_z_sum

For your interest, but not for marks:

  • p1511

Problem sets are capped at 15 marks (there are 4 possible bonus marks from the three-dot exercises that can bring you up to a total of 15 if you missed out on any other marks in the one- or two-dot exercises).

Completing just the one and two-dot exercises every week can give you the full 15 marks needed in this component.

For more details, see the course outline.

Preparation

Before the lab you should re-read the relevant lecture slides and their accompanying examples.

When attempting the following exercises, make sure to read the whole exercise, including any hints and assumptions that may make the exercise easier.

Exercise
(●◌◌)
:

Word Square

Write a program called word_square.c that prompts the user to enter a word, and afterwards, prints that word out n amount of times, where n is the length of the word.

You should use the function fgets to scan in the input word.

./word_square
Input word: a

Word square is:
a
./word_square
Input word: word

Word square is:
word
word
word
word
./word_square
Input word: abrakadabra

Word square is:
abrakadabra
abrakadabra
abrakadabra
abrakadabra
abrakadabra
abrakadabra
abrakadabra
abrakadabra
abrakadabra
abrakadabra
abrakadabra
You can assume that you will be given a word no longer than 1024 character (Including the null-terminator).
You can run an automated code style checker using the following command:
1511 style word_square.c

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

1511 autotest word_square

When you are finished working on this exercise, you and your lab partner must both submit your work by running give:

give cs1511 lab05_word_square word_square.c

Note, even though this is a pair exercise, you both must run give from your own account before Monday 27 March 20:00 to obtain the marks for this lab exercise.

Exercise
(●◌◌)
:

Modifying the case of letters in a string.

Complete the C program, alternating_case.c.

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

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

The main function has already been written for you. You must not modify it in any way.

Your job is to implement the function void make_alternating(char string[MAX_STRING_LENGTH]);.

This function takes in a string, and should modify it so that the first letter is lowercase, and the case of each following letter alternates.

In other words, the string should be modified so that:

  • The first letter is lowercase,
  • The second letter is uppercase,
  • The third letter is lowercase,
  • The forth letter is uppercase,
  • etc.

All non letter characters should be left unmodified.

The output from your program should exactly match the following:

./alternating_case
hello
hElLo
./alternating_case
Hello World
hElLo WoRlD
./alternating_case
The quick brown fox jumps over the lazy dog
tHe QuIcK bRoWn FoX jUmPs OvEr ThE lAzY dOg
./alternating_case
a1b2c3e4d5 f6g7
a1B2c3E4d5 F6g7

Assumptions/Restrictions/Hints

  • You can assume the string will contain at most 1024 characters.
You can run an automated code style checker using the following command:
1511 style alternating_case.c

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

1511 autotest alternating_case

When you are finished working on this exercise, you and your lab partner must both submit your work by running give:

give cs1511 lab05_alternating_case alternating_case.c

Note, even though this is a pair exercise, you both must run give from your own account before Monday 27 March 20:00 to obtain the marks for this lab exercise.

Exercise
(●◌◌)
:

Creating a simple Snake game

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

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

Snake is one of the oldest and most famous digital games

The Snake game involves controlling a snake that moves along a 2D plane. The goal is to lead this snake to an apple on the map, that upon eating, increases the length of the snake.

As more apples are eaten, the player must be careful as they move the snake, as the game will end if the snake moves back into their tail.

For this exercise, you will be implementing a simpler version of Snake. This version involves:

  1. Spawning the snake and the apple
  2. Moving the snake up/down/left/right in a loop (using u/d/l/r commands)
  3. Ending the game when the snake reaches the apple

Since this game is fundamentally about moving a snake on a 2D plane, it should make sense to represent this as a 2D array in code. In the starter code provided, you should notice that the first line of code in the main() function defines this array as:

enum land map[SIZE][SIZE];

This means that the map is made up only of values defined in the enum land definition above the main() function.

Let's have a look at what each value in enum land represents:

  • NOT_VISITED - Indicates a land tile that the snake has not visited yet
  • VISITED - Indicates a land tile that the snake has visited
  • SNAKE - The land tile the snake is currently on
  • APPLE - The land tile the apple is currently on

You have been provided a print_map() function that will print the 2D array with the enum land tiles set.

Make sure you understand everything mentioned above before reading the example below!

dcc simple_snake.c -o simple_snake
./simple_snake
Welcome to Snake!
Please enter apple location: 2 3
Please enter snake location: 4 3
. . . . . . . . 
. . . . . . . . 
. . . A . . . . 
. . . . . . . . 
. . . S . . . . 
. . . . . . . . 
. . . . . . . . 
. . . . . . . . 
r
. . . . . . . . 
. . . . . . . . 
. . . A . . . . 
. . . . . . . . 
. . . - S . . . 
. . . . . . . . 
. . . . . . . . 
. . . . . . . . 
u
. . . . . . . . 
. . . . . . . . 
. . . A . . . . 
. . . . S . . . 
. . . - - . . . 
. . . . . . . . 
. . . . . . . . 
. . . . . . . . 
u
. . . . . . . . 
. . . . . . . . 
. . . A S . . . 
. . . . - . . . 
. . . - - . . . 
. . . . . . . . 
. . . . . . . . 
. . . . . . . . 
u
. . . . . . . . 
. . . . S . . . 
. . . A - . . . 
. . . . - . . . 
. . . - - . . . 
. . . . . . . . 
. . . . . . . . 
. . . . . . . . 
l
. . . . . . . . 
. . . S - . . . 
. . . A - . . . 
. . . . - . . . 
. . . - - . . . 
. . . . . . . . 
. . . . . . . . 
. . . . . . . . 
d
. . . . . . . . 
. . . - - . . . 
. . . S - . . . 
. . . . - . . . 
. . . - - . . . 
. . . . . . . . 
. . . . . . . . 
. . . . . . . . 
Chomp!

Assumptions/Restrictions/Clarifications

  • You will always be given snake/apple locations inside the map
  • You will always be given correct direction commands (u/d/l/r)
  • You will never be given commands such that the snake walks off the map
You can run an automated code style checker using the following command:
1511 style simple_snake.c

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

1511 autotest simple_snake

When you are finished working on this exercise, you and your lab partner must both submit your work by running give:

give cs1511 lab05_simple_snake simple_snake.c

Note, even though this is a pair exercise, you both must run give from your own account before Monday 27 March 20:00 to obtain the marks for this lab exercise.

Exercise
(●●◌)
:

Refactoring code

For this activity, you've been provided with a fully working program: weather_prediction.c file.

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

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

While this code produces the correct output, it's been all been implemented in the main function!

Your job is to take this working program, and improve its style by breaking it up into well named functions which are less than 30 lines long. You will also have to pass 1511 style weather_prediction.c, so you will have to write function comments for the functions that you create.

Your changes shouldn't affect the functionality of the program in any way. In other words, they should not change any of the program's behaviour or output.

Program description:

Below is a description of the program. Keep in mind that this has all already been implemented for you, so you don't need to worry about this too much.

The provided program scans in and stores the details 5 sets of days worth of temperature data and 6 days worth of humidity values. Once all details have been scanned in, The program calculates the average of each, and makes some statements based on what it thinks that means for tomorrow's values.

./weather_prediction
Hello and welcome to CS Weather!
=======================================
This program will help you to analyse a given weather patten
and make some predictions about the coming day
Please enter the past 4 day(s) worth of temperatures.
21
22
21
24
Please enter the last 5 days(s) worth of humidities
78
77
79
80
77
The average temperature was: 22.000000
Should be a lovely temperature tomorrow.
The average humidity was: 78.200000
Shouldn't be too humid tomorrow.
You can run an automated code style checker using the following command:
1511 style weather_prediction.c

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

1511 autotest weather_prediction

When you are finished working on this exercise, you and your lab partner must both submit your work by running give:

give cs1511 lab05_weather_prediction weather_prediction.c

Note, even though this is a pair exercise, you both must run give from your own account before Monday 27 March 20:00 to obtain the marks for this lab exercise.

Exercise
(●●◌)
:

Add numbers in an array together, carrying numbers where neccesary.

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

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

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

// Put the sum of the lines in the array into the last line
// accounting for carrying. Return anything you did not carry.
//
// NOTE: num_lines is the number of lines you are adding together. The
// array has an extra line for you to put the result.
int sum(int num_lines, int num_digits, int array[MAX_SIZE][MAX_SIZE]) {
    // Put your code here.
    return 0;
}

You will implement the sum function, which will be given a two-dimensional array with a variable number of rows ("lines") and columns ("digits"), like the following:

When you receive this array, you are guaranteed the last row will be all zeroes. For each column, starting from the right-most digit, you should add every digit in that column, and put the result of that addition into the last row.

An example of the first column is shown below

To simulate real addition, however, none of the values in the array may exceed 9, so you will need to implement "carrying", just like in normal addition. "Carrying" is when all the numbers in a column sum to greater than 9, and you add extra to the next column to keep the current column below 10. For example, the following array:

And then

The sumIn addition, the function will normally return 0. However, if your addition cannot be represented in the array because the last column you add still carries something over, your function should return the amount carried.
For example:

More formally, you should:

  1. Start at the rightmost column of the array.
  2. Add together the integers in that column, as well as anything "carried across".
  3. If the result of that addition would be less than ten, write the result of that addition into the last number in that row. Nothing is carried across.
  4. Otherwise, find the result of the addition modulo 10, and write that into the last value in the column.
  5. Then, divide the result of the addition by 10, and "carry that accross" to the next column.
  6. Repeat on the next column to the next, from step two.
  7. If you reach the leftmost column of the array, and there is still a value "carried across", return it. Otherwise, return zero.

The file advanced_addition.c contains a main function which reads values into a 2D array and calls sum.

Here is how advanced_addition.c should behave after you add the correct code to the function add:

dcc advanced_addition.c -o advanced_addition
./advanced_addition
Enter the number of rows (excluding the last): 3
Enter the number of digits on each row: 3
Enter 2D array values:
1 2 3
4 5 6
0 1 0
5 8 9

./advanced_addition
Enter the number of rows (excluding the last): 4
Enter the number of digits on each row: 2
Enter 2D array values:
1 3
1 3
1 3
1 3
5 2
./advanced_addition
Enter the number of rows (excluding the last): 2
Enter the number of digits on each row: 1
Enter 2D array values:
9
9
8
Carried over: 1
You can run an automated code style checker using the following command:
1511 style advanced_addition.c

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

1511 autotest advanced_addition

When you are finished working on this exercise, you and your lab partner must both submit your work by running give:

give cs1511 lab05_advanced_addition advanced_addition.c

Note, even though this is a pair exercise, you both must run give from your own account before Monday 27 March 20:00 to obtain the marks for this lab exercise.

Exercise
(●●●)
:

Remove any duplicate values from an array and write the result into another array

Write a C function that removes duplicate elements from an array, by copying the non-duplicate values to a second array, i.e. only the first occurrence of any value should be copied.

Place your answer in a file named remove_duplicates_function.c

Your function should take three parameters: the length of source array, the source array itself, and the destination array. It must have this prototype:

int remove_duplicates(int length, int source[length], int destination[length]);

Your function should return a single integer: the number of elements copied to the destination array.

For example if the source array contains these 6 elements:

3, 1, 4, 1, 5, 9

Your function should copy these 5 values to the destination array:

3, 1, 4, 5, 9

Your function should return the integer 5, because there were 5 values copied -- the second occurrence of the digit 1 was not copied.

Assumptions/Restrictions/Clarifications.

You can assume the source array only contains positive integers.

You can assume the source array contains at least one integer.

You can assume that the destination array will always be large enough to fit all of the copied values.

You cannot assume anything about the number of duplicates, i.e. there may not be any duplicates, or conversely, the entire array may be duplicates.

Your function should return a single integer.

Your function should not change the array it is given.

Your function should not call scanf (or getchar or fgets).

Your function should not print anything. It should not call printf.

Your submitted file may contain a main function. It will not be tested or marked.

You can run an automated code style checker using the following command:
1511 style remove_duplicates_function.c

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

1511 autotest remove_duplicates_function

When you are finished working on this exercise, you and your lab partner must both submit your work by running give:

give cs1511 lab05_remove_duplicates_function remove_duplicates_function.c

Note, even though this is a pair exercise, you both must run give from your own account before Monday 27 March 20:00 to obtain the marks for this lab exercise.

Exercise
(●●●)
:

Find the Largest Sum of Numbers in a Z Shape

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

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

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

// Return the largest sum of numbers in a z shape.
int largest_z_sum(int size, int array[MAX_SIZE][MAX_SIZE]) {
    // Put your code here.
    return 42;
}

You are to implement the largest_z_sum function which should return the sum of values forming the shape of the letter 'Z' in a square 2D array.

A Z shape is made up of three lines of equal length. Two of these lines are horizontal and one is diagonal. The length of the three lines must be equal but can range from 3 up to the size of the array. Only correctly oriented Z shapes are valid - Z shapes with a northwest/southeast diagonal are not valid.

The 2D square array may contain any positive or negative integers.

You can assume that the side length of the 2D square array will always be greater than or equal to 3.

You can assume that the side length of the 2D array will never be greater than 100.

The file largest_z_sum.c contains a main function which reads values into a square 2D array and calls largest_z_sum.

Here is how largest_z_sum.c should behave after you add the correct code to the function largest_z_sum:

dcc largest_z_sum.c -o largest_z_sum
./largest_z_sum
Enter 2D array side length: 3
Enter 2D array values:
1 1 1
1 1 1
1 1 1
The largest z sum is 7.
./largest_z_sum
Enter 2D array side length: 5
Enter 2D array values:
1  2  3  4  5
6  7  8  9  10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
The largest z sum is 169.
./largest_z_sum
Enter 2D array side length: 5
Enter 2D array values:
 28 -47 -40  29  49
 26 -42 -37  48  1
-36  50  41 -24 -33
 41  25 -39  39  48
 14 -26 -46 -3  -29
The largest z sum is 153.
./largest_z_sum
Enter 2D array side length: 5
Enter 2D array values:
1  1  1  1  1
1  1  1  1  1
99 99 99 1  1
1  99 1  1  1
99 99 99 1  1
The largest z sum is 693.

Note:
In the first example, there is only one possible Z sum of size 3.
The Z in the example input is underlined below for your reference:

1 1 1
1 1 1
1 1 1
    
In the second example, the Z of size 5 starting from (0, 0) is used to form the largest sum of:
1 + 2 + 3 + 4 + 5 + 9 + 13 + 17 + 21 + 22 + 23 + 24 + 25 = 169
The Z in the example input is underlined below for your reference:
1  2  3  4  5
6  7  8  9  10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
    
In the third example, the Z of size 4 starting from (0, 1) is used to form the largest sum of:
-47 - 40 + 29 + 49 + 48 + 41 + 25 - 39 + 39 + 48 = 153
The Z in the example input is underlined below for your reference:
 28 -47 -40  29  49
 26 -42 -37  48  1
-36  50  41 -24 -33
 41  25 -39  39  48
 14 -26 -46 -3  -29
    
In the fourth example, the Z of size 3 starting from (2, 0) is used to form the largest sum of:
99 + 99 + 99 + 99 + 99 + 99 + 99 = 693
The Z in the example input is underlined below for your reference:
1  1  1  1  1
1  1  1  1  1
99 99 99 1  1
1  99 1  1  1
99 99 99 1  1
    
You can run an automated code style checker using the following command:
1511 style largest_z_sum.c

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

1511 autotest largest_z_sum

When you are finished working on this exercise, you and your lab partner must both submit your work by running give:

give cs1511 lab05_largest_z_sum largest_z_sum.c

Note, even though this is a pair exercise, you both must run give from your own account before Monday 27 March 20:00 to obtain the marks for this lab exercise.

Exercise
(☠)
:

Implement p1511, a new programming language.

So far in this course, you have been learning the C language.

While C is a very famous and popular language, thousands (perhaps tens of thousands) of programming languages exist. Some are very popular, though others are designed as a joke or a game. Joke languages like this are often called "eso-langs" or "esoteric languages".

Some more famous examples of eso-langs include:

In this challenge, we ask you to implement a dialect of P'' called P1511.

There are only three concepts you need to know:

  • Commands: A P1511 program is an array of characters. Each character represents a command. After running a command, you run the next one (unless the command says otherwise).
  • Your Memory: This is an array of integers, which is 0 initialized. The array can be as big as you like (we recommend 20 for debugging purposes). Each value in the array is called a "cell"
  • The Cell-Pointer One cell is always "selected". Many commands in P1511 act on the selected cell. To keep track of which cell is selected, we have the "cell pointer".

You should assume the list of commands is no longer than 10000.

An instruction can be one of the following commands:

Code Description
> Move the cell-pointer right. If you are at the last cell, loop back around to the first one.
< Move the cell-pointer left. If you are at the first cell, loop back around to the last one.
+ Add one to the current value of the cell-pointer.
- Subtract one from the current value of the cell-pointer.
. Print out the value of the cell-pointer as an ascii character.
, Replace the cell-pointer's value with a scanned in number (i.e. scanf a number, and set the cell-pointer to be equal to it).
any lowercase letter If the value of the cell-pointer is 0, jump through your commands to the uppercase version of this letter.
any uppercase letter If the value of the cell-pointer is not 0, jump through your commands to the lowercase version of this letter
! End the program :)

With this simple language, you can write almost any program!

To complete this challenge, you should write a program which simulates P1511.

Examples

Here is a simple P1511 program:

  char commands[10000] = {
    '>', '+', '+', '+', '+', '+', '+', '+', '+',
      'a', '<', '+', '+', '+', '+', '+', '+', '+', '+', '+', '>', '-', 'A',
    '<', '.', '+', '.', '!'
  };

This program prints out "HI". To see the logic of this program, run 1511 p1511, which will walk you through, step by step.

Write your own P1511 programs

If you manage to write a program in P1511, you can share it by making a post on the course forum!.

Try writing a program to print out a word, or (challenge) to add two numbers together!

You can run an automated code style checker using the following command:
1511 style p1511.c

Formatif Feedback (Optional)

Every week, you have the opportunity to submit a piece of code to formatif, and receive feedback on your work! This is entirely optional, but will provide a valuable opportunity to develop your understanding of C, and get advice on problem solving/algorithmic choices.

To get feedback, go to formatif, and upload the code that you'd like a tutor to look at (Note: This cannot be code from assignments - it must be from labs, or code written for your own practice). Once the feedback is ready, you'll receive an email with instructions on how to collect the feedback!

Submission

When you are finished each exercises make sure you submit your work by running give.

You can run give multiple times. Only your last submission will be marked.

Don't submit any exercises you haven't attempted.

If you are working at home, you may find it more convenient to upload your work via give's web interface.

Remember you have until Week 7 Monday 20:00 to submit your work.

You cannot obtain marks by e-mailing your code to tutors or lecturers.

You check the files you have submitted here.

Automarking will be run by the lecturer several days after the submission deadline, using test cases different to those autotest runs for you. (Hint: do your own testing as well as running autotest.)

After automarking is run by the lecturer you can view your results here. The resulting mark will also be available via give's web interface.

Lab Marks

When all components of a lab are automarked you should be able to view the the marks via give's web interface or by running this command on a CSE machine:

1511 classrun -sturec