Week 04 Laboratory Sample Solutions
Objectives
- using while loops for repetition
- creating functions
Activities To Be Completed
The following is a list of all the activities available to complete this week...
Worth 0.7 mark(s) in total:
- devowel
- middle3
Worth 0.7 mark(s) in total:
- hollow_triangle
- souffle_pancake
Worth 0.4 mark(s) in total:
- cs_calculator
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.
Exercise
(●◌◌)
:
Devowelling Text
devowel.c
which reads characters from its input
and writes the same characters to its output, except it does not write lower case vowels ('a', 'e', 'i', 'o', 'u').
Your program should stop only at the end of input.
Your code should match the following example exactly:./devowel Are you saying 'Boo' or 'Boo-Urns'? Ar y syng 'B' r 'B-Urns'? In this house, we obey the laws of thermodynamics! In ths hs, w by th lws f thrmdynmcs!
1091 style devowel.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1091 autotest devowel
When you are finished working on this exercise,
you must
submit your work by running give
:
give dp1091 lab04_devowel devowel.c
You must run give
before Monday 23 September 09:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
devowel.c
// Written 3/3/2018 by Andrew Taylor (andrewt@unsw.edu.au)
// read characters from stdin and write to stdout
// except lower case vowels ('a', 'e','i', 'o', 'u') are not written
#include <stdio.h>
int is_vowel(char character);
int main(void) {
char character;
while (scanf("%c", &character) == 1) {
if (!is_vowel(character)) {
printf("%c", character);
}
}
return 0;
}
// return 1 if character is a lower case vowel
// 0 otherwise
int is_vowel(char character) {
return character == 'a' ||
character == 'e' ||
character == 'i' ||
character == 'o' ||
character == 'u';
}
Exercise
(●◌◌)
:
Print the Middle Integer of 3 Integers
Download middle3.c here, or copy it to your CSE account using the following command:
cp -n /import/reed/A/dp1091/public_html/24T3/activities/middle3/middle3.c .
Write a C program middle3.c
that reads 3 integers into a struct and prints
the middle integer.
You are not permitted to use loops or arrays (use if statements).
Examples
dcc middle3.c -o middle3 ./middle3 Enter integer: 23 Enter integer: 5 Enter integer: 27 Middle: 23 ./middle3 Enter integer: 3 Enter integer: 6 Enter integer: 27 Middle: 6 ./middle3 Enter integer: 9 Enter integer: 7 Enter integer: 8 Middle: 8
You can assume the user supplies 3 integers. You do not have to check the return value from scanf.
1091 style middle3.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1091 autotest middle3
When you are finished working on this exercise,
you must
submit your work by running give
:
give dp1091 lab04_middle3 middle3.c
You must run give
before Monday 23 September 09:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
middle3.c
// Program to scan in three integers and print out the middle one.
#include <stdio.h>
struct numbers {
int first;
int second;
int third;
};
int main(void) {
// DO NOT CHANGE CODE BELOW HERE
struct numbers nums;
printf("Enter integer: ");
scanf("%d", &nums.first);
printf("Enter integer: ");
scanf("%d", &nums.second);
printf("Enter integer: ");
scanf("%d", &nums.third);
// DO NOT CHANGE CODE ABOVE HERE
// ADD CODE BELOW HERE
int middle = nums.first;
if (nums.first > nums.second) {
// third second first
if (nums.second > nums.third) {
middle = nums.second;
// second third first
} else if (nums.first > nums.third) {
middle = nums.third;
}
} else {
// first second third
if (nums.third > nums.second) {
middle = nums.second;
// first third second
} else if (nums.third > nums.first) {
middle = nums.third;
}
}
printf("Middle: %d\n", middle);
return 0;
}
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 * ** * * * * * * * * * * * * * * * * ***********
1091 style hollow_triangle.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1091 autotest hollow_triangle
When you are finished working on this exercise,
you must
submit your work by running give
:
give dp1091 lab04_hollow_triangle hollow_triangle.c
You must run give
before Monday 23 September 09:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
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
(●●◌)
:
Souffle Pancakes
Download souffle_pancake.c here, or copy it to your CSE account using the following command:
cp -n /import/reed/A/dp1091/public_html/24T3/activities/souffle_pancake/souffle_pancake.c .
Complete the C program, souffle_pancake.c
.
The main function has already been written, which help the user
calculate how many resources they will need to cook any given amount of
souffle pancakes!
Unfortunately due to a strange bug in the DCC Compiler, the math.h library has been acting up, so Paula has asked you to help her out and write some useful functions similar to those in that library.
Your job is to write 3 functions that are currently being used in the main function.
They are: divide
, ceiling
and a helper procedure print_time
.
Functions to Implement
1- divide
is a function that divides two doubles.
function input: a double
for the top of the divide, a double
for the bottom of the divide
function output: double
for the result
2- ceiling
is a function that rounds up a given double to the closest integer.
If the value is already a whole number, it stays the same value.
function input:a double
for the number being ceiling-ed
function output: int
for the result
3- print_time
is a procedure that given minutes, will print out the time in hours and minutes
function input:an int
for the cooking time in minutes
function output: void
It will print the time in the format "X hours and X minutes"
, even if either the minutes or hours is 0.
Examples
dcc souffle_pancake.c -o souffle_pancake ./souffle_pancake How many souffle pancakes do you want to make? 3 You will need: - 2 eggs - 30g sugar - 24g flour Frying will take you 0 hours and 15 minutes.
./souffle_pancake How many souffle pancakes do you want to make? 5 You will need: - 4 eggs - 50g sugar - 40g flour Frying will take you 0 hours and 30 minutes.
1091 style souffle_pancake.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1091 autotest souffle_pancake
When you are finished working on this exercise,
you must
submit your work by running give
:
give dp1091 lab04_souffle_pancake souffle_pancake.c
You must run give
before Monday 23 September 09:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
souffle_pancake.c
// Does some calculations to make souffle pancakes
// Solution by Paula Tennent (2023)
#include <stdio.h>
#define COOKING_TIME 15
#define PANCAKES_PER_PAN 4
// Function prototypes
double divide(double a, double b);
int ceiling(double x);
void print_time(int minutes);
// divides two double values and returns a double.
double divide(double a, double b) {
return a / b;
}
// Rounds up a number to the nearest integer.
int ceiling(double x) {
int new_x = x;
if (new_x < x) {
return new_x + 1;
} else {
return x;
}
}
// Prints the time in hours and minutes given only minutes.
void print_time(int minutes) {
int hours = minutes / 60;
minutes = minutes % 60;
printf("%d hours and %d minutes", hours, minutes);
}
int main(void) {
printf("How many souffle pancakes do you want to make? ");
int pancakes;
scanf("%d", &pancakes);
// for 3 pancakes, we need 2 eggs!
double eggs_decimal = pancakes * divide(2, 3);
// but we can't have part of an egg, so lets use ceiling
int eggs = ceiling(eggs_decimal);
int sugar_grams = pancakes * 10;
int flour_grams = pancakes * 8;
printf("You will need:\n");
printf("- %d eggs\n", eggs);
printf("- %dg sugar\n", sugar_grams);
printf("- %dg flour\n", flour_grams);
// also using ceiling for frying sessions as if we have 1 pancake left
// it still needs the same time as full pan of pancakes.
int frying_sessions = ceiling(divide(pancakes, PANCAKES_PER_PAN));
int minutes = frying_sessions * COOKING_TIME;
printf("Frying will take you ");
print_time(minutes);
printf(".\n");
return 0;
}
Exercise
(●●●)
:
Create a Simple Calculator, Reading Different Numbers of Integers
For this exercise, make a program called cs_calculator.c
which
will scan in instructions until End-Of-Input (ctrl+D) and prints the output as specified below. An instruction is a sequence of positive integers. The first integer identifies what
type the instruction is.
- If the first number in the instruction is
1
, then your program should print out the square of the next number in the instruction. - If the first number in the instruction is
2
, then your program should print out the value of the next number raised to the power of the number after next.
You can assume that the first number in the instruction is only either
1
or 2
You can assume that for each instruction, the correct number of successive positive integers will be given.
./cs_calculator Enter instruction: 1 2 4 Enter instruction: 2 5 3 125 Enter instruction: 1 4 16 Enter instruction: 2 3 4 81 Enter instruction:
./cs_calculator Enter instruction: 2 3 3 27 Enter instruction: 1 10 100 Enter instruction:
Note: The autotest for this exercise expects your program to end WITHOUT a new line character when the user presses Ctrl+D. This means that the command prompt for the next command should be on the same line as the end of your program.
One major challenge of this exercise is figuring out how to use scanf
effectively.
The lessons you learn in this exercise regarding scanf
will be useful in the first assignment.
1091 style cs_calculator.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1091 autotest cs_calculator
When you are finished working on this exercise,
you must
submit your work by running give
:
give dp1091 lab04_cs_calculator cs_calculator.c
You must run give
before Monday 23 September 09:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
cs_calculator.c
// Author: Dean Wunder
// d.wunder@unsw.edu.au
// 2020-05-04
// A arbitrary calculator app designed to help students
// understand variable length input scanning before assignment 1.
#include <stdio.h>
#define SQUARE_COMMAND 1
#define POWER_COMMAND 2
int main (void) {
int command;
printf("Enter instruction: ");
while (scanf("%d", &command) == 1) {
if (command == SQUARE_COMMAND) {
int num;
scanf("%d", &num);
printf("%d\n", num * num);
} else if (command == POWER_COMMAND) {
int base, power;
scanf("%d %d", &base, &power);
int i = 0;
int result = 1;
while (i < power) {
result *= base;
i++;
}
printf("%d\n", result);
}
printf("Enter instruction: ");
}
return 0;
}
Exercise
— individual:
(Not For Marks) Debugging - Letter Search
Copy the program debug_letter_search.c
from the course account to your
directory by typing (make sure you type the dot at the end):
cp ~dp1091/public_html/24T3/activities/debug_letter_search/debug_letter_search.c .
**Note that this exercise is not marked or worth marks!**
### Debugging Tips!
Some debugging tips for you:
- dcc output - as you run into issues, dcc will point you to where the errors are. Remember that dcc gives you the line number the issue is on, and will give some sort of explanation. Make sure you read everything dcc gives you. Sometimes we get “errors carried forward”, so find your first error, fix that, then recompile.
- print statements - sometimes it can be handy to see if the flow of your code puts you in the spot you expect it to be (ie. inside the right if statement, or going through a loop the correct amount of times). A quick way you can check this is by putting print statements in your code for testing purposes, like "the value of x is %d and y is %d"
. This lets you check that you got against what you expected.
DPST1091 debugging guide - https://cgi.cse.unsw.edu.au/~dp1091/23T3/resources/debugging_guide.html
### The Task
This exercise reads in a letter from the user, and then searches more input given by the user for that letter, or until **CTRL+D** is entered. It then tells the user if the search was sucessful or not. ### Examples
dcc debug_letter_search.c -o debug_letter_search ./debug_letter_search Which letter are we searching for?: g COMP1511 is awesome! hmmm, how about this? what about now? hm. How about frog? We found g!!! ./debug_letter_search Which letter are we searching for?: ? No questions here. Only sentences. I could have a question. Nah The mission was not successful :(
1091 style debug_letter_search.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1091 autotest debug_letter_search
debug_letter_search.c
// debug_letter_search.c SOLUTION
//
// Write a C program that takes in a letter from the user, and then searches
// more input given by the user for that letter, or until CTRL+D is entered.
//
// Gab Steiner, June 2023
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int main(void) {
// Get the letter we are trying to find
printf("Which letter are we searching for?: ");
char target;
scanf("%c", &target);
// Loop through input until we get the target, or ctrl+d
char letter;
int found = FALSE;
while (found == FALSE && scanf("%c", &letter) == 1) {
// Check if we found the letter
if (letter == target) {
found = TRUE;
}
}
// Tell the user if we found it or not
if (found == TRUE) {
printf("We found %c!!!\n", target);
} else {
printf("The mission was not successful :(\n");
}
return 0;
}
Exercise
— individual:
(Not For Marks) Debugging - Clouds
Copy the program debug_cloud.c
from the course account to your
directory by typing (make sure you type the dot at the end):
cp ~dp1091/public_html/24T3/activities/debug_cloud/debug_cloud.c .
**Note that this exercise is not marked or worth marks!**
### Debugging Tips!
Some debugging tips for you:
- dcc output - as you run into issues, dcc will point you to where the errors are. Remember that dcc gives you the line number the issue is on, and will give some sort of explanation. Make sure you read everything dcc gives you. Sometimes we get “errors carried forward”, so find your first error, fix that, then recompile.
- print statements - sometimes it can be handy to see if the flow of your code puts you in the spot you expect it to be (ie. inside the right if statement, or going through a loop the correct amount of times). A quick way you can check this is by putting print statements in your code for testing purposes, like "the value of x is %d and y is %d"
. This lets you check that you got against what you expected.
- DPST1091 debugging guide - https://cgi.cse.unsw.edu.au/~dp1091/24T3/resources/debugging_guide.html
### The Task
This exercise reads in some cloud heights from a user and works out what type of clouds they are. The program then prints out the total count for all the types. Note that fog clouds are the lowest, then cumulo, then alto, then cirro clouds occur at the highest heights. ### Examples
dcc debug_cloud.c -o debug_cloud ./debug_cloud Enter some clouds: 200 550 880 2500 100000 CLOUDS There are 1 fog clouds There are 2 cumulo clouds There are 1 alto clouds There are 1 cirro clouds
./debug_cloud Enter some clouds: 65000 80000 3000 4000 4690.23 12.54 24.57 8 CLOUDS There are 3 fog clouds There are 0 cumulo clouds There are 3 alto clouds There are 2 cirro clouds
1091 style debug_cloud.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1091 autotest debug_cloud
debug_cloud.c
// debug_cloud.c SOLUTION
// This is a C program that reads in some clouds and tallies the types.
// Gab Steiner, June 2023
#include <stdio.h>
enum levels {
LOW = 500,
MID = 2000,
HIGH = 6000
};
enum cloud_type {
FOG,
CUMULO,
ALTO,
CIRRO
};
struct cloud {
double height;
enum cloud_type type;
};
int cloud_type_count(enum cloud_type type, struct cloud clouds[10],
int count);
int main(void) {
struct cloud sky[10];
printf("Enter some clouds:\n");
// Scan in some clouds
int index = 0;
while (scanf("%lf", &sky[index].height) == 1) {
// Determine the type of cloud based on it's height
if (sky[index].height > HIGH) {
sky[index].type = CIRRO;
} else if (sky[index].height > MID) {
sky[index].type = ALTO;
} else if (sky[index].height > LOW) {
sky[index].type = CUMULO;
} else {
sky[index].type = FOG;
}
index++;
}
// Print out the total for each cloud
printf("\nCLOUDS\n");
printf("There are %d fog clouds\n", cloud_type_count(FOG, sky, index));
printf("There are %d cumulo clouds\n", cloud_type_count(CUMULO, sky, index));
printf("There are %d alto clouds\n", cloud_type_count(ALTO, sky, index));
printf("There are %d cirro clouds\n", cloud_type_count(CIRRO, sky, index));
return 0;
}
// This function counts the number of times a specific type of cloud was seen.
//
// ARGS:
// - type is the type of cloud being looked for.
// - clouds is an array of cloud structs.
// - count is the number of clouds filled in the array.
//
// RETURN:
// - total is the number of clouds of the specific type that were found.
//
int cloud_type_count(enum cloud_type type, struct cloud clouds[10],
int count) {
int total = 0;
// Find all the clouds with that type
for (int i = 0; i < count; i++) {
if (clouds[i].type == type) {
total++;
}
}
return total;
}
Submission
give
.
You only need to do this if the exercise specifies a give command, otherwise - the exercise is not worth marks.
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 5 Monday 9:00am 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:
1091 classrun -sturec
Generative AI Permission Level
In completing this assessment, you are permitted to use standard editing and referencing functions in the software you use to complete your assessment. These functions are described below. You must not use any functions that generate or paraphrase passages of text or other media, whether based on your own work or not.
If your Convenor has concerns that your submission contains passages of AI-generated text or media, you may be asked to account for your work. If you are unable to satisfactorily demonstrate your understanding of your submission, you may be referred to UNSW Conduct & Integrity Office for investigation for academic misconduct and possible penalties.
DPST1091/CPTG1391 Specific Information
You are permitted to use the tools dcc-help to help you understand the error messages you may get when compiling the code you have written.
You are permitted to use autotest-help to help you understand why your code may not be passing the automated tests.
You are not permitted to submit code generated by automatic AI tools such as Github Copilot, ChatGPT, Google Bard in DPST1091/CPTG1391/COMP1511 for assignments. Submitting code generated by Github Copilot, ChatGPT, Google Bard and similar tools will be treated as plagiarism.
Our reasoning behind our decisions:
Systems such as Github Copilot and ChatGPT based on large language models or other generative artificial intelligence techniques, look likely to become heavily used by programmers. However, you need a good understanding of the language you are coding in and the systems involved before you can effectively use these tools. Using these tools to generate code for DPST1091/CPTG1391/COMP1511 instead of writing the code yourself will hinder your learning.