Coding Exercises
I think that many teachers (whether you tutor, TA, or lecture) can relate to the problem of coming up with appropriate exercises on the spot. After reading another post 1 by another TA, I thought I’d put together a list of examples with code examples. Each exercise has an explanation, and examples are given in C and Python.
I will update this list of projects when I think of some more ideas, but please leave any suggestions (or corrections) in the comments!
Feel free to use these materials as you wish. I only ask that you provide attribution, and link back to this page.
Table of Contents
Getting Started
Hello World!
Originally attributed to Brian Kernighan (one of the creators of the “C” language) when he worked at Bell Labs, pretty much every programmer starts off with this infamous program1.
#include <stdio.h>
int main() {
printf("hello, world\n");
}
print("hello, world")
User Input
Important for a wide range of applications, most programs need user input to make them useful, so it makes sense that learning this early on is important.
#include <stdio.h>
#define MAX_SIZE 100
int main() {
char name[MAX_SIZE];
printf("What is your name? ");
fgets(name, MAX_SIZE, stdin);
printf("Hello %s", name);
}
name = input("What is your name? ")
print("Hello", name)
FizzBuzz
Based on a classic playground game, count up to a specific number, substituting multiples of 3 with “Fizz”, multiples of 5 with “Buzz”, and multiples of both with “FizzBuzz”.
for (int n = 0; n < 100; n++) {
if (n % 5) == 0 && (n % 3) == 0 {
printf("FizzBuzz\n");
} else if (n % 5) == 0 {
printf("Fizz\n");
} else if (n % 3) == 0 {
printf("Buzz\n");
} else {
printf("%d\n", n);
}
}
for n in range(100):
if (n % 5) == 0 and (n % 3) == 0:
print("FizzBuzz")
elif (n % 5) == 0:
print("Fizz")
elif (n % 3) == 0:
print("Buzz")
else:
print(n)
Command Line Arguments
It can be really handy to get the command-line arguments of a program, so start off by first reading them and printing them out. Once you can do this, you can start to use them as useful, efficient user input.
#include <stdio.h>
int main(int argc, char** argv) {
for (int i = 0; i < argc; i++) {
printf("%s\n", argv[i]);
}
// You can also get specific options with...
// getopt(int argc, char *const argv[], const char *optstring)
}
import sys
print(sys.argv)
print(len(sys.argv)) # Equivalent to argc
# Python provides a similar function: getopt.getopt(args, options, [long_options])
You can read more here:
File I/O
Reading to and writing from files is really crucial for a wide variety of problems, whether you are making some kind of file editor or using a SQLite Database.
#include <stdio.h>
int main() {
// Reading files
FILE* f = fopen("my_file.txt", "r");
char c;
do {
c = fgetc(f);
// This reads one character at a time (other methods are available)
printf("%c", c);
} while (c != EOF);
fclose(f);
// Writing to files
FILE* f = fopen("my_file.txt", "w");
const char* txt = "Some cool text to write...";
fprintf(f, "You can use fprintf just like printf, writing strings and values (%d)\n", 37);
// Again, other options are available for writing to files...
fclose(f);
}
# Reading files
f = open("my_file.txt")
txt = f.read()
print(txt)
f.close()
# Reading files (Another Solution)
with open("my_file.txt") as f:
txt = f.read()
print(txt)
# Writing to files
txt = "Hello File!"
with open("my_file.txt", "w") as f:
f.write(txt)
Intermediate Exercises
Bubble Sort
#include <stdio.h>
void sort(int a[], const int len) {
int tmp;
for (int i = 0; i < len-1; i++) {
for (int j = i+1; j < len; j++) {
if (a[i] > a[j]) { // Use < to sort descending instead
// Swap
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
}
void print_array(const int a[], const int len) {
for (int i = 0; i < len; i++)
printf("%d ", a[i]);
printf("\n");
}
int main() {
int arr[] = {3, -28, 634, 30, -32}, len = 5;
printf("Unsorted: ");
print_array(arr, len);
sort(arr, len);
printf("Sorted: ");
print_array(arr, len);
}
Adapted from the pseudocode on includehelp.com
def sort(a):
for i in range(len(a)):
for j in range(i+1, len(a)):
if a[i] > a[j]: # Use < to sort descending instead
a[i], a[j] = a[j], a[i] # Swap
arr = [3, -28, 634, 30, -32]
print(arr)
sort(arr)
print(arr)
Anagram
Write a function that can check whether two strings are anagrams of each other. As a bonus, think about how this could be optimised using techniques like dynamic programming.
#include <stdbool.h>
#include <string.h>
#include <malloc.h>
/**
* Sort a string's characters in alphabetical order
* I use the bubble sort algorithm,
* but you can use your favourite algorithm instead!
**/
char* sort_string(const char* s) {
const int n = strlen(s);
char* sorted = malloc(sizeof(s));
strcpy(sorted, s);
char tmp;
for (int i = 0; i < n-1; i++) {
for (int j = i+1; j < n; j++) {
if (sorted[i] > sorted[j]) {
// Swap
tmp = sorted[i];
sorted[i] = sorted[j];
sorted[j] = tmp;
}
}
}
return sorted;
}
/**
* Returns 1 (true) if the strings are anagrams of each other
* Returns 0 (false) if they are not
**/
bool anagram(const char* s1, const char* s2) {
if (strlen(s1) != strlen(s2)) {
return false;
}
return strcmp(sort_string(s1), sort_string(s2)) == 0;
}
int main() {
anagram("test", "tset"); // 1
anagram("test", "test"); // 1
anagram("steve", "brian"); // 0
anagram("super", "upres"); // 1
}
def anagram(s1, s2):
if len(s1) != len(s2):
return False
s1 = ''.join(sorted(s1))
return s1 == ''.join(sorted(s2))
anagram("test", "tset") # True
anagram("test", "test") # True
anagram("steve", "brian") # False
anagram("super", "upres") # True
Chess Board
Construct a chessboard, looking something like that shown in the figure above. You could produce output like this:
White Black White Black White Black White Black
Black White Black White Black White Black White
White Black White Black White Black White Black
Black White Black White Black White Black White
White Black White Black White Black White Black
Black White Black White Black White Black White
White Black White Black White Black White Black
Black White Black White Black White Black White
The following solutions just focus on producing the above output. However, you could modify them to produce a data structure that contains the chessboard.
#include <stdio.h>
#include <stdbool.h>
#define COLS 8
#define ROWS 8
int main() {
char* colours[] = {"White", "Black"};
bool alt = false;
for (int i = 0; i < COLS*ROWS; i++) {
if (i != 0 && i % COLS == 0) {
printf("\n");
alt = !alt;
}
printf("%s ", colours[alt ? 1-(i%2) : i%2]);
}
}
COLS = 8
ROWS = 8
def print_board():
colours = ["White", "Black"]
alt = False
for i in range(COLS*ROWS):
if i != 0 and i % COLS == 0:
print()
alt = not alt
print(colours[1-(i%2) if alt else i%2], end=" ")
print_board()
Pig Latin Translator
Pig Latin is produced by adding a fabricated suffix and reconstructing the pieces of English words. You can translate from English to Pig Latin by taking the first letter of each word, moving it to the end of the word and appending the suffix “ay”.
For example “Pig Latin is pretty cool” in English, would become “Igpay atinlay siay rettypay oolcay”.
def translate_english(s):
a = []
for word in s.split(" "):
a.append(pl_w(word).lower())
return " ".join(a)
def translate_piglatin(s):
return " ".join([en_w(word).lower() for word in s.split(" ")])
def pl_w(s):
return s[1:] + s[0] + "ay"
def en_w(s):
return s[-3] + s[:-3]
def main():
en = "Pig Latin is pretty cool"
# Translate English to Pig Latin
pl = translate_english(en)
print(en)
print(pl)
# Translate Pig Latin to English
print(translate_piglatin(pl))
if __name__ == "__main__":
main()
Logic Problems
Wolf, Sheep, Cabbage
A classic river crossing problem 2. A farmer has bought a wolf, a sheep and a cabbage from a market on one side of a river, and needs to take them over to the other side. However, he can only take one at a time, and if the wolf is left alone with the sheep, or the sheep with the cabbage, they will be eaten.
You can solve the problem interactively on Coolmath Games.
Solution
- Take the sheep over
- Return
- Take the wolf or cabbage over
- Return with the sheep
- Take the cabbage or wolf over
- Return
- Take sheep over