Homework 5:
More Structurally Recursive Functions
Due: Monday, February 26, at 11:59 PM
Introduction
This assignment asks you to write a few more recursive functions in Racket. Its primary goal is to gain experience with common recursion patterns, especially mutual recursion.
Template Source File
Download these files:
and use them as the starting points for your submission. As usual, please use the names given for your files.
The source file includes a provide
clause that exports
your five public functions for use by other files. The tests file
includes a require
clause that imports your functions,
enabling it (and you!) to test them with Rackunit. The
provide
clause also enables me to test your code using
my own Rackunit tests.
With provide
, you must define all five functions. If
you don't have time to solve a problem, define a function that
takes the correct number of arguments and returns a legal default
value, such as 0 or '()
. homework05.rkt
includes default functions for each problem that you can use until
you write your code.
Do Not Use...
To solve these problems, you do not need any Racket features beyond the things we have learned in class and the things discussed in this assignment. In order to practice the new skills we are learning, do not use...
-
... any of Racket's primitive higher-order functions, including
map
,apply
, andfilter
. -
...
reverse
or any Racket function that converts a list argument to another datatype. Process the list one element at a time. -
... a
let
expression or an internaldefine
in any function.
Organizing Code
Use a comment to indicate where the code for each problem begins and ends. The template already does that for you.
Put your tests in homework05-tests.rkt
. For each
problem, write at least three Rackunit expressions to test
your solution. Depending on the type of value that the
function produces, use check-equal?
or
check-true/check-false
. You may use my examples as
one of your tests. Be sure that you test other key cases, too.
Put any helper functions you write for a problem between the main function in your solution and the tests for the main function. (You are not required to write any helper functions.)
Problems
-
Write a structurally recursive function named
(prefix-of? lst1 lst2)
that takes two arguments, both flat lists. Either can be the empty list.prefix-of?
returns true iflst2
starts with the items inlst1
in the same order, and false otherwise. For example:> (prefix-of? '(cs1510 cs1800) '(cs1510 cs1800 cs1520 cs1410)) #t > (prefix-of? '(cs1510 cs1800) '(cs1510 cs1520 cs1800)) #f
The empty list is a prefix of every other list. -
Write a mutually recursive function named
(includes-course? course requirements)
that takes two arguments, a symbolcourse
and a course treerequirements
. A course tree is defined as:<course-tree> ::= () | (<course-exp> . <course-tree>) <course-exp> ::= <symbol> | <course-tree>
includes-course?
returns true ifcourse
occurs anywhere inrequirements
, and false otherwise. For example:> (includes-course? 'cs1510 '((cs1120 cs1130 cs1140 cs1150 cs1160 cs1510) cs1520 ((cs1410 cs2420) (cs1800 cs2530)))) #t > (includes-course? 'cs3540 '(cs1120 cs1130 cs1140 cs1150 cs1160 cs1510)) #f
includes-course?
should be mutually recursive with the functionincludes-course-ce?
, which processes a course and a course-exp. -
Write a mutually recursive function named
(nlist+ nlist)
that takes one argument, an n-listnlist
.<n-list> ::= () | (<number-exp> . <n-list>) <number-exp> ::= <number> | <n-list>
nlist+
returns the sum of the numbers innlist
. For example:> (nlist+ '(1 -1 1 7 21 -6 21 3 4 -5 1)) 47 > (nlist+ '(1 -1 (1 (7 21)) ((-6 21) 3 (4 -5) 1))) 47
nlist+
should be mutually recursive with the functionnum-expr+
, which returns the sum of the values in a number expression. -
Write a mutually recursive function named
(max-length str-list)
that takes one argument, a string-list.<string-list> ::= () | (<string-exp> . <string-list>) <string-exp> ::= <string> | <string-list>
max-length
returns the length of the longest string instr-list
. Ifstr-list
is the empty list, it returns -1. For example:> (max-length '("Write" "a" "mutually" "recursive" "function" ("max-length" "str-list") "that" "takes" "one" "argument" ("a" "string-list"))) 11
max-length
should be mutually recursive with the functionmax-length-se
, which processes a string expression.
Recall that Racket provides the functionsmax
andstring-length
. -
Write a mutually recursive function named
(prefix->infix binary-exp)
that takes one argument, a binary expression in prefix notation.<prefix-exp> ::= (<operator> <number-exp> <number-exp>) <number-exp> ::= <number> | <prefix-exp>
prefix->infix
returns an equivalent infix expression as its value.<infix-exp> ::= (<number-exp> <operator> <number-exp>) <number-exp> ::= <number> | <infix-exp>
In both kinds of expression, an operator is a symbol. For example:> (prefix->infix '(+ 4 5)) '(4 + 5) > (prefix->infix '(* (+ 4 5) (+ 7 6))) '((4 + 5) * (7 + 6))
prefix->infix
should be mutually recursive with the functionnumber-expr->infix
, which returns an infix version of a number expression.
Note: This is a fine place to use program derivation, if you like. You are not required to do so.
Deliverables
By the due time and date, use the course submission system to submit the following files electronically:
-
homework05.rkt
, the source file containing your function definitions -
homework05-tests.rkt
, the source file containing your test cases
Be sure that your submission follows the submission requirements. As always, be sure to use the specified name for your files. This enables the autograder to find and run your code.