posted on 2018-01-30
Given a list of $n$ unary functions $L:=(f_1, f_2,\ldots,f_n)$, write a function (appList L x)
that returns $(f_1(x), f_2(x), \ldots, f_n(x))$. For example:
(appList (list sin cos tan) 3.14)
;; ==> (0.00159265291648683 -0.99999873172754 -0.00159265493640722)
posted on 2018-01-30
Write functions square-matrix?
and diagonal-matrix?
to determine if a matrix is square (same number of rows and columns), or if a matrix is diagonal (the only non-zero entries are those on the diagonal).
posted on 2018-01-30
Suppose a matrix is represented as a list of equally sized lists representing the rows. Write a function to transpose a matrix in this representation. Transposition is a process where every row becomes a column, and every column becomes a row.
posted on 2018-01-30
Implement the following combinators, high-order functions that are usually composed together. (Here we specify the type signatures in Haskell-like notation.)
(constantly x)
, a function which takes an argument x
and produces a unary function which always returns x
.yes
which always returns a true value, and no
which always returns a false value.(complement f)
, a function which takes a function returning a Boolean, and produces another function which does the same but with the Boolean inverted.(conjunction f g)
which returns a function which takes an argument and returns true iff both f
and g
are satisfied by x
.(disjunction f g)
which is like conjunction
but checks iff either f
or g
are satisfied by the input.One should note the similarity between these functions and some of the basic unary and binary Boolean predicates.
Write out the type signature of each of the above functions.
Implement Fizz Buzz using these combinators.
posted on 2018-01-30
In Common Lisp, there's a macro called destructuring-bind
which allows you to "take apart" a list and bind the parts to variables. It's a primitive form of pattern matching for lists.
Implement a basic version that allows the following to work:
(define lst '(1 2 3))
(define cns '(1 . 2))
(destructuring-bind (a b c) lst
(+ a b c)) ; ==> 6
(destructuring-bind (a . b) cns
(+ a b)) ; ==> 3
(destructuring-bind (a . b) lst
(map (lambda (x) (+ a x)) b)) ; ==> (3 4)
posted on 2018-01-30
Wirte a fincuton wcihh teaks a snetnece as a srintg and sberalmcs the mlddie lretets of each word, keiepng the first and last ltretes of each word itnact. You can asmuse "ieadl" ipunt: no pntitcoauun, no nbuemrs, etc.
posted on 2018-01-30
Implement a C-style for
-loop without using another explicit
imperative looping construct.
(for ((<var> <init>) <condition> <post-loop-thing>)
<body>)
For example:
(for ((i 0) (< i 10) (set! i (+ 1 i)))
(display i)
(newline))
which would print 0 through 9. Unlike C, i
's scope is limited.
Now extend for
so you can do (for (<var> in <list>) …)
to iterate
over lists. This is (almost) equivalent to Common Lisp's dolist
macro.
Generalize the results of Part 2 so that the user can "program" the
for
-loop with iteration semantics of any data type. As an example of
what this may mean, though you might do it differently, is to have a
table of predicates, like so in Common Lisp:
(defvar *for-loop-extensions*
; predicate ???
'((listp ???)
(vectorp ???)
...))
;; for-loop should now work with at least
;; lists and vectors.
(for (i in #(1 2 3))
(print i))
I've put ???
so as to not spoil what they could be.
posted on 2018-01-30
For better or for worse, some disciplines use degrees as a measure of
angle. Write a macro with-degrees
which causes the trigonometric
functions sin
, cos
, and tan
to use degrees and not radians
within the lexical scope of with-degrees
. For example,
(with-degrees
(+ (sin 30) (sin 90)))
should return 1.5
.
Note: This is much less straightforward in Common Lisp than it is in Scheme due to Common Lisp's packaging rules.
posted on 2018-01-30
In challenge #8,
you wrote a define
macro called define*
. However, this can be
awkward and even inefficient when we have a cond
or a
case
. Consider:
(define* (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else (+ (fib (- n 1))
(fib (- n 2))))))
Each time we compute a yet-uncomputed Fibonacci number, we have to
check if it's 0
first, then 1
, then we can proceed to compute.
In this challenge, we want to be allowed to define constant cases
which add to the memoization table immediately. Let's call this
definition procedure def
. The syntax looks as follows:
(def fib
(0) => 0
(1) => 1
(n) => (+ (fib (- n 1))
(fib (- n 2))))
This will create a function fib
which will have the results of (fib
0)
and (fib 1)
memoized, and allow for the general case. When we do
call the general case for an unmemoized function, we no longer have to
crawl the cond
, because there is none. So we save comparisons each
time it's called.
For multi-argument functions, it would be illegal to have clauses like
(4 b c) => ...
. You can safely assume the last case will be the
variable case.