Skip to main content

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).