Homework 5
More Structurally Recursive Functions
Due: Monday, March 2, 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. -
...
reverseor any Racket function that converts a list argument to another datatype. Process the list one element at a time. -
... a
letexpression or an internaldefinein any function.
Organizing Code
Put your solutions in homework05.rkt. Use a
comment to indicate where the code for each problem begins
and ends. The template already does this 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 one of 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 just after the main function in your solution. You are not required to write any helper functions not specified by the problem.
Problems
-
Write a structurally recursive function named
(prefix-of? lst1 lst2)that takes two arguments, both flat lists. Either can be the empty list.<list> ::= () | (<any-value> . <list>)prefix-of?returns true iflst2starts with the items inlst1in 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 symbolcourseand a course treerequirements. A course tree is defined as:<course-tree> ::= () | (<course-exp> . <course-tree>) <course-exp> ::= <symbol> | <course-tree>includes-course?returns true ifcourseoccurs 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)) #fincludes-course?must be mutually recursive with the functionincludes-course-ce?, which processes a course and a course-exp. -
Write a mutually recursive function named
(nlist+ n nlist)that takes two arguments, an n-listnlistand a numbern.<n-list> ::= () | (<number-exp> . <n-list>) <number-exp> ::= <number> | <n-list>nlist+returns an n-list just likenlistbut with each number incremented byn. For example:> (nlist+ 2 '(1 -1 1 7 21 -6 21 3 4 -5 1)) '(3 1 3 9 23 -4 23 5 6 -3 3) > (nlist+ -1 '(1 -1 (1 (7 21)) ((-6 21) 3 (4 -5) 1))) '(0 -2 (0 (6 20)) ((-7 20) 2 (3 -6) 0))
nlist+must be mutually recursive with the functionnum-expr+, which increments every value 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-lengthreturns the length of the longest string instr-list. Ifstr-listis 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"))) 11max-lengthmust be mutually recursive with the functionmax-length-se, which processes a string expression.
Recall that Racket provides the functionsmaxandstring-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->infixreturns 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->infixmust be mutually recursive with the functionnumber-expr->infix, which returns an infix version of a number expression.
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 auto-grader to find and run your code.