mapcar with lambda and two list as input - list

first, i would like to understand the difference, if there is any, in the following code:
1 (setf list1 '(1 2 3))
2 (setf list2 '(10 100))
3
4 (defun som(x y )
5 (* x y))
6
7
8 (print(mapcar #'(lambda(x)x) list1))
9 (print (mapcar #'(lambda(x)x) list1))
which returns the following:
(1 2 3)
(1 2 3)
Then i would like to understand how to do the following:
(setf list1 '(1 2 3))
(setf list2 '(10 100))
(mapcar '#+ x y)
in order to get the following:
((11 101) (12 102) (13 103)), this is, add the first item of the first list
to every item of the second list.
Of course I could, very quickly define a function which would iterate through a list and apply a mapcar to the list. I was wondering if there is any primitive which would do that.
Thanks, have a good night

Your code
(setf list1 '(1 2 3))
(setf list2 '(10 100))
(defun som(x y )
(* x y))
(print(mapcar #'(lambda(x)x) list1))
(print (mapcar #'(lambda(x)x) list1))
;; This is the same between forms you do not need the space
;; but it is more readeable to write things with spcaes and tabs
so this is how I woul write the expression
(print (mapcar #'(lambda (x) x) list1))
or you can use the function identity
(print (mapcar #'identity list1))
allways remeber that the first element of the form is a function for the evaluator
to understand this you need to get a full understanding of lambda experssions and map functions in lisp also will be useful to learn functional programming, in that case you will wirte this as quickly as you will write the iterate version
You will have other aproches, this is not one of my foavourites because the use of global variables but it should do the thick it allways remember me to the iterative version
(defparameter *list1* '(1 2 3))
(defparameter *list2* '(10 100))
(print (mapcar (lambda (x) (mapcar (lambda (y) (+ x y)) *list2*)) *list1*))

Related

How can I add a () in a list?

How can I add a parentheses in a list? For example,
(multiply '(1 2) '(1 2 3))
It should output ((1 2 3) (2 4 6))
This is what I have now
(define multiply
(lambda (los1 los2)
(cond
((null? los1) '())
((null? los2) '())
(else (cons (* (car los1) (car los2))
(append (multiply(list (car los1)) (cdr los2))
(multiply(cdr los1) los2)))))))
The output I get is (1 2 3 2 4 6).
P/S: If this is a bad question or anything, don't hesitate to tell me or scold me. I am trying to learn to use stackoverflow.
Think about what the implications of the input and the output are. I imagine that you cannot do this with one single recursive procedure, but you can do it with two.
(list-multiply 5 '(1 2 3))
; ==> (5 10 15)
When you have that you iterate over the first list and use list-multiply for each element and of course the second argument is never iterated, it's just passed along.
(multiply '(1 2) '(1 2 3))
; ==> (cons (list-multiply 1 '(1 2 3))
; (cons (list-multiply 2 '(1 2 3))
; '()))
; ==> ((1 2 3) (2 4 6))
You can implement this simply by useinfg higher order functions:
(define (multiply lst1 lst2)
(map (lambda (e1)
(map (lambda (e2) (* e1 e2)) lst2))
lst1))
Notice the double map. One that iterates lst1 to make elements in the result and a second map that multiplies the one element with each element of the list. You might imagine that since these look similar the two recursive functions probably have a lot in common too.
PS: Learn to solve your problems without list and append. (list 1 2 3) is just a procedure that is equivalent to (cons 1 (cons 2 (cons 3 '()))) and (append '(1 2 3) '(4 5 6)) is equivalent to (cons 1 (cons 2 (cons 3 '(4 5 6)))). Try always building lists from end to beginning and in the event you need the opposite it might just need a reverse in the end.

Remove elements in a list using a pattern

Greeting everyone. I'm trying to write an algorithm in Racket but I'm faced with a problem:
I'm studying way of generating different types of grids over surfaces, using a CAD software as a backend for Racket. Basically I have a function that generates a matrix of point coordinates (in the u and v domains) of a parametric surface and another one which connects those points with a line, in a certain order, to create the grid pattern. The problem is, to obtain more complex grids I need to be able to remove certain points from that matrix.
With that said, I have a list of data (points in my case) and I want to remove items from that list based on a true-false-false-true pattern. For example, given the list '(0 1 2 3 4 5 6 7 8 9 10) the algorithm would keep the first element, remove the next two, keep the third and then iterate the same patter for the rest of the list, returning as the final result the list '(0 3 4 7 8).
Any suggestions? Thank you.
Using Racket's for loops:
(define (pattern-filter pat lst)
(reverse
(for/fold ((res null)) ((p (in-cycle pat)) (e (in-list lst)))
(if p (cons e res) res))))
testing
> (pattern-filter '(#t #f #f #t) '(0 1 2 3 4 5 6 7 8 9 10))
'(0 3 4 7 8)
A solution using list functions in SRFI-1:
#!racket
(require srfi/1)
(define (pattern-filter pat lst)
(fold-right (λ (p e acc) (if p (cons e acc) acc))
'()
(apply circular-list pat)
lst))
(pattern-filter '(#t #f #f #t)
'(0 1 2 3 4 5 6 7 8 9 10)) ; ==> '(0 3 4 7 8)
There are other ways but it won't become easier to read.
In Racket I would probably use match to express the specific pattern you described:
#lang racket
(define (f xs)
(match xs
[(list* a _ _ d more) (list* a d (f more))]
[(cons a _) (list a)]
[_ (list)]))
(require rackunit)
;; Your example:
(check-equal? (f '(0 1 2 3 4 5 6 7 8 9 10)) '(0 3 4 7 8))
;; Other tests:
(check-equal? (f '()) '())
(check-equal? (f '(0)) '(0))
(check-equal? (f '(0 1)) '(0))
(check-equal? (f '(0 1 2)) '(0))
(check-equal? (f '(0 1 2 3)) '(0 3))
(check-equal? (f '(0 1 2 3 4)) '(0 3 4))
However I also like (and upvoted) both usepla's and Sylwester's answers because they generalize the pattern.
Update: My original example used (list a _ _ d more ...) and (list a _ ...) match patterns. But that's slow! Instead use (list* a _ _ d more) and (cons a _), respectively. That expands to the sort of fast code you'd write manually with cond and list primitives.
The question is tagged with both scheme and racket, so it's probably not a bad idea to have an implementation that works in Scheme in addition to the versions that work for Racket given in some of the other answers. This uses the same type of approach that's seen in some of those other answers: create an infinite repetition of your boolean pattern and iterate down it and the input list, keeping the elements where your pattern is true.
Here's a method that takes a list of elements and a list of #t and #f, and returns a list of the elements that were at the same position as #t in the pattern. It ends whenever elements or pattern has no more elements.
(define (keep elements pattern)
;; Simple implementation, non-tail recursive
(if (or (null? elements)
(null? pattern))
'()
(let ((tail (keep (cdr elements) (cdr pattern))))
(if (car pattern)
(cons (car elements) tail)
tail))))
(define (keep elements pattern)
;; Tail recursive version with accumulator and final reverse
(let keep ((elements elements)
(pattern pattern)
(result '()))
(if (or (null? elements)
(null? pattern))
(reverse result)
(keep (cdr elements)
(cdr pattern)
(if (car pattern)
(cons (car elements) result)
result)))))
To get an appropriate repeating pattern, we can create a circular list of the form (#t #f #f #t …) we can create a list (#t #f #f #t) and then destructively concatenate it with itself using nconc. (I called it nconc because I've got a Common Lisp background. In Scheme, it's probably more idiomatic to call it append!.)
(define (nconc x y)
(if (null? x) y
(let advance ((tail x))
(cond
((null? (cdr tail))
(set-cdr! tail y)
x)
(else
(advance (cdr tail)))))))
(let ((a (list 1 2 3)))
(nconc a a))
;=> #0=(1 2 3 . #0#)
Thus, we have a solution:
(let ((patt (list #t #f #f #t)))
(keep '(0 1 2 3 4 5 6 7 8 9 0) (nconc patt patt)))
;=> (0 3 4 7 8)

If you're mapping a function over a list in rackect how can you get a reference to the next element?

If I have a list and I map a lambda function over it how can I get a reference to the next or previous item while processing the current one?
(map (lambda (x) x) '(1 2 3))
How would I reference the previous or next element while processing x?
John McCarthy originally made maplist and it's defined in CL still and predates map(car). It's definition in Scheme would be something like:
(define (maplist fun lst)
(if (null? lst)
'()
(cons (fun lst) (maplist fun (cdr lst)))))
(maplist values '(1 2 3 4)) ; ==> ((1 2 3 4) (2 3 4) (3 4) (4))
It's slightly more difficult to get each element like map but if you need more than the first then it's perfect.
Start with your one list, construct two other lists, one 'shifted' right, and the other 'shifted' left. Like this:
(define (process func x)
(let ((to-front (cons 'front (reverse (cdr (reverse x)))))
(to-rear (append (cdr x) (list 'rear))))
(map func to-front x to-rear)))
Note that the stuff above with reverse is because map expects all lists to have the same length. So when adding to the front, you need to remove one from the tail.
Also, the provided func needs to accept three arguments.
> (process list '(a b c))
((front a b) (a b c) (b c rear))
You can always use map on two zipped lists, i.e.
(import (srfi srfi-1)) ; or use some zip implementation
(define a '(1 2 3 4 5))
(map (lambda (x) x)
(zip a
(append (cdr a) (list (car a)))))
which results in ((1 2) (2 3) (3 4) (4 5) (5 1)).
Of course, the above assumes "periodic" boundary conditions for the lists (you should modify the boundary conditions for your case).
And also you would need to modify the lambda to handle pairs of elements.
For simplicity let's take the case of two elements at a time -- the current and next one. So if you have (list 1 2 3), and a function that takes this and next args, you want it to be called with:
1 2
2 3
3 <some value, let's say 3>
You could write that concisely as:
(map f xs (append (drop xs 1) (list (last xs))))
However the drop and append-ing means that's not the fastest way to do it. Instead you could write a map-slide-pairs function to do it more directly:
#lang racket/base
(require racket/match)
;; map a list as "sliding pairs". For example:
;; (map-slide-pairs cons '(1 2 3)) ==> '((1 . 2)
;; (2 . 3)
;; (3 . 3))
(define (map-slide-pairs f xs #:last-val [last-val #f])
;; Concise implementation:
;; (map f xs (append (drop xs 1) (list (last xs)))))
;; Faster implementation:
(let loop ([xs xs])
(match xs
[(list) (list)]
[(list this) (list (f this (or last-val this)))]
[(list this next more ...) (cons (f this next)
(loop (cons next more)))])))
(module+ test
(require rackunit)
(check-equal? (map-slide-pairs cons '(1 2 3))
'([1 . 2][2 . 3][3 . 3]))
(check-equal? (map-slide-pairs cons '(1 2 3) #:last-val 100)
'([1 . 2][2 . 3][3 . 100])))
Hopefully you can see how to extend this and make a "map-slide-triples" function that would be called with the previous, current, and next elements of the list.

Find how many times each number occurs in list

If we had a list A holding (1 2 1 1 2 3 3 4 4 4), how could we get a new list B with ((1 . 30) (2 . 20) (3 . 20) (4 . 30)) in it, such that the number_after_dot is the percentage of the number_before_dot in the list A.
For example 1 is 30% of list A, 2 is 20% of list A, etc..
(1 . 30) is a pair, which could be made by (cons 1 30)
I think what you want to do is calculate the percentage of the list that is equal to each element. You used the word "unique" but that a bit confusing since your list has no unique elements. This is based on your sample input and output, where the list (1 2 1 1 2 3 3 4 4 4) is composed of "30% ones".
You can break this down roughly into a recursive algorithm consisting of these steps:
If the input list is empty, return the empty list.
Otherwise, get the first element. Calculate how many times it occurs in the list.
Calculate the percentage, and cons the element with this percentage.
Remove all the occurrences of the first item from the cdr of the list.
Recurse on this new list, and cons up a list of (element . percentage) pairs.
To do the first part, let's use filter:
> (filter (lambda (x) (eq? (car A) x)) A)
(1 1 1)
With your list A, this will return the list (1 1 1). We can then use length to get the number of times it occurs:
> (length (filter (lambda (x) (eq? (car A) x)) A))
3
To calculate the percentage, divide by the number of elements in the whole list, or (length A) and multiply by 100:
> (* 100 (/ (length (filter (lambda (x) (eq? (car A) x)) A)) (length A)))
30
It's easy to cons this with the element (car A) to get the pair for the final list.
To do the second step, we can use remove which is the inverse of filter: it will return a list of all elements of the original list which do not satisfy the predicate function:
> (remove (lambda (x) (eq? (car A) x)) A)
(2 2 3 3 4 4 4)
This is the list we want to recurse on. Note that at each step, you need to have the original list (or the length of the original list) and this new list. So you would need to somehow make this available to the recursive procedure, either by having an extra argument, or defining an internal definition.
There might be more efficient ways I'm sure, or just other ways, but this was the solution I came up with when I read the question. Hope it helps!
(define (percentages all)
(let ((len (length all))) ; pre-calculate the length
;; this is an internal definition which is called at ***
(define (p rest)
(if (null? rest)
rest
;; equal-to is a list of all the elements equal to the first
;; ie something like (1 1 1)
(let ((equal-to (filter (lambda (x) (eq? (car rest) x))
rest))
;; not-equal-to is the rest of the list
;; ie something like (2 2 3 3 4 4 4)
(not-equal-to (remove (lambda (x) (eq? (car rest) x))
rest)))
(cons (cons (car rest) (* 100 (/ (length equal-to) len)))
;; recurse on the rest of the list
(p not-equal-to)))))
(p all))) ; ***
The question formulation is very close to the idea of run-length encoding. In terms of run-length encoding, you can use a simple strategy:
Sort.
Run-length encode.
Scale the run lengths to get percentages.
You can implement run-length encoding like this:
(define (run-length-encode lst)
(define (rle val-lst cur-val cur-cnt acc)
(if (pair? val-lst)
(let ((new-val (car val-lst)))
(if (eq? new-val cur-val)
(rle (cdr val-lst) cur-val (+ cur-cnt 1) acc)
(rle (cdr val-lst) new-val 1 (cons (cons cur-val cur-cnt) acc))))
(cons (cons cur-val cur-cnt) acc)))
(if (pair? lst)
(reverse (rle (cdr lst) (car lst) 1 '()))
'()))
and scaling looks like:
(define (scale-cdr count-list total-count)
(define (normalize pr)
(cons (car pr) (/ (* 100 (cdr pr)) total-count)))
(map normalize count-list))
Now we need something to sort a list. I'll just use the sort function in racket (adapt as needed). The function to calculate the percentages for each number in the list is then:
(define (elem-percent lst)
(scale-cdr (run-length-encode (sort lst <)) (length lst)))
Some examples of use:
> (elem-percent '())
'()
> (elem-percent (list 1 2 3 4 5))
'((1 . 20) (2 . 20) (3 . 20) (4 . 20) (5 . 20))
> (elem-percent (list 1 2 1 1))
'((1 . 75) (2 . 25))
> (elem-percent (list 1 2 1 1 2 3 3 4 4 4))
'((1 . 30) (2 . 20) (3 . 20) (4 . 30))

lisp filter out results from list not matching predicate

I am trying to learn lisp, using emacs dialect and I have a question.
let us say list has some members, for which predicate evaluates to false. how do I create a new list without those members? something like { A in L: p(A) is true }. in python there is filter function, is there something equivalent in lisp? if not, how do I do it?
Thanks
These functions are in the CL package, you will need to (require 'cl) to use them:
(remove-if-not #'evenp '(1 2 3 4 5))
This will return a new list with all even numbers from the argument.
Also look up delete-if-not, which does the same, but modifies its argument list.
If you manipulate lists heavily in your code, please use dash.el modern functional programming library, instead of writing boilerplate code and reinventing the wheel. It has every function to work with lists, trees, function application and flow control you can ever imagine. To keep all elements that match a predicate and remove others you need -filter:
(-filter (lambda (x) (> x 2)) '(1 2 3 4 5)) ; (3 4 5)
Other functions of interest include -remove, -take-while, -drop-while:
(-remove (lambda (x) (> x 2)) '(1 2 3 4 5)) ; (1 2)
(-take-while (lambda (x) (< x 3)) '(1 2 3 2 1)) ; (1 2)
(-drop-while (lambda (x) (< x 3)) '(1 2 3 2 1)) ; (3 2 1)
What is great about dash.el is that it supports anaphoric macros. Anaphoric macros behave like functions, but they allow special syntax to make code more concise. Instead of providing an anonymous function as an argument, just write an s-expression and use it instead of a local variable, like x in the previous examples. Corresponding anaphoric macros start with 2 dashes instead of one:
(--filter (> it 2) '(1 2 3 4 5)) ; (3 4 5)
(--remove (> it 2) '(1 2 3 4 5)) ; (1 2)
(--take-while (< it 3) '(1 2 3 2 1)) ; (1 2)
(--drop-while (< it 3) '(1 2 3 2 1)) ; (3 2 1)
I was looking for the very same last night and came across the Elisp Cookbook on EmacsWiki. The section on Lists/Sequences contains filtering teqniques and show how this can be done with mapcar and delq. I had to mod the code to use it for my own purposes but here is the original:
;; Emacs Lisp doesn’t come with a ‘filter’ function to keep elements that satisfy
;; a conditional and excise the elements that do not satisfy it. One can use ‘mapcar’
;; to iterate over a list with a conditional, and then use ‘delq’ to remove the ‘nil’
;; values.
(defun my-filter (condp lst)
(delq nil
(mapcar (lambda (x) (and (funcall condp x) x)) lst)))
;; Therefore
(my-filter 'identity my-list)
;; is equivalent to
(delq nil my-list)
;; For example:
(let ((num-list '(1 'a 2 "nil" 3 nil 4)))
(my-filter 'numberp num-list)) ==> (1 2 3 4)
;; Actually the package cl-seq contains the functions remove-if and remove-if-not.
;; The latter can be used instead of my-filter.
Emacs now comes with the library seq.el, use seq-remove.
seq-remove (pred sequence)
"Return a list of all the elements for which (PRED element) is nil in SEQUENCE."
With common lisp, you can implement the function as follows:
(defun my-filter (f args)
(cond ((null args) nil)
((if (funcall f (car args))
(cons (car args) (my-filter f (cdr args)))
(my-filter f (cdr args))))))
(print
(my-filter #'evenp '(1 2 3 4 5)))
There are a ton of ways to filter or select stuff from a list using built-ins which are much faster than loops. The built-in remove-if can be used this way. For example, suppose I want to drop the elements 3 through 10 in list MyList. Execute the following code as an example:
(let ((MyList (number-sequence 0 9))
(Index -1)
)
(remove-if #'(lambda (Elt)
(setq Index (1+ Index))
(and (>= Index 3) (<= Index 5))
)
MyList
)
)
You will get '(0 1 2 6 7 8 9).
Suppose you want to keep only elements between 3 and 5. You basically flip the condition I wrote above in the predicate.
(let ((MyList (number-sequence 0 9))
(Index -1)
)
(remove-if #'(lambda (Elt)
(setq Index (1+ Index))
(or (< Index 3) (> Index 5))
)
MyList
)
)
You will get '(3 4 5)
You can use whatever you need for the predicate that you must supply to remove-if. The only limit is your imagination about what to use. You can use the sequence filtering functions, but you don't need them.
Alternatively, you could also use mapcar or mapcar* to loop over a list using some function that turns specific entries to nil and the use (remove-if nil ...) to drop nils.
It's surprising there's no builtin version of filter without cl or (or seq which is very new).
The implementation of filter mentioned here (which you see in the Elisp Cookbook and elsewhere) is incorrect. It uses nil as a marker for items to be removed, which means if you have nils in your list to start with, they're going to be removed even if they satisfy the predicate.
To correct this implementation, the nil markers need to be replaced with an uninterred symbol (ie. gensym).
(defun my-filter (pred list)
(let ((DELMARKER (make-symbol "DEL")))
(delq
DELMARKER
(mapcar (lambda (x) (if (funcall pred x) x DELMARKER))
list))))