Counting numbers in a list - lisp

Is there anyone who can help me to write a function in common LISP that counts the numbers in a list?
The code that I have written is below, but it does not work!
(defun count-numbers(lst)
(let(result()))
(dolist(number lst)
(push number result))
(length result))
For example, when I enter this query "(count'(r 4 f d w 2 3 4 1 z))", I must get 5.

Since it's homework, I'll just give some pointers. First: simplicity. If you are new to Common-Lisp, just use its basic features. For example: recursion. In pure functional style. Think about something like this:
(defun count (list counter)
;; something
)
we first check list. If it's empty, we already checked all the elements, so we return counter. If list is not empty, we
take its first element
we check if it's a number
it's a number! We recursively call count on the rest of the list and with counter = counter + 1
it's not a number! We recursively call count on the rest of the list with counter the same as before
Use (numberp n). It returns T if n is a number, NIL if not.

(defun count-numbers (lst)
(let (result ()))
(dolist (number lst)
(push number result))
(length result))
Check the indentation. Is that what you wanted? Maybe not.
Then you also push all elements to the result list? Is that what you want?
Here is a list of functions on numbers. http://www.lispworks.com/documentation/HyperSpec/Body/c_number.htm
Maybe there is one you need?
This is a good introductory Lisp book for download: http://www.cs.cmu.edu/~dst/LispBook/

I'd say there are a variety of ways to solve this, one would be an imperative loop, like the mostly correct solution already written, a recursive counting function (which is probably the worst way since there's no guarantee in CL that you won't blow the stack), or the functional approach you would probably actually use in production. The last one would be this:
(defun count-numbers (list) (count-if #'numberp list))

Related

Find max in lisp

I am trying to do Recursive method to find max value in list.
Can anyone explain where I made the mistake on this code and how to approach it next time.
(defun f3 (i)
(setq x (cond (> (car (I)) (cdr (car (I))))
(f3 (cdr (I)))))
)
(f3 '(33 11 44 2) )
also I tried this following method and didn't work:
(defun f3 (i)
(cond ((null I )nil )
(setq x (car (i))
(f3(cdr (i)))
(return-from max x)
)
Thanks a lot for any help. I am coming from java if that helps.
If you're working in Common Lisp, then you do this:
(defun max-item (list)
(loop for item in list
maximizing item))
That's it. The maximizing item clause of loop determines the highest item value seen, and implicitly establishes that as the result value of loop when it terminates.
Note that if list is empty, then this returns nil. If you want some other behavior, you have to work that in:
(if list
(loop for item in list
maximizing item))
(... handle empty here ...))
If the number of elements in the list is known to be small, below your Lisp implementation's limit on the number of arguments that can be passed to a function, you can simply apply the list to the max function:
(defun max-item (list)
(apply #'max list))
If list is empty, then max is misused: it requires one or more arguments. An error condition will likely be signaled. If that doesn't work in your situation, you need to add code to supply the desired behavior.
If the list is expected to be large, so that this approach is to be avoided, you can use reduce, treating max as a binary function:
(defun max-item (list)
(reduce #'max list))
Same remarks regarding empty list. These expressions are so small, many programmers will avoid writing a function and just use them directly.
Regarding recursion, you wouldn't use recursion to solve this problem in production code, only as a homework exercise for learning about recursion.
You are trying to compute the maximum value of a list, so please name your function maximum and your parameter list, not f3 or i. You can't name the function max without having to consider how to avoid shadowing the standard max function, so it is best for now to ignore package issues and use a different name.
There is a corner case to consider when the list is empty, as there is no meaningful value to return. You have to decide if you return nil or signal an error, for example.
The skeleton is thus:
(defun maximum (list)
(if (null list)
...
...))
Notice how closing parentheses are never preceded by spaces (or newlines), and opening parentheses are never followed by spaces (or newlines). Please note also that indentation increases with the current depth . This is the basic rules for Lisp formatting, please try following them for other developers.
(setq x <value>)
You are assigning an unknown place x, you should instead bind a fresh variable if you want to have a temporary variable, something like:
(let ((x <value>))
<body>)
With the above expression, x is bound to <value> inside <body> (one or more expressions), and only there.
(car (i))
Unlike in Java, parentheses are not used to group expressions for readability or to force some evaluation order, in Lisp they enclose compound forms. Here above, in a normal evaluation context (not a macro or binding), (i) means call function i, and this function is unrelated to your local variable i (just like in Java, where you can write int f = f(2) with f denoting both a variable and a method).
If you want to take the car of i, write (car i).
You seem to be using cond as some kind of if:
(cond (<test> <then>) <else>) ;; WRONG
You can have an if as follows:
(if <test> <then> <else>)
For example:
(if (> u v) u v) ;; evaluates to either `u` or `v`, whichever is greater
The cond syntax is a bit more complex but you don't need it yet.
You cannot return-from a block that was undeclared, you probably renamed the function to f3 without renaming that part, or copied that from somewhere else, but in any case return-from is only needed when you have a bigger function and probably a lot more side-effects. Here the computation can be written in a more functionnal way. There is an implicit return in Lisp-like languages, unlike Java, for example below the last (but also single) expression in add evaluates to the function's return value:
(defun add-3 (x)
(+ x 3))
Start with smaller examples and test often, fix any error the compiler or interpreter prints before trying to do more complex things. Also, have a look at the available online resources to learn more about the language: https://common-lisp.net/documentation
Although the other answers are right: you definitely need to learn more CL syntax and you probably would not solve this problem recursively in idiomatic CL (whatever 'idiomatic CL' is), here's how to actually do it, because thinking about how to solve these problems recursively is useful.
First of all let's write a function max/2 which returns the maximum of two numbers. This is pretty easy:
(defun max/2 (a b)
(if (> a b) a b))
Now the trick is this: assume you have some idea of what the maximum of a list of numbers is: call this guess m. Then:
if the list is empty, the maximum is m;
otherwise the list has a first element, so pick a new m which is the maximum of the first element of the list and the current m, and recurse on the rest of the list.
So, we can write this function, which I'll call max/carrying (because it 'carries' the m):
(defun max/carrying (m list)
(if (null list)
m
(max/carrying (max/2 (first list) m)
(rest list))))
And this is now almost all we need. The trick is then to write a little shim around max/carrying which bootstraps it:
to compute the maximum of a list:
if the list is empty it has no maximum, and this is an error;
otherwise the result is max/carrying of the first element of the list and the rest of the list.
I won't write that, but it's pretty easy (to signal an error, the function you want is error).

Beginner LISP: At what stage in a Do Loop can I implement an IF condition?

I am designing a simple function (for class, so please no complete done-for-you answers) that returns the first odd integer in a list, or 'none if there are none.
I have a working code for finding the odd number:
(defun first-odd (lst)
(do ((numbers lst (cdr numbers)))
((oddp (car numbers)) (car numbers))))
but what I can't seem to figure out is where to place the IF conditional (which is required for the assignment) to produce "NONE" if the list is only even #s, or presumably NIL.
Do I make the exit point of the DO itself the IF conditional? Or does it go before/after?
I'm working on something like this (although I have a feeling it's wrong):
(defun first-odd (lst)
(do ((numbers lst (cdr numbers)))
((if (oddp (car numbers))
(car numbers)
(print 'none)))))
Or can someone advise me on 'where' to place the IF? Sorry for the truly beginner takes, but the prof didn't provide much documentation for DO and I've been scratching my head all weekend. Thanks in advance.
DO takes three arguments: the first one is the list of variables with their initial values and the subsequent values; the second is the terminating condition, i.e. when to exit the loop and the result to return; the third one is the body of the loop, and it's optional.
The second element contains an implicit if.
Your first code looks good with one exception: have you considered what happens if there are no odd elements in the list? You need then to test for the end of the list (i.e. when list is nil). Then, the result will depend on whether you exited the loop because an odd number was found, or a nil list. That's where you can use IF.

Make a sublist from list using LiSP

I have difficulty creating a sublist: '(((3)2)1)' from the list '(3 2 1)'.
I don't know where to start, any help would be greatly appreciated.
Take a careful look at the input. You'll see that every list in the result is two elements long - except the first. Since we need to handle the first cons in one way, and all of the others another, we'll split the work between two functions, the second of which will be a loop:
(defun nest-left (list)
(if (null list)
nil
(nest-aux <?> (cdr list))))
(defun nest-aux (acc list)
(if (null list)
<?>
<?>))
I'll leave you to fill in the <?>s.

LISP Programming Exam Review Q

Using the built-in map and zip functions, define a Scheme function zipadd that takes two lists of numbers and returns the a list consisting of the corresponding elements added together. You may assume that the lists are the same length. For example (zipadd '(1 2 3) '(4 5 6)) is (5 7 9). (A correct solution not using zip and map will be worth 8 points.)
I am not sure how to do this. I would really like to know the solution before my exam tomorrow. Can anyone help me please?
For starters, Racket doesn't come with a zip procedure, although it's trivial to implement one:
(define (zip lst1 lst2)
(map list lst1 lst2))
Now regarding your question - a solution using only map is the simplest way to solve this problem and it's very similar to the above procedure, just think what could be used to fill the blank:
(define (zipadd lst1 lst2)
(map <???> lst1 lst2))
Although it's a bit more contrived, you can use zip to reach the same solution (and get full marks). Try to figure out how it works - zip sticks together all pairs of elements in both lists, creating a list of two-element lists. Afterwards, map will traverse that list and apply a procedure to each element (remember: each element is a list of two elements), creating a new list with the results:
(define (zipadd lst1 lst2)
(map (lambda (x) <???>) ; x is a list with two numbers, how to add them?
(zip lst1 lst2)))
Finally and for completeness' sake, a solution without using map or zip. It's an implementation of map for the special case where the numbers on both lists must be added pair-wise:
(define (zipadd lst1 lst2)
(if <???> ; if either list is empty (*)
<???> ; then return the empty list
(cons (+ <???> <???>) ; else add the first elements of both lists
(zipadd <???> <???>)))) ; and advance the recursion over both lists
(*) Remember: both lists are assumed to have the same length.
Try to write all the variations of the solution, it'll be interesting to compare different approaches to solve the same problem. And if you have to use map and zip to get full marks then by all means use the second version above, just be aware that's not the simplest nor the most efficient way to express the solution to the problem at hand.

CLISP - Reversing a simple list

I have to reverse the elements of a simple (single-dimension) list. I know there's a built-in reverse function but I can't use it for this.
Here's my attempt:
(defun LISTREVERSE (LISTR)
(cond
((< (length LISTR) 2) LISTR) ; listr is 1 atom or smaller
(t (cons (LISTREVERSE (cdr LISTR)) (car LISTR))) ; move first to the end
)
)
Output pretty close, but is wrong.
[88]> (LISTREVERSE '(0 1 2 3))
((((3) . 2) . 1) . 0)
So I tried to use append instead of cons:
(t (append (LISTREVERSE (cdr LISTR)) (car LISTR)))
But got this error:
*** - APPEND: A proper list must not end with 2
Any help?
I can give you a couple of pointers, because this looks like homework:
The base case of the recursion is when the list is empty (null), and not when there are less than two elements in the list
Consider defining a helper function with an extra parameter, an "accumulator" initialized in the empty list. For each element in the original list, cons it at the head of the accumulator. When the input list is empty, return the accumulator
As an aside note, the above solution is tail-recursive.
As a follow-up to Óscar López (and fighting the temptation to just write a different solution down):
Using both append and length makes the posted solution just about the least efficient way of reversing a list. Check out the documentation on cons and null for some better ideas on how to implement this.
Please, please indent properly.
Tail recursion really is both more efficient and reasonably simple in this case. Try it if you haven't already. labels is the form you want to use to define local recursive functions.
It may be worth your while to flip through The Little Schemer. It'll give you a better feel for recursion in general.
It's ok what you did. You only missed the composition of the result list.
Think about it: You have to append the 1-element list of the CAR to the end of the list of the reversed CDR:
(defun LISTREVERSE (LISTR)
(cons
((< (length LISTR) 2) LISTR) ; listr is 1 atom or smaller
(t (append (LISTREVERSE (cdr LISTR)) (list (car LISTR))))))
(defun listreverse (list)
(let (result)
(dolist (item list result)
(push item result))))
Don't use recursion in Common Lisp when there is a simple iterative way to reach the same goal. Common Lisp does not make any guarantees about tail recursion, and your tail recursive function invocation may not be optimized to a jump at the discretion of the compiler.
push prepends the item to the result
dolist has an optional third argument which is the value returned. It is evaluated when the loop is exited.