How to use MAPCAR to implement REMOVE-IF [closed] - lisp

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
How can I use the MAPCAR function to implement a function equivalent to REMOVE-IF, non-recursively in Common Lisp?

It is not possible with MAPCAR, because it always returns a list of the same length as the input (and you want a shorter list, if some of the input elements satisfy the predicate.)
But it is possible with the related function MAPCAN. If you
Apply the predicate to each element X.
If X satisfies the predicate, substitute (X)If X does not satisfy the predicate, substitute NIL
Concatenate the resulting lists
then you will have a list containing the elements that did not satisfy the predicate, as required.
MAPCAN will combine these operations, given a function that implements step #1.
Example:
(defun list-if-not (pred)
(lambda (x) (if (funcall pred x) nil (list x))))
(defun my-remove-if (pred lst)
(mapcan (list-if-not pred) lst))
(my-remove-if #'evenp '(1 2 3 4 5))
==> (1 3 5)
MAPCAR alone cannot do this, though you can combine it with NCONC (or APPEND) for the same result:
(defun my-remove-if (pred lst)
(apply #'nconc (mapcar (list-if-not pred) lst)))

Related

Defining a "minimum" function to return the minimum of a list using another function that returns the smaller of two numbers

(defun *smaller* (x y)
( if (> x y) y
x))
(defun *minimum* (lst)
(do ((numbers lst (cdr numbers))
(result (car numbers) (*smaller* result (car numbers))))
((null numbers) result)))
LISP says that variable "numbers" in "minimum" function is an unbound one although I think I've bound it to "lst". What am I missing?
Do binds in parallel. The expression for the initial value of result is (cdr numbers), and numbers is unbound there. Do* would work here.
Another approach to this problem is to try and think about it inductively.
an empty list has no minimum;
if the list is not empty, its first element is a candidate minimum:
if the rest of the list is empty it's the answer
else the candidate minumum is the smaller of the current candidate and the first element of the list, and carry on through the rest of the list.
This translates very naturally into Lisp:
(defun smaller (x y)
(if (< x y) x y))
(defun running-minimum (candidate tail)
(if (null tail)
candidate
(running-minimum (smaller candidate (first tail)) (rest tail))))
(defun minimum (list)
(when (null list)
(error "?")) ;ed is the standard text editor
(running-minimum (first list) (rest list)))
Notes
For good, if now mostly historical, reasons, CL makes no guarantees that code like this will be turned into an iterative process. Many implementations do so, but a conforming implementation need not, and even implementation which do so may not always do so, for instance in interpreted code or code compiled for ease of debugging. So a minimum function like the above is not really very idiomatic CL, and is certainly not completely safe if the code is meant to be portable.
However that is not my goal in this answer: one of the important things that you should get from learning lisp, in my opinion, is the ability to think inductively about solving problems. In other words to think about a class of problems which can be solved by starting from a simple base case and then steps which get from some general case closer to the base case, and then expressing this in code. This is a very different approach to programming than the approach which is natural in more imperative languages, and once you understand it it's a very powerful way of thinking.
As someone whose first serious language was FORTRAN (in the days when that was the correct way of writing its name even!) I think that this inductive approach is very important, and it's that which I wanted to get across here.
(defun smaller (x y)
"returns the smaller number"
(if (> x y)
y
x))
(defun minimum (list)
"returns the smallest number of a list"
(do* ((numbers list (rest numbers))
(result
(first numbers)
(if numbers
(smaller result (first numbers))
result)))
((null numbers) result)))
First of all, as pointed above, you should use do* instead of do, in order to bind the variables sequentially.
Second, you are testing (null numbers) to end the loop. However, when only one element is left to process, numbers is not nil but then it becomes (cdr numbers) which is nil. This nil value is what is being passed to *smaller* as second argument, and that's why you get the error message. To avoid this, you should test for (null (cdr numbers)) instead:
(defun *smaller* (x y)
( if (> x y) y
x))
(defun *minimum* (lst)
(do* ((numbers lst (cdr numbers))
(result (car numbers) (*smaller* result (car numbers))))
((null (cdr numbers)) result)))
This exits the loop when there is only one item left in the list.

Drracket lists adding only numbers while ignoring other data types [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Hello I need to create a function that consumes a list that sums up only numbers within the list and ignores any other type of data (strings etc)
Example (adding-only-numbers (cons 5 (cons "b" ( cons 2 (cons "whatsup" empty)))))
should come out to (cons 7 (cons "b" (cons "whatsup" empty)))
Keeping all the strings or other data types in order while collecting the numbers and adding them all up.
If there are no numbers, and only strings then it should be 0 at the front
Example (adding-only-numbers (cons "eb" (cons "b" ( cons (make posn 5 0) (cons "whatsup" empty)))))
should come out to (cons 0 (cons "eb" (cons "b" ( cons (make posn 5 0) (cons "whatsup" empty)))))
your help is much appreciated!
Since this smells a little like homework, I'll set you on the right track:
#!/usr/bin/racket
#lang racket
(define (sum lst)
(foldl (lambda (num sum)
(if (number? num) (+ sum num) sum))
0
lst))
(sum '(1 2 "hello"))
So this will return the summation of a flat list... Should be one more simple step to push this to the front of the list.
Note that the foldl function takes a function to apply for each element, the starting value and the list.

Temporary edits global variable [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
LISP - Global variable keep their old value after reinitialization
I'm currently doing some coursework with Lisp (using Common Lisp) and have nowhere else to turn with this problem I'm having.
It's tricky to explain but here goes..
The situation:
I've got two global variables, p1 & p2, which are polynomial expressions. My task is to create a polynomial calculator, which is going well so far.
I keep my polynomial elements in a specific format: 3x^2 == ((x 2) 3), and I've created two functions which recursively run through both lists of polynomial elements.
If I wanted to add together 3x^2 and 2x^2, the answer would be 5x^2 (or "((x 2) (3+2))").
I have a third list, the result, which is appended to whenever an element is calculated/can't be calculated.
The problem:
With two elements I can add together, I create a temporary variable to be added to the result. However, the global variable is changed despite what I do.
I've tried let, lambda, various functions, etc. I've been stuck for a couple of days now and would greatly appreciate any help you could give me :)
Here's a small example of what I mean:
(setf p1 '((x 2) 2))
;2x^2
(setf p2 '((x 2) 3))
;3x^2
(if (equal (first p1) (first p2))
(progn
(setf temp p1)
(setf (second temp) (+ (second p1) (second p2)))
(append-to-result temp)
(print p1)
(print temp)))
Output:
((x 2) 5)
((x 2) 5)
When you do:
(setf temp p1)
you are not_making a copy of the list structure that p1 refers to. Both variables now refer to the same cons cells. Then when you do:
(setf (second temp) ...)
you're modifying that list structure, which both variables still refer to. Change to:
(setf temp (copy-tree p1))

What is the functionality of this code? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
Can anyone help me with this program in LISP:
(defun callie(x y) (if x (callie (cdr x) y))
(if (= (mod (car x) y) 0) (format t "~a~%" (car x))))
I have to understand the functionality and repair it. What does this program do?
When trying to understand that program, you should probably start by fixing the formatting:
(defun callie (x y)
(if x
(callie (cdr x) y))
(if (= (mod (car x) y) 0)
(format t "~a~%" (car x))))
Replacing ifs without a else-branch with whens, and the comparison with 0 with the specific zerop predicate, can further clarify things:
(defun callie (x y)
(when x
(callie (cdr x) y))
(when (zerop (mod (car x) y))
(format t "~a~%" (car x))))
The expected parameter types seem to be a list of integers for x, and an integer for y. The purpose of the function seems to be to print all elements of x that are multiples of y.
A problem seems to be that the function recurses until x is empty, and then tries to do the check on the first element of that version of x (which obviously doesn't exist). So, to fix this, you would have to make sure that the function won't try to process the empty list further. The preferable approach, in my opinion, would be to make use of a standard function or macro for processing a list for side-effects, like mapc or dolist.
Looks like the code tries to print all possible values from the list X where the value is exact-divisible by Y.
It has some errors in it, though.
The usual way to write that in Common Lisp is to use a function which returns a new list, where all items, which don't divide to zero with the given number, are removed.
Typically this test is written as a predicate function which returns a boolean. This functions then is used to remove the unwanted items from the list.
See REMOVE-IF and REMOVE-IF-NOT.
Your task is to get the recursion right. But in real Lisp code, the recursion is not used directly.

Problems with Nth in common lisp

I'm trying to write a function that can calculate GPA. Now I can do limited calculation(only 3 ),but I stuck on how to calculate more , without using loop or recursion (that's the requirement of subject) how to expend nth function? like: (nth n) ,if so ,is that mean i need to write a lambda expression? As an newbie, I maynot describe the question clearly, really need some help..
Glist is grade points Clist is credit hours.
GPA=( gradepoint *credithour + gradepoint *credithour) / ( the sum of credithour) like: (3*1+3*2+4*1)/(1+2+1)
here is my code:
(defun gpa (Glist Clist)
(format t "~3,2f~%"
(/
(+(nth 0 (mapcar #' * Glist Clist))
(nth 1 (mapcar #' * Glist Clist))
(nth 2 (mapcar #' * Glist Clist)))
(+ (nth 0 Clist)
(nth 1 Clist)
(nth 2 Clist))
);end "/"
);end "format"
(values) );end
EDIT
This seems like a good opportunity to emphasize some common (little c) Lisp ideas, so I fleshed out my answer to illustrate.
As mentioned in another answer, you could use a sum function that operates on lists (of numbers):
(defun sum (nums)
(reduce #'+ nums))
The dot product is the multiplicative sum of two (equal-length) vectors:
(defun dot-product (x y)
(sum (mapcar #'* x y)))
The function gpa is a simple combination of the two:
(defun gpa (grades credits)
(/ (dot-product grades credits) (sum credits)))
The example from the question results in the answer we expect (minus being formatted as a float):
(gpa '(3 3 4) '(1 2 1))
> 13/4
There are a few things worth mentioning from this example:
You should learn about map, reduce, and their variants and relatives. These functions are very important to Lisp and are very useful for operating on lists. map* functions generally map sequences to a sequence, and reduce usually transforms a sequence into to a single value (you can however use forms like (reduce #'cons '(1 2 3))).
This is a good example of the "bottom-up" approach to programming; by programming simple functions like sum that are often useful, you make it easy to write dot-product on top of it. Now the gpa function is a simple, readable function built on top of the other two. These are all one-liners, and all are easily readable to anyone who has a basic knowledge of CL. This is in contrast to the methodology usually applied to OOP.
There is no repetition of code. Sure, sum is used more than once, but only where it makes sense. You can do very little more to abstract the notion of a sum of the elements of a list. It's more natural in Scheme to write functions with functions, and that's a whole different topic. This is a simple example, but no two functions are doing the same thing.
If you're using nth to traverse a list, you're doing it wrong. In this case, you might want to write a summing function:
(defun sum (items)
(reduce #'+ items))