程序代做 COMP712 Tutorial #3: LISP Exercises – Simple Functions

COMP712 Tutorial #3: LISP Exercises – Simple Functions

1. What is printed given this in LISP?

(a.b)
a b

2. Write a function, Reverse-num, that given a number will return a number with a different sign unless the number is 0. If the latter, it returns 0.

> (reverse-num -10)
10
> (reverse-num 10)
-10
> (reverse-num 0)
0

(defun reverse-num (x)
(cond ((zerop x) 0)
(t (- x)))

3. Write a function, reverse-num2, that given a number will return an even number if it is odd and an odd number otherwise.

> (reverse-num2 -10)
-9
> (reverse-num2 11)
12
> (reverse-num2 0)
1

(defun reverse-num2 (x) (1+ x))

4. Write a function One-List which given 3 arguments will return them as a list:

> (one-list ‘(a b c d) ‘x ‘(y (r s)))
(a b c d x y (r s))

> (one-list ‘a ‘(b c) ‘d)
(a b c d)

The difficulty here is that the arguments are NOT uniform. That is, they are not lists or atoms but a mixture. One solution is to try to hack! – check each in turn and perform the needed actions:

(defun poor-one-list (a b c)
(cond ((and (listp a) (listp b) (listp c)) (append a b c))
((and (listp a) (listp b) (atom c)) (append a b (list c)))
((and (listp a) (atom b) (listp c))…….

The above is ugly. Other people have to read through the code to figure out what you are trying to do. A better solution is to turn the data into a uniform representation i.e all lists or all atoms. Which is better, list or atom?

In this case, it is better to turn them into a list, why? To do so, imagine you have a function (just like the given functions such as car, append, etc) that, given an argument, will return a list if it is not a list else return itself. Let’s call this function turn-into-list. Then, your problem is solved:

(defun one-list (a b c)
  (append (turn-into-list? a) (turn-into-list? b) (turn-into-list? c)))

But there is no such function. Well, we can write one:

(defun turn-into-list? (x) (if (listp x) x (list x)))

The above illustrates a functional approach to problem solving. Think of what functions you can use and if not available, implement the functions yourself. Alternatively, you could:

(defun one-list (a b c)
  (append (if (atom a) (list a) a) 
(if (atom b) (list b) b)
(if (atom c) (list c) c))))

5. Write a function TWELFTH which given a list will return the twelfth element in the list:

> (twelfth ‘(1 2 3 4 5))
nil
> (twelfth ‘(1 2 3 4 5 6 7 8 9 10 11 12 13))
12

(defun twelfth (L)
(cadddr (cddddr (cddddr L))))

6. Write a function First-list which given a list will return the first element in it which is a list:

> (first-list ‘(1 2 3 4 5))
nil

> (first-list ‘(1 2 (3) (4) 5))
(3)

(defun first-list (L)
(cond ((null L) nil)
((listp (car L)) (car L))
( t (first-list (cdr L)))))

7. Write a function Last-list which given a list will return the last element in it which is a list:

> (first-list ‘(1 2 3 4 5))
nil

> (first-list ‘(1 2 (3) (4) 5))
(4)

(defun last-list (L) (first-list (reverse L))) ; you can always reuse the function once you have defined it.

8. Write a function First-list1 which given a list will return the car of the first element in it which is a list:

> (first-list1 ‘(1 2 3 4 5))
nil

> (first-list1 ‘(1 2 (3) (4) 5))
3

(defun first-list1 (L)
(cond ((null L) nil)
((listp (car L)) (caar L))
( t (first-list1 (cdr L)))))

9. Write a function my-last which given a list will return the last element in the list:

> (my-last ‘(1 2 3 4 5))
5
> (my-last ‘(1))
1

(defun my-last (L) (car (reverse L))

10. Write a function oddlist which given a list will return all the odd numbers in it.

> (oddlist ‘(1 2 b (c 3) d))
(1)
> (oddlist ‘(2 4 6 8))
()

(defun oddlist (L)
(cond ((null L) L)
((oddp (car L)) (cons (car L) (oddlist (cdr L)))))
(t (oddlist (cdr L)))))

11. Write a function sum-all which given a list will return the sum of all the numbers in it provided the list contains numbers only.

> (sum-all ‘(1 2 b (c 3) d))
(1 2 b (c 3) d)

> (sum-all ‘(2 4 6 8))
20

(defun nums-only (L)
(cond ((null L) t)
((numberp (car L)) (nums-only (cdr L)))
(t nil)))

(defun sum-all (L)
(cond ((null L) nil)
((nums-only L) (my-sum L))
(t L)))

(defun my-sum (L)
(cond ((null L) 0)
(t (+ (car L) (my-sum (cdr L))))))