Vector addition of lists - lisp

If I had a N lists each of length M, how could I write a nice clean function to return a single list of length M, where each element is the sum of the corresponding elements in the N lists?
(starting to learn lisp - go easy!)

This is a job for the map and apply functions. Here is a way to do it, with an EDIT suggested by Nathan Sanders:
(define (add-lists . more)
(apply map + more))

For a more matlab like syntax:
(define (piecewise func)
(lambda more
(apply map func more)))
(define pw piecewise)
((pw +) '(1 2 3 4 5) '(6 7 8 9 0))
((pw -) '(1 2 3 4 5) '(6 7 8 9 0))
((pw *) '(1 2 3 4 5) '(6 7 8 9 0))
((pw /) '(1 2 3 4 5) '(6 7 8 9 0.1))
outputs:
(7 9 11 13 5)
(-5 -5 -5 -5 5)
(6 14 24 36 0)
(1/6 2/7 3/8 4/9 50.0)

Just this works in MIT scheme.
(map + '(1 2 3) '(4 5 6) '(7 8 9))
;Value 28: (12 15 18)

Related

Change just one position on array Clisp

I'm doing an algorithm that randomizes a TSP (array of citys) based on 1 TSP.
(do ((i 0 (+ i 1)))
((= i n-population))
(setf (aref population i) (shuffle TSP 100))
)
And as far as I know im filling up i positions of the array population with (shuffle TSP 100) that is beeing called each iteration, but the algorithm is setting all array positions and not just i position.
[Note. An earlier version of this answer contained a mistake which would badly alter the statistics of the shuffling: please check below for the corrected version and a note as to what the problem was.]
Given your code, slightly elaborated to turn it into a function:
(defun fill-array-with-something (population n-population TSP)
(do ((i 0 (+ i 1)))
((= i n-population))
(setf (aref population i) (shuffle TSP 100))))
Then each element of population from 0 to (1- n-population) will be set to the result of (shuffle TSP 100). There are then two possibilities:
(shuffle TSP 100) returns a fresh object from each call;
(shuffle TSP 100) returns the same object – probably TSP – from each call.
In the first case, each element of the array will have a distinct value. In the second case, all elements below n-population will have the same value.
Without knowing what your shuffle function does, here is an example of one which will give the latter behaviour:
(defun shuffle (vec n)
;; shuffle pairs of elts of VEC, N times.
(loop with max = (length vec)
repeat n
do (rotatef (aref vec (random max))
(aref vec (random max)))
finally (return vec)))
And we can test this:
> (let ((pop (make-array 10))
(tsp (vector 0 1 2 3 4 5 6 7 8 9 )))
(fill-array-with-something pop (length pop) tsp)
pop)
#(#(2 8 7 1 3 9 5 4 0 6) #(2 8 7 1 3 9 5 4 0 6) #(2 8 7 1 3 9 5 4 0 6)
#(2 8 7 1 3 9 5 4 0 6) #(2 8 7 1 3 9 5 4 0 6) #(2 8 7 1 3 9 5 4 0 6)
#(2 8 7 1 3 9 5 4 0 6) #(2 8 7 1 3 9 5 4 0 6) #(2 8 7 1 3 9 5 4 0 6)
#(2 8 7 1 3 9 5 4 0 6))
As you can see all the elements are mysteriously the same thing, which is because my shuffle simply returned its first argument, having modified it in place.
You can check this by either explicitly checking the result of shuffle, or by, for instance, using *print-circle* to see the sharing. The latter approach is pretty neat:
> (let ((*print-circle* t)
(pop (make-array 10))
(tsp (vector 0 1 2 3 4 5 6 7 8 9 )))
(fill-array-with-something pop (length pop) tsp)
(print pop)
(values))
#(#1=#(4 6 7 0 1 2 5 9 3 8) #1# #1# #1# #1# #1# #1# #1# #1# #1#)
And now it's immediately apparent what the problem is.
The solution is to make sure either that shuffle returns a fresh object, or to copy its result. With my shuffle this can be done like this:
(defun fill-array-with-something (population n-population tsp)
(do ((i 0 (+ i 1)))
((= i n-population))
(setf (aref population i) (shuffle (copy-seq TSP) 100))))
Note that a previous version of this answer had (copy-seq (shuffle TSP 100)): with my version of shuffle this is a serious mistake, as it means that the elements in population are related to each other but get increasingly shuffled as you go along. With (shuffle (copy-seq TSP) 100) each element gets the same amount of shuffling, independently.
And now
> (let ((*print-circle* t)
(pop (make-array 10))
(tsp (vector 0 1 2 3 4 5 6 7 8 9 )))
(fill-array-with-something pop (length pop) tsp)
(print pop)
(values))
#(#(8 3 4 1 6 9 2 5 0 7) #(8 6 5 1 3 0 4 2 9 7) #(5 0 4 7 1 6 9 3 2 8)
#(3 0 7 6 2 9 4 5 1 8) #(8 2 5 1 7 3 9 0 4 6) #(0 5 6 3 8 7 2 1 4 9)
#(4 1 3 7 8 0 5 2 9 6) #(6 9 1 5 0 7 4 2 3 8) #(2 7 5 8 0 9 6 3 4 1)
#(5 4 8 9 6 7 2 0 1 3))
I suspect that the problem is in OP function SHUFFLE which has not yet been shared; my suspicion is that SHUFFLE is shuffling the *TSP* array itself in place instead of creating a shuffled copy of that array. The POPULATION values are then all referencing the same shuffled *TSP* array.
To solve this problem, SHUFFLE should return a shuffled array instead of shuffling the array in place. Here is a function that performs a Fisher-Yates shuffle on a vector:
(defun shuffle-vector (vect)
"Takes a vector argument VECT and returns a shuffled vector."
(let ((result (make-array (length vect) :fill-pointer 0)))
(labels ((shuffle (v)
(if (zerop (length v))
result
(let* ((i (random (length v)))
(x (elt v i)))
(vector-push x result)
(shuffle (concatenate 'vector
(subseq v 0 i)
(subseq v (1+ i))))))))
(shuffle vect))))
Testing in the REPL:
CL-USER> (defvar *TSP* #("Village" "Town" "City" "Metropolis" "Megalopolis"))
*TSP*
CL-USER> (defvar *n-population* 5)
*N-POPULATION*
CL-USER> (defvar *population* (make-array *n-population*))
*POPULATION*
CL-USER> (dotimes (i *n-population*)
(setf (aref *population* i) (shuffle-vector *TSP*)))
NIL
CL-USER> *population*
#(#("Megalopolis" "City" "Metropolis" "Town" "Village")
#("Megalopolis" "Metropolis" "Town" "City" "Village")
#("City" "Megalopolis" "Town" "Village" "Metropolis")
#("City" "Megalopolis" "Village" "Metropolis" "Town")
#("Megalopolis" "Town" "Metropolis" "City" "Village"))

Lisp, Remove sublist with two common elements

i am programming in Common lisp, and i need an algorithm that delete sublist with (at least) two common elements.
i don't have any idea to how i can solve the problem. I thought to use this:
(defun remove-duplicates-list (list) (remove-duplicates list :test 'equal :key 'cdr))
but the cdr between the sublists is different, and i just can't figure out how i can count two elements and remove the sublist.
Also i need to don't remove the "original" sublist (in the example '(1 2 3 4)), bot only (2 3 4) and (1 3 4)
Example :
input: '( (1 2 3 4) (2 3 4) (5 6 7 8) (1 3 4) (9 9 9 9) )
output: '( (1 2 3 4) (5 6 7 8) (9 9 9 9) )
input: '( ((1 . 1) (2 . 2) (3 . 3) (4 . 4)) ((1 . 1) (2 . 2) (4 . 4)))
output : '((1 . 1) (2 . 2) (3 . 3) (4 . 4))
Thank you!
P.s sorry if, at first, i have not explained well my problem, i correct many mistake in the post. this is my first question on this community, so forgive please
Actually you could do it with remove-duplicates. You need to make a test function that returns true when at least two elements are similar. eg.
(defun two-similar-p (lst1 lst2)
...)
(two-similar-p '(1 2 3) '(1 4 5)) ; ==> nil
(two-similar-p '(1 2 5) '(1 4 5)) ; ==> t
Using a hash is the fastest and best time complexity while iterating one list (length other-list) times is possibly the easiest. Then you can solve your problem this way:
(defun remove-duplicates-list (list)
(remove-duplicates list :test #'two-similar-p :from-end t))
(remove-duplicates-list '((1 2 3 4) (2 3 4) (5 6 7 8) (1 3 4) (9 9 9 9)))
; ==> ((1 2 3 4) (5 6 7 8) (9 9 9 9))

Get pretty-printed result in Cider-evaluated expression in Emacs

I'd like to insert the result of an evaluated Clojure expression directly in my Emacs buffer, in pretty-printed form.
For example, with something like:
;; [emacs lisp]
(insert (nrepl-dict-get (nrepl-sync-request:eval "(range 30)") "value"))
I get, in the buffer of interest,
;;=>
(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29)
In the past, I've let Clojure pretty-print things for me, as so:
(nrepl-dict-get
(nrepl-sync-request:eval
(format "(clojure.core/let [x %s] (with-out-str (clojure.pprint/pprint x)))"
"(range 30)"))
"value")
;;=>
"(0\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n 10\n 11\n 12\n 13\n 14\n 15\n 16\n 17\n 18\n 19\n 20\n 21\n 22\n 23\n 24\n 25\n 26\n 27\n 28\n 29)\n"
However, the " and \n are being inserted escaped; I want them to be inserted unescaped. In other words, I want the pretty-printed result to be inserted directly without escaping quotes or newlines. This used to work in earlier versions of Cider and cider-nrepl.
Wrapping:
(nrepl-dict-get
(nrepl-sync-request:eval
(format "(clojure.core/let [x %s] (with-out-str (clojure.pprint/pprint x)))"
"(range 30)"))
"value")
in read should solve this.
I've just added this feature to lispy (it's a Paredit-style
package that uses Cider for Clojure eval):
2E will to a pretty-printed eval-and-insert, while
E will keep doing a plain one.
Here's an example (| represents point):
|(for [x (range 8)] (range x))
After E:
|(for [x (range 8)] (range x))
(() (0) (0 1) (0 1 2) (0 1 2 3) (0 1 2 3 4) (0 1 2 3 4 5) (0 1 2 3 4 5 6))
After 2E:
|(for [x (range 8)] (range x))
(()
(0)
(0 1)
(0 1 2)
(0 1 2 3)
(0 1 2 3 4)
(0 1 2 3 4 5)
(0 1 2 3 4 5 6))
Of course you can still do EjM to accomplish the same thing:
(for [x (range 8)] (range x))
|(()
(0)
(0 1)
(0 1 2)
(0 1 2 3)
(0 1 2 3 4)
(0 1 2 3 4 5)
(0 1 2 3 4 5 6))

Justification in a format with variable number of items in a list

So I can do this:
CL-USER> (format t "~80<~a~;~a~;~a~;~a~>~%" "hello" "how are you" "i'm fine" "no you're not")
hello how are you i'm fine no you're not
It evenly spaces the 4 strings across the span of 80 as specified.
However, I want to pass a list of strings, and have it justify those instead, based on however many are in the list.
Neither of these do it:
CL-USER> (format t "~{~80<~a~;~>~}~%" '(1 2 3 4 5 6))
1
2
3
4
5
6
CL-USER> (format t "~80<~{~a~;~}~>~%" '(1 2 3 4 5 6))
; Evaluation aborted on #<SB-FORMAT:FORMAT-ERROR {126651E1}>.
; ~; not contained within either ~[...~] or ~<...~>
Is there a way to do this?
You can do this with (format stream (format nil ...)) where you generate the format control for justification using format:
CL-USER> (format nil (format nil "|~~40<~{~a~^~~;~}~~>|" '(1 2 3 4 5)))
"|1 2 3 4 5|"
CL-USER> (format nil (format nil "|~~40<~{~a~^~~;~}~~>|" '(1 2 3 4 5 6 7 8 9 10)))
"|1 2 3 4 5 6 7 8 9 10|"
CL-USER> (format nil (format nil "|~~40<~{~a~^~~;~}~~>|" '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)))
"|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15|"
If you don't want to generate the whole format control for the outer format, you can use some variant of ~? to process a string and some arguments recursively:
CL-USER> (format nil "|~#?|" (format nil "~~40<~{~a~^~~;~}~~>" '(1 2 3 4 5)))
"|1 2 3 4 5|"
CL-USER> (format nil "|~#?|" (format nil "~~40<~{~a~^~~;~}~~>" '(1 2 3 4 5 6 7 8 9 10)))
"|1 2 3 4 5 6 7 8 9 10|"
CL-USER> (format nil "|~#?|" (format nil "~~40<~{~a~^~~;~}~~>" '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)))
"|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15|"
The recursive processing with ~? only allows you to process another format control with a list of arguments; it doesn't give you a way to splice in a new format string. It appears that the text that is justified has to be present in the control string, so you'd really need a way to splice in a control string that already contains the text that you want.
Although the first of these seems simpler, there is a danger in it because you're putting the printed text into another format string, and you're not doing that in the second case. In the first case, if any of those numbers were replaced with format directives, the outer format would try to process them. In the second case, this doesn't happen. As such, I think I'd suggest the second.

Lisp sort function

I am trying to make a (somehow) delicate sorting function in Lisp. I know there is lambda operator that should make my work a lot easier, but I couldn't find anything helpful so I hope you can help me.
As an input I have a nested list like this one:
((o1 10 15 20) (o2 5 14 20) (o3 7 8 8))
The output should be a nested list like this one:
((o1 1 1 1) (o2 3 2 1) (o3 2 3 3))
To be more specific, the first element from o1 is compared to the first element from o2 and o3 and the return should be it's position (in the example above, 10 is greater than 5 and 7 so it will be on the first position in the resulting list) and so on.
The highest number will get the first position.
(it's like a score function. Some students make an application and their features numbers are compared. The one with highest number of features will get the first place, but when comparing the number of different technologies used, he may get the 2nd or 3rd place).
Thanks and I hope you can help me
A little exploration is in order.
[3]> (setq a '((o1 10 15 20) (o2 5 14 20) (o3 7 8 8)))
((O1 10 15 20) (O2 5 14 20) (O3 7 8 8))
[4]> (setq b (apply #'mapcar #'list a))
((O1 O2 O3) (10 5 7) (15 14 8) (20 20 8))
[5]> (setq c (mapcar #'(lambda(x)(sort x #'>)) (cdr b)))
((10 7 5) (15 14 8) (20 20 8))
[6]> (mapcar #'(lambda(g)(cons (car g) (mapcar #'1+
(mapcar #'position (cdr g) c)))) a)
((O1 1 1 1) (O2 3 2 1) (O3 2 3 3))
Now stir, form, and bake at 190 C until ready.