Write and test the following functions. Please be sure to get the spelling and capitalization right, and the right number and types of parameters, in order to make testing them feasible.
These are mostly unrelated exercises, to give you some experience with Clojure syntax. The exercises in the first group do not require higher-order functions, the exercises in the second group might be done with higher-order functions, and the exercises in the third group are higher-order functions. Almost all are recursive.
In some cases, for example reversing a list, you may find Clojure
functions that already do exactly what you want. (This is certainly true
for the functions whose names begin with my-.) Please don't
use them, but rather write the functions yourself.
Most of these functions are defined to work with lists, because my experience in Lisp has been almost entirely with lists. If your functions works with lists, they will probably also work with other kinds of sequences.
In all cases, assume that the inputs to the function are correct; don't do any error checking.
You don't need higher-order functions to program these, but if you see an opportunity to use them, go ahead. Generally, the purpose is to get you used to writing recursive functions the Clojure way.
(atomic? v)true if v is not any kind
of a collection (check with coll?), and false
otherwise.(member? x lst)x is in lst.(my-count lst)lst.
For example, (a (b c (d e)) f) has 3 top
level elements; (b c (d e)) is a single
top-level element. (a b () d) has 4 top-level
elements.(append lst1 lst2)lst1 and lst2
into a single list. For example, if lst1 is (:a
:b :c) and lst2 is (1 (2 3)),
the result should be (:a :b :c 1 (2 3)).(zip lst1 lst2)lst1 and lst2
into a list of two-element lists; stop when you run out of elements in
either list. For example, if lst1 is (:a
:b :c) and lst2 is (1 (2 3)
4 5), the result should be ((:a 1)
(:b (2 3)) (:c 4)).(lookup key list-of-pairs)key and a list of (key
value) pairs, return the value
that corresponds to the key, or nil
if there is no such pair. You can assume that there is only one such
pair.(my-merge lst1 lst2)lst1 is (3 7 12 19 19 25 30)
and lst2 is (4 7 10 12 20), the
result should be (3 4 7 7 10 12 12 19 19 20 25 30).(count-all lst)lst,
at all levels. For example, (a (b c () (25) nil) ())a, b, c,
25, and nil.(my-drop n lst)lst with the first n
elements removed. For example, (my-drop 3 '(a b c d e))
should return (d e)). If n is equal
to or greater than the length of the list lst,
return the empty list, ().(my-take n lst)n elements of lst.
If lst has fewer than n
elements, the result is just lst. Strong
hint: Use two parameters lists, the second one using an
"accumulator" parameter to collect the elements taken from lst.
You are likely to find reverse to be useful.(my-reverse lst)lst. For example,
the list (1 2 (3 4)) becomes the sequence ((3
4) 2 1) .(remove-duplicates lst)lst.
For example, given (1 2 3 1 4 1 2) ,
remove-duplicates returns a sequence containing the elements (1
2 3 4) , in some order.(my-flatten list-of-lists) lst is
(((1 1) (2 3)) ((5 7))) , the result
should be ((1 1) (2 3) (5 7) ).These are best done with higher-order functions, so please use them wherever they seem to work.
(buzz list-of-ints)7,
has been replaced by :buzz. Hint: (seq
string) returns a list of characters, and map
is useful.(divisors-of n)n, returns the divisors of
n, other than 1 and n
itself. For example, 12 has divisors (2, 3, 4, 6). Hint:
Use mod and filter.(longest list-of-strings)list-of-strings;
if there is more than one longest string, return the earlier one. Assume
that list-of-strings is not empty. Hint:
reduce.(my-map f lst)f to
each element of lst, returning a list of the
results.(my-filter pred lst)pred to each element of lst,
returning a list of the ones that pass the test.(my-reduce f value? lst)f
to the value? and the first element of
the sequence (if value? is present), else to the
first two elements of the sequence; applies the function to the result
and the next element in the list, recursively. Hint:
Since this function takes two or three arguments,
you have to use the proper syntax for this. See Defining and
calling functions in my Concise
Guide to Clojure.(my-flat-map f lst)f must be a function that returns lists. my-flat-map
applies the function f to each element of lst,
flattens the resultant list by removing one level of
parentheses, and returns the result.Write, in a separate file, unit tests for all your methods. Since we
haven't talked about testing yet, here's a model for you to follow. Notice
the use of deftest and is.
(ns user (:use clojure.test))
(deftest test-my-reverse
(is (= '(3 2 1) (my-reverse '(1 2 3))))
(is (= '(5 (3 4) 2 1) (my-reverse '(1 2 (3 4) 5))))
(is (= () (my-reverse ()))) )
(run-tests)
Zip and turn in your exercises.clj and
exercises-test.clj files by 6am, Tuesday, September 27
As always, only files submitted to Canvas
will be accepted. I do not accept assignments submitted by email.