Lisp function count recurring a's in list - lisp

I am trying to write a function that takes only a list as a parameter and counts the number of times the symbol a appears in the list, without counting any a's in a sublist within the list.
I am very new to Lisp so please use as basic code as possible so I could understand what it is doing, even if it is inefficient.
(defun times (l)
(setf x 'a)
(cond
((null l) nil)
((equal x (car l)) (+ 1 (times x (cdr L))))
(t (times x(cdr l)))))
So (times '(a b (a) c)) should return 1. However I am getting the error that with this line times is getting two arguments when it should be getting one.

There are multiple ways to implement this in Common Lisp. The example should be small enough for you to follow (test them).
Recursive implementation
Your approach is fine, except you have small errors (in addition to the other ones reported in comments):
Do not use SETF for undeclarded variables.
Do not return NIL in the base case: your function should return a number.
Also, your code coud be better formatted, and you should use longer names (lowercase l in particular is hard to read)
Here is a modified version:
(defun times (list element)
(cond
((null list) 0)
((equal (car list) element) (1+ (times (cdr list) element)))
(t (times (cdr list) element))))
Example
Let's TRACE the function:
CL-USER> (trace times)
Here is the execution trace:
CL-USER> (times '(a b c d a f a) 'a)
0: (TIMES (A B C D A F A) A)
1: (TIMES (B C D A F A) A)
2: (TIMES (C D A F A) A)
3: (TIMES (D A F A) A)
4: (TIMES (A F A) A)
5: (TIMES (F A) A)
6: (TIMES (A) A)
7: (TIMES NIL A)
7: TIMES returned 0
6: TIMES returned 1
5: TIMES returned 1
4: TIMES returned 2
3: TIMES returned 2
2: TIMES returned 2
1: TIMES returned 2
0: TIMES returned 3
3
You can see that the call stack grows for each and every element visited in the list. It is usually a bad practice, especially when the recursive function is basically implementing a loop.
Loops
Use a simple LOOP:
(defun times (list element)
(loop for value in list count (equal value element)))
Alternatively, use DOLIST:
(defun times (list element)
(let ((counter 0))
(dolist (value list counter)
(when (equal element value)
(incf counter)))))
Here above, counter is a local variable introduced by LET. It is incremented with INCF inside the loop, only WHEN the comparison holds. Finally, counter is returned from the dolist (the third parameter indicates which form to evaluate to have the result value). The return value of dolist is also the return value of the let and the whole function.
This can be rewritten also with DO:
(defun times (list element)
(do ((counter 0)) ((null list) counter)
(when (equal element (pop list))
(incf counter))))
The first list in do introduces bindings, the second list is a termination test (here we stop when the list is empty) followed by a result form (here, the counter). Inside the body of the loop, we POP elements from the input list and do the comparison, as before.
Tail-recursive implementation
If you want to keep a recursive implementation, add an accumulator and compute all the intermediate results before entering a recursive evaluation. If all results are passed as function arguments, there is no need to keep track of intermediate results at each step of the recursion, which eliminates the need to even allocate stack frames. The ability to perform tail-call elimination is not expressly required by the specification of the language, but it is typically available in most implementations.
(defun times (list element)
(labels ((recurse (list counter)
(cond
((null list) counter)
((equal (first list) element)
(recurse (rest list) (1+ counter)))
(t (recurse (rest list) counter)))))
(recurse list 0)))
Here above, recurse is a local recursive function introduced by LABELS, which accepts a counter parameter. The difference with the original recursive function is that when the list is empty, it returns the current value of counter instead of zero. Here, the result of recurse is always the same as the value returned by recursive invocations: the compiler can just rebind inputs and perform a jump instead of allocating intermediate frames.
Higher-order functions
Here are yet two other ways, based on higher-order functions.
First, the usual way to define functions with accumulators is with REDUCE (known as fold in other languages). There is no explicit mutation:
(defun times (list element)
(reduce (lambda (counter value)
(if (equal value element)
(1+ counter)
counter))
list
:initial-value 0))
The anonymous function accepts the current state of the accumulator, the current value being visited in the list, and shall compute the next state of the accumulator (the counter).
Alternatively, call MAP with a nil first argument, so that the iteration is only done for effects. The anonymous function established by the LAMBDA form closes over the local counter variable, and can increment it when comparison holds. It is similar to the previous dolist example w.r.t. incrementing the counter through side-effects, but the iteration is done implicitly with map.
(defun times (list element)
(let ((counter 0))
(map ()
(lambda (value)
(when (equal value element)
(incf counter)))
list)
counter))
Built-in
For your information, there is a built-in COUNT function:
(defun times (list element)
(count element list :test #'equal))

Here is some code which might help. It uses tail recursion and defines a helper function which is called recursively and keeps track of the number of times the symbol 'a appears with the argument count. The helper function takes two arguments, but the functino count-a takes one. Count-a calls the helper with the list l and the total number of times it has counted the symbol 'a at the beginning, which is zero to kick off the recursive calls.
(defun count-a (l)
(labels ((helper (x count)
(if (equalp 'a (car x)) (incf count))
(cond ((null x) count)
(t (helper (cdr x) count)))))
(helper l 0)))
You can also use the loop macro:
(defun count-a-with-a-loop (l)
(loop for i in l count (equalp 'a i))\
Or as Coredump points out:
(defun count-a-with-count (l)
(count 'a l :test #'equal))
Note the '# character before equal lets the Lisp interpreter know that equal is a function, known as a reader macro.

If you use a Lisp compiler (like SBCL) you might see this:
* (defun times (l)
(setf x 'a)
(cond
((null l) nil)
((equal x (car l)) (+ 1 (times x (cdr L))))
(t (times x(cdr l)))))
; in: DEFUN TIMES
; (TIMES X (CDR L))
;
; caught WARNING:
; The function was called with two arguments, but wants exactly one.
;
; caught WARNING:
; The function was called with two arguments, but wants exactly one.
;
; caught WARNING:
; undefined variable: X
;
; compilation unit finished
; Undefined variable:
; X
; caught 3 WARNING conditions
The Lisp compiler tells you that there are three errors in your code.
Let's fix the undefined variable problem first, by introducing a local variable x:
(defun times (l)
(let ((x 'a))
(cond
((null l) nil)
((equal x (car l)) (+ 1 (times x (cdr L))))
(t (times x (cdr l))))))
Now, we look at the other two: you call TIMES with two arguments.
We can just remove the x argument, since it is not needed:
(defun times (l)
(let ((x 'a))
(cond
((null l) nil)
((equal x (car l)) (+ 1 (times (cdr L))))
(t (times (cdr l))))))
It may be more useful to be able to search for more things, so we add x to the argument list and add it to the call arguments.
(defun times (x l)
(cond
((null l) nil)
((equal x (car l)) (+ 1 (times x (cdr L))))
(t (times x (cdr l)))))
Now the function should always return a number, not NIL for an empty list:
(defun times (x l)
(cond
((null l) 0)
((equal x (car l)) (+ 1 (times x (cdr L))))
(t (times x (cdr l)))))
Since Lisp has functions like first and rest, we can replace car and cdr:
(defun times (x l)
(cond
((null l) 0)
((equal x (first l)) (+ 1 (times x (rest l))))
(t (times x (rest l)))))

Related

Common Lisp - Function which return an element appears n times in a list

I'm trying to write a function which return an element appears n times in a list.
For example, for a list like : (setq lst '(a b b b c)), the function returns :
count-list (lst 3) --> b
But when there is two element (or more) which appears in n same time, the function only returns the first element :
count-list (lst 1) --> a
Instead of
count-list (lst 1) --> a b
Here is the function :
(defun count-list (lst nb)
(loop for x in lst do
(if (eq (count x lst) nb)
(return x)
)
)
)
What did I miss ?
return tells the count-list function to exit immediately as soon as it finds a hit, so it won't look for other elements matching the count.
One possible solution is this:
(defun count-list (lst n)
(remove-duplicates
(mapcan #'(lambda (x)
(when (eql (count x lst) n)
(list x) ))
lst )))
However, this is very inefficient since for each item the list has to be traversed twice, one for the function itself and one for count, so this would take a time proportional to the square of the length of the list.
A more efficient way would be to accumulate the values (e.g. in an assoc list) and select at the end those items matching the input count number.
(defun count-list (lst n)
(let* (count-list pair)
(dolist (x lst)
(if (setq pair (assoc x count-list))
(incf (cdr pair))
(push (cons x 1) count-list) ))
(mapcan #'(lambda (pair)
(when (eql n (cdr pair))
(list (car pair)) ))
count-list )))
I never used LISP. I assume your problem is that your function returns at the first match. Either create an array in your function for storing all the elements appearing n times and return to that array, or, for example, in Python I would use print(x) so the function does not return at the first match, like in your case.

Common LISP: Make Your Own Union Function

I'm trying to make my own union function and realizing how much I dislike LISP. The goal is to give the function two lists and it will return a set theoretic union of the two. My attempted solution has grown increasingly complex with the same result: NIL. I can't change that from being the result no matter what I do.
I was thinking of building a separate list in my "removeDuplicates" function below, but then idk how I'd return that with recursion. I think what's happening is my "removeDuplicates" function eventually returns an empty list (as intended) but then an empty list is return at every level of the stack when the recursion unfurls (starts returning values up the stack) but I could be wrong. I've always had trouble understanding recursion in detail. The code is below.
(defun rember (A LAT)
(cond
((null LAT) ())
((EQ (car LAT) A) (cdr LAT))
(T (cons (car LAT)(rember A (cdr LAT))))
)
)
(defun my_member (A LAT)
(cond
((null LAT) nil)
((EQ (car LAT) A) T)
(T (my_member A (cdr LAT)))
)
)
(defun removeDuplicates (L)
(cond
((null L) '())
((my_member (car L) (cdr L)) (rember (car L) L) (removeDuplicates (cdr L)))
(T (removeDuplicates (cdr L)))
)
)
(defun my_union (A B)
(setq together(append A B))
(removeDuplicates together)
)
I'm aware most people are not a fan of this format of LISP code, but I prefer it. It allows me to see how parentheses line up better than if you just put all the closing parentheses together at the end of functions and condition blocks.
If I run (my_union '(a b) '(b c)) for example, the result is NIL.
When you call removeDuplicates recursively in the last condition, you're not combining the result with the car of the list, so you're discarding that element.
You're also not using the result of rember.
(defun removeDuplicates (L)
(cond
((null L) '())
((my_member (car L) (cdr L))
(cons (car L)
(removeDuplicates
(rember (car L) (cdr L))
))
)
(T (cons (car L) (removeDuplicates (cdr L))))
)
)
Here's a simple, obvious, union function:
(defun union/tfb (&rest lists)
;; compute the union of any number of lists, implicitly using EQL
(labels ((union/spread (l1 ls)
;; UNION/SPREAD just exists to avoid the impedance
;; mismatch in argument convention
(if (null ls)
l1
(let ((result l1))
(destructuring-bind (l2 . more) ls
(dolist (e l2 (union/spread result more))
(pushnew e result)))))))
(union/spread (first lists) (rest lists))))
I think this is reasonably natural CL, although of course the whole point of using a language like CL is avoiding endless wheel-reinvention like this.
So the rules of the game perhaps say you're not allowed to use PUSHNEW: well, you can easily can replace it with a conditional involving MEMBER:
(defun union/tfb (&rest lists)
;; compute the union of any number of lists, implicitly using EQL
(labels ((union/spread (l1 ls)
;; UNION/SPREAD just exists to avoid the impedance
;; mismatch in argument convention
(if (null ls)
l1
(let ((result l1))
(destructuring-bind (l2 . more) ls
(dolist (e l2 (union/spread result more))
;; Really use PUSHNEW for this
(unless (member e result)
(setf result (cons e result)))))))))
(union/spread (first lists) (rest lists))))
And perhaps you are also not allowed to use MEMBER: well you can easily write a predicate which does what you need:
(defun union/tfb (&rest lists)
;; compute the union of any number of lists, implicitly using EQL
(labels ((union/spread (l1 ls)
;; UNION/SPREAD just exists to avoid the impedance
;; mismatch in argument convention
(if (null ls)
l1
(let ((result l1))
(destructuring-bind (l2 . more) ls
(dolist (e l2 (union/spread result more))
;; Really use MEMBER for this, and in fact
;; PUSHNEW
(unless (found-in-p e result)
(setf result (cons e result))))))))
(found-in-p (e list)
;; is e found in LIST? This exists only because we're not
;; meant to use MEMBER
(cond ((null list) nil)
((eql e (first list)) t)
(t (found-in-p e (rest list))))))
(union/spread (first lists) (rest lists))))
If you want the result to be a set with unique elements even if the first list is not you can trivially do that (note CL's UNION does not promise this, and you can get the same result with the earlier version of UNION/TFB by (union/tfb '() ...)):
(defun union/tfb (&rest lists)
;; compute the union of any number of lists, implicitly using EQL
(labels ((union/spread (l1 ls)
;; UNION/SPREAD just exists to avoid the impedance
;; mismatch in argument convention
(if (null ls)
l1
(let ((result l1))
(destructuring-bind (l2 . more) ls
(dolist (e l2 (union/spread result more))
;; Really use MEMBER for this, and in fact
;; PUSHNEW
(unless (found-in-p e result)
(setf result (cons e result))))))))
(found-in-p (e list)
;; is e found in LIST? This exists only because we're not
;; meant to use MEMBER
(cond ((null list) nil)
((eql e (first list)) t)
(t (found-in-p e (rest list))))))
(union/spread '() lists)))
Finally if the rules prevent you using iterative constructs and assignment you can do that too:
(defun union/tfb (&rest lists)
;; compute the union of any number of lists, implicitly using EQL
(labels ((union/spread (l1 ls)
;; UNION/SPREAD just exists to avoid the impedance
;; mismatch in argument convention
(if (null ls)
l1
(union/loop l1 (first ls) (rest ls))))
(union/loop (result l more)
;; UNION/LOOP is just an iteration
(if (null l)
(union/spread result more)
(destructuring-bind (e . remainder) l
(union/loop (if (found-in-p e result)
result
(cons e result))
remainder more))))
(found-in-p (e list)
;; is e found in LIST? This exists only because we're not
;; meant to use MEMBER
(cond ((null list) nil)
((eql e (first list)) t)
(t (found-in-p e (rest list))))))
(union/spread '() lists)))
The final result of all these changes is something which is, perhaps, very pure, but is not natural CL at all: something like it might be more natural in Scheme (albeit not gratuitously replacing MEMBER with a home-grown predicate like this).
One way to test your Common Lisp code is to ask your interpreter to TRACE functions:
(trace removeDuplicates my_member rember)
To avoid having too many traces, use small examples.
First, let's try with an empty list; this is an example from the REPL ("read eval print loop"), tested with SBCL, while in the "SO" package (StackOverflow); the trace is printed a bit indented, a is numbered according to the depth of the recursion. Here the call is not recursive and terminates right away:
SO> (removeduplicates nil)
0: (SO::REMOVEDUPLICATES NIL)
0: REMOVEDUPLICATES returned NIL
NIL
This works, let's try an example with a singleton list, where there is obviously no duplicate:
SO> (removeduplicates '(1))
0: (SO::REMOVEDUPLICATES (1))
1: (SO::MY_MEMBER 1 NIL)
1: MY_MEMBER returned NIL
1: (SO::REMOVEDUPLICATES NIL)
1: REMOVEDUPLICATES returned NIL
0: REMOVEDUPLICATES returned NIL
NIL
removeDuplicate calls my_member, which correctly returns nil, followed by a recursive call to removeDuplicates with nil, which correctly returns nil. There is however a problem because then, the outermost call returns nil too, which is incorrect.
Looking at the trace, we have to look back at the code to find a place where my_member is called, followed by a recursive call to removeDuplicates. There is only one place wher my_member is called, as a test to the second clause in the cond;
Since the result is nil for that test, the next clause is tried, in that case the default case:
(cond
...
;; this is the call to my_member (= nil)
((my_member (car L) (cdr L)) ...)
;; this is the recursive call
(t (removeDuplicates (cdr L))))
The value of the cond is the one given by the last (removeDuplicates (cdr L)), which just does not retain the existing elements in front of L. If you were mutating a sequence, you could just recurse down the subsequence and ignore the previous elements: in that case the caller would still hold a reference to the original sequence, which would get its element removed by a side-effect of your functions. But here you are following a strictly immutable approach, and you have to recontruct a list as a return value.
In other words, removeDuplicates is expressed as: return a new list which contains the same elements as the original list, but without duplicates.
So you have to add (car L) in front of (removeDuplicates (cdr L)).
(defun removeDuplicates (L)
(cond
((null L) '())
((my_member (car L) (cdr L)) (rember (car L) L) (removeDuplicates (cdr L)))
(T (cons (car L)
(removeDuplicates (rest L))))))
Let's test:
SO> (removeduplicates '())
0: (SO::REMOVEDUPLICATES NIL)
0: REMOVEDUPLICATES returned NIL
NIL
SO> (removeduplicates '(1))
0: (SO::REMOVEDUPLICATES (1))
1: (SO::MY_MEMBER 1 NIL)
1: MY_MEMBER returned NIL
1: (SO::REMOVEDUPLICATES NIL)
1: REMOVEDUPLICATES returned NIL
0: REMOVEDUPLICATES returned (1)
(1)
You can test with a longer list (without duplicates), the result is correct, but the trace is longer.
Now, let's add duplicates:
SO> (removeduplicates '(1 2 2 1))
0: (SO::REMOVEDUPLICATES (1 2 2 1))
1: (SO::MY_MEMBER 1 (2 2 1))
2: (SO::MY_MEMBER 1 (2 1))
3: (SO::MY_MEMBER 1 (1))
3: MY_MEMBER returned T
2: MY_MEMBER returned T
1: MY_MEMBER returned T
1: (SO::REMBER 1 (1 2 2 1))
1: REMBER returned (2 2 1)
1: (SO::REMOVEDUPLICATES (2 2 1))
2: (SO::MY_MEMBER 2 (2 1))
2: MY_MEMBER returned T
2: (SO::REMBER 2 (2 2 1))
2: REMBER returned (2 1)
2: (SO::REMOVEDUPLICATES (2 1))
3: (SO::MY_MEMBER 2 (1))
4: (SO::MY_MEMBER 2 NIL)
4: MY_MEMBER returned NIL
3: MY_MEMBER returned NIL
3: (SO::REMOVEDUPLICATES (1))
4: (SO::MY_MEMBER 1 NIL)
4: MY_MEMBER returned NIL
4: (SO::REMOVEDUPLICATES NIL)
4: REMOVEDUPLICATES returned NIL
3: REMOVEDUPLICATES returned (1)
2: REMOVEDUPLICATES returned (2 1)
1: REMOVEDUPLICATES returned (2 1)
0: REMOVEDUPLICATES returned (2 1)
(2 1)
The result is correct (order does not matter).
So far, our tests are good.
You might not have identified the other problem in that function, namely that all calls to rember are useless, and frankly this is not necessarily easy to spot with the trace. But looking at the code, it should be clear if you write code to have little side-effects that the following clause calls (rember ...) for nothing:
((my_member (car L) (cdr L)) (rember (car L) L) (removeDuplicates (cdr L)))
A cond clause has for syntax (TEST . BODY), where BODY is a sequence of expressions that evaluates like a PROGN: the value of a PROGN is the value of its last clause, all intermediate clauses are only used for their side-effects. For example:
(progn
(print "I am here")
(* 10 3))
Here above, the call to PRINT returns a value, but it is discarded: the value of the enclosing PROGN is 30.
In your code, rember does no side-effect, and its return value is discarded. Just remove it:
(defun removeDuplicates (L)
(cond
((null L) '())
((my_member (car L) (cdr L))
(removeDuplicates (cdr L)))
(T (cons (first L)
(removeDuplicates (rest L))))))
I would write the same code as follows, personally:
(defun remove-duplicate-elements (list)
(when list
(let ((head (first list))
(tail (remove-duplicate-elements (rest list))))
(if (member head tail) tail (cons head tail)))))
Here is a remove-dupes that removes duplicates from a list in O(n) time using a hash table. It supports a custom equality function (which must be eq, eql, equal or `equalp) and a custom test function, so that any aspect of an item can be treated as the key.
(defun remove-dupes (list &key (test #'eql) (key #'identity))
(let ((hash (make-hash-table :test test)))
(loop for item in list
for item-key = (funcall key item)
for seen = (gethash item-key hash)
unless seen collect item and
do (setf (gethash item-key hash) t))))
For instance, suppose we have the assoc list ((a . 1) (a . 2) (b . 3) (c . 4) (b . 4)). We'd like to remove duplicates by car:
[1]> (remove-dupes '((a . 1) (a . 2) (b . 3) (c . 4) (b . 4)) :key #'car)
((A . 1) (B . 3) (C . 4))
Only the leftmost A, B and C entries are reported; the duplicates are suppressed. Now let's do it by cdr:
[2]> (remove-dupes '((a . 1) (a . 2) (b . 3) (c . 4) (b . 4)) :key #'cdr)
((A . 1) (A . 2) (B . 3) (C . 4))
The (b . 4) got culled due to the duplicated 4 value.
But, why do all this, when Common Lisp provides a remove-duplicates function (not to mention union).
remove-duplicates is more general than what I have here: it handles sequences, rather than just lists, so it works on vectors and strings. It has more keyword parameters.

A varaible independent its local scope

I tried to solve the twoSum Problem with primitive tools of car and cdr
Given an array of integers, return indices of the two numbers such
that they add up to a specific target.
You may assume that each input would have exactly one solution, and
you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
The idea is to take a x from nums, then check if x's complement (target -x) is member of set nums-x
The key logic is
if ((memberp complement (remove-first x nums))
then (list x complement))
Begin with a helper function try nums
(defun two-sum (nums target)
(try nums))
The main function:
(defun try (nums)
(let ((x (car nums))
(complement (- target x)))
(cond
((null x) '())
((memberp complement (remove-first x nums))
(list x complement))
(t (try (cdr nums)))
)))
Then I realize that nums in ((memberp complement (remove-first x nums)) should be stay unchanged and independent from the local scope of let.
How could get such a nums?
memberp and `remove-first'
(defun remove-first (item sequence)
(filter (lambda (x) (not (= x item)))
sequence))
(defun filter (predicate sequence)
(cond ((null sequence) nil)
((funcall predicate (car sequence))
(cons (car sequence)
(filter predicate
(cdr sequence))))
(t (filter predicate
(cdr sequence)))))
(defun memberp(item x)
(cond ((null x) 'false)
((equal item (car x)) x)
(t (memq item (cdr x)))))
Here is a simple recursive function to compute the indexes:
(defun two-sum (list target &optional (pos 0))
(if (null (cdr list))
nil
(let ((p (my-position (- target (car list)) list)))
(if p
(list pos (+ pos p))
(two-sum (cdr list) target (1+ pos))))))
(defun my-position (element list &optional (pos 0))
(cond ((null list) nil)
((eql element (car list)) pos)
(t (my-position element (cdr list) (1+ pos)))))
The function is initially called with the list and the target. The parameter pos, which initially is not passed to the function, is assigned automatically to 0, and in the subsequent calls it will be incremented by one, so that it tracks the index of the current element of the list.
The first condition checks if the list has less than two elements: if it is empty (or its cdr is empty) the result is nil since no solution is possibile (note that in Common Lisp (cdr nil) is nil).
Otherwise we compute the position of the “complement” of the number in the rest of the list (note that position is a primitive function, so I called my-position its rewriting). If the element is present, we return both pos and (+ pos p) (since the position found is relative to the current position), otherwise (my-position returns nil when no element is found) we recur on the rest of the list.
Note that with this method there is no need to consider every time all the elements of the list.

Mutual Recursion in Common Lisp

This is the Common Lisp code:
(defun take (L)
(if (null L) nil
(cons (car L) (skip (cdr L)))))
(defun skip (L)
(if (null L) nil
(cons (car L) (take (cdr L)))))
The idea here is that, "take" will give all the odd sequence elements in the input list and "skip" will give all the even sequence elements in the input list. However, in both cases the entire list is returned.
What is the error in this code? Is this something to do with how CL handles lists, because the similar code in SML gives the desired output.
fun take(lst) =
if lst = nil then nil
else hd(lst)::skip(tl(lst))
and
skip(lst) =
if lst = nil then nil
else hd(lst)::take(tl(lst));
To expound on what Sylwester has said, your skip is wrong in both Lisp and SML. It should be
(defun take (L) ; even-indexed elements of a list L
(if (not (null L))
(cons (car L) (skip (cdr L)))))
(defun skip (L) ; odd-indexed elements of a list L
(if (not (null L))
(take (cdr L))))
and
fun take(lst) =
if lst = nil then nil
else hd(lst)::skip(tl(lst))
and
skip(lst) =
if lst = nil then nil
else take(tl(lst));
The take and skip are identical so that is no mystery. skip should just tail call instead of cons-ing. It's the consing that makes the return here.
It's worth pointing out that indexing in Common Lisp (like many other programming languages) starts with 0, so the even-indexed elements of a list are the first, the third, the fifth, and so on, since those have indices 0, 2, 4, etc. It's also worth noting that in Common Lisp, you can take the rest of the empty list and get back the empty list. (You can't do this in every Lisp, though. E.g., in Scheme it's an error to call cdr on something that's not a pair.) This means that you can implement even-elements and odd-elements rather easily. even-elementsjust returns a list of the first element, and the odd elements of the rest of the list. odd-elements returns the even-elements of the rest of the list:
(defun even-elements (list)
(if (endp list) list
(list* (first list) (odd-elements (rest list)))))
(defun odd-elements (list)
(even-elements (rest list)))
These behave in the expected fashion:
CL-USER> (even-elements '(0 1 2 3 4 5))
(0 2 4)
CL-USER> (odd-elements '(0 1 2 3 4 5))
(1 3 5)
Of course, if you note that the call to (odd-elements x) is just a call to (even-elements (rest x)), we could have implemented even-elements as follows, and had the same result:
(defun even-elements (list)
(if (endp list) list
(list* (first list) (even-elements (rest (rest list))))))

Lisp - Remove instances from a list of pairs

I want to create a function in lisp that receives a number and a list of pairs and iterates through the list of pairs and removes the ones in which the result of the division between the first element of the pair, and the second element of the same pair is different from the number passed as an argument. In the end it returns a list with only the ones in which the result of the division is the same.
I have the following code so far:
(defun retira-terco(num l1)
(cond ((null l1) ())
((not (equal num (/ (car(first l1)) (cdr(first l1)))))
(retira-terco num (rest l1)))
(t (cons (first l1) (retira-terco num (rest l1))))))
When I try to run this example with a real example I get the following error:
Error: `(1)' is not of the expected type `NUMBER'
What am I doing wrong?
The problem with your code is in this line:
(/ (car(first l1)) (cdr(first l1)))
(car (first l1)) evaluates to a number, but (cdr (first l1)) evaluates to a list. You probably meant (cadr (first l1)).
That said, this code isn't that great from a lispiness point of view. You have a condition you want to filter on. Use higher order programming to express that more like this:
(defun foo (num lst)
(remove-if (lambda (item)
(equal num
(/ (car item)
(cadr item))))
lst)))