Assignment 6: Exploring recursion
- Summary
- For this assignment, you will start applying your knowledge of recursion to solve problems that require general repetition.
- Collaboration
- You must work with your assigned partner(s) on this assignment. You may discuss this assignment with anyone, provided you credit such discussions when you submit the assignment.
- Submitting
- Email your answers to csc151-03-grader@grinnell.edu. The subject of your email should be [CSC151 03] Assignment 6 and should contain your answers to all parts of the assignment. Scheme code should be in the body of the message, not in an attachment.
- Warning
- So that this assignment is a learning experience for everyone, we may spend class time publicly critiquing your work.
Problem 1: Partitioning elements of a list
Topics: numeric recursion
Write and document a procedure (partition lst k) that takes a list lst and a positive integer k as parameters and partitions lst into k sublists. The sublists should maintain the order of the elements and all be roughly the same size (i.e. differ in length by at most 1). Here are a few examples.
> (partition (iota 20) 2)
'((0 1 2 3 4 5 6 7 8 9) (10 11 12 13 14 15 16 17 18 19))
> (partition (iota 20) 5)
'((0 1 2 3) (4 5 6 7) (8 9 10 11) (12 13 14 15) (16 17 18 19))
> (partition (iota 10) 4)
'((0 1 2) (3 4 5) (6 7) (8 9))
> (partition (iota 10) 1)
'((0 1 2 3 4 5 6 7 8 9))
> (partition (list 1) 10)
'((1) () () () () () () () () ())
Problem 2: Palindromes
Topics: tail recursion, strings and characters
A string is called a palindrome if reversing the characters of the string results in the same string. A few examples of palindromes are "radar", "civic", and "aabaa". Write and document a tail recursive procedure (palindrome? str) that checks to see if the string str is a palindrome. You may NOT use any string compare procedures for this problem (e.g. string=?, string<=?, etc.).
> (palindrome? "hello")
#f
> (palindrome? "civic")
#t
Problem 3: Adding and removing elements
Topics: list recursion, numeric recursion
Sometimes we want to add an individual element to a list at a particular position, or to remove the element at a particular position.
a. Write and document a recursive procedure, (insert-at pos val lst),
that creates a new version of lst but with val inserted at the
given position.
> (insert-at 0 'x '(a b c))
'(x a b c)
> (insert-at 1 'x '(a b c))
'(a x b c)
> (insert-at 2 'x '(a b c))
'(a b x c)
> (insert-at 3 'x '(a b c))
'(a b c x)
Note: While you can implement insert-at with take and drop,
for this assignment, you must implement it recursively.
b. Write and document a recursive procedure, (remove-at pos lst), that
creates a new veresion of lst with the value at position pos removed.
> (remove-at 0 '(a b c d))
'(b c d)
> (remove-at 1 '(a b c d))
'(a c d)
> (remove-at 2 '(a b c d))
'(a b d)
> (remove-at 3 '(a b c d))
'(a b c)
Problem 4: Building list variants through insertion
Topics: recursion
Write, but do not document, a procedure, (insert-everywhere val lst),
that takes as input a value and a list, and returns a list of lists,
each of which is a copy of lst with val inserted at each position
between 0 and (length lst), inclusive.
> (insert-everywhere 'a '())
'((a))
> (insert-everywhere 'a '(b))
'((a b) (b a))
> (insert-everywhere 'a '(b c))
'((a b c) (b a c) (b c a))
> (insert-everywhere 'a '(b c d))
'((a b c d) (b a c d) (b c a d) (b c d a))
Hint: Although you are building a list, this is really a problem in numeric recursion.
Problem 5: Generating permutations
Topics: recursion
Given a list of items, it can be useful to know all possible ways the list can be uniquely ordered. A specific ordering of items is called a permutation and the notion appears frequently in mathematics.
Write but do not document a procedure called (permutations lst) that
takes a list as a parameter returns a list of all possible permutations of
the elements of lst. Here are a few example executions of the procedure.
> (permutations (list 1 2))
'((1 2) (2 1))
> (permutations (list 0 1 2))
'((0 1 2) (1 0 2) (1 2 0) (0 2 1) (2 0 1) (2 1 0))
> (permutations (list 'a 'b 'c))
'((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))
> (permutations (list "a" 'b 7))
'(("a" b 7) ("a" 7 b) (b "a" 7) (b 7 "a") (7 "a" b) (7 b "a"))
> (permutations (list "hello"))
'(("hello"))
The insert-everywhere procedure you just wrote will help. How? To
compute the permutations of a non-empty list, you make all of the
permutations of the cdr of the list, insert the car of the list at
each position in each permutation, and then join them all together.
> (insert-everywhere 1 '(2))
'((1 2) (2 1))
> (insert-everywhere 0 '(1 2))
'((0 1 2) (1 0 2) (1 2 0))
> (insert-everywhere 0 '(2 1))
'((0 2 1) (2 0 1) (2 1 0))
> (append (insert-everywhere 0 '(1 2)) (insert-everywhere 0 '(2 1)))
'((0 1 2) (1 0 2) (1 2 0) (0 2 1) (2 0 1) (2 1 0))
Evaluation
We will primarily evaluate your work on correctness (does your code compute what it’s supposed to and are your procedure descriptions accurate); clarity (is it easy to tell what your code does and how it achieves its results; is your writing clear and free of jargon); and concision (have you kept your work short and clean, rather than long and rambly).