Pairing list elementes
Pairing list elementes
Hi, because of my ignorance im stuck whit this problem.
I have a list, example:
(1024 -42 42 123 0 6 -1 0 0 -2)
but i need it to look like this:
(1024 . -42) (42 . 123) (0 . 6) (-1 . 0) (0 . -2)
I have already made this function(i need it like this):
(defun make-point (x y) (cons x y))
The problem is that i dont not how to pairing the elements by the make-point function, can you halp me pls?
EDIT: it will be usefull even create two list of alternate elements like:
(1024 42 0 -1 0)
(-42 123 6 0 -2)
I have a list, example:
(1024 -42 42 123 0 6 -1 0 0 -2)
but i need it to look like this:
(1024 . -42) (42 . 123) (0 . 6) (-1 . 0) (0 . -2)
I have already made this function(i need it like this):
(defun make-point (x y) (cons x y))
The problem is that i dont not how to pairing the elements by the make-point function, can you halp me pls?
EDIT: it will be usefull even create two list of alternate elements like:
(1024 42 0 -1 0)
(-42 123 6 0 -2)
-
I X Code X 1
- Posts: 59
- Joined: Sun May 29, 2011 8:52 pm
- Location: NY
- Contact:
Re: Pairing list elementes
Okayyyy, this is really ugly and there are probably a million better ways to do this. But I think it does what you want it to. Note: it will only work for an even amount of numbers, but if these are suppose to be coordinates then it should not matter; it will always be an even amount of points.
Okay, I simply made a global variable (could figure out a way to do this without globals if you wanted to) which is going to be the resulting list. Take the cons of the first element and the second element. If the cddr of the list is still a list (not nil/empty), we call the method again. It keeps going until all cons have been pushed into the list. Lastly, I reversed the list because the function push is kind of a LIFO structure in the sense that the last element pushed is in the front of the list, and then I just set *y* back to empty. You can take that part out if you want, I just did it so you can call it again with a new set of elements and the last ones won't be there anymore.
CG-USER(57): (MAKE-POINT '(1 2 3 4 5 6 7 8 9 10))
((1 . 2) (3 . 4) (5 . 6) (7 . 8) (9 . 10))
NIL
CG-USER(61): (MAKE-POINT '(2 3 4 5 6 7))
((2 . 3) (4 . 5) (6 . 7))
NIL
This is what happens if the number of coordinates is odd:
CG-USER(65): (make-point '(1 2 3))
((1 . 2) (3))
NIL
All the coordinates are grouped into a big list, but it would be easy to access them if you needed to. If you really don't want this, you can throw something like this in there and monkey around with the code a bit more. I think it's good how it is now though. Can easily access nested lists inside one big list.
Code: Select all
(defparameter *y* '())
(defun make-point (list)
(let ((x (cons (first list) (second list))))
(setf *y* (push x *y*))
(if (cddr list)
(make-point (cddr list))
(progn (print (reverse *y*))
(setf *y* '())))))CG-USER(57): (MAKE-POINT '(1 2 3 4 5 6 7 8 9 10))
((1 . 2) (3 . 4) (5 . 6) (7 . 8) (9 . 10))
NIL
CG-USER(61): (MAKE-POINT '(2 3 4 5 6 7))
((2 . 3) (4 . 5) (6 . 7))
NIL
This is what happens if the number of coordinates is odd:
CG-USER(65): (make-point '(1 2 3))
((1 . 2) (3))
NIL
All the coordinates are grouped into a big list, but it would be easy to access them if you needed to. If you really don't want this, you can throw something like this in there and monkey around with the code a bit more. I think it's good how it is now though. Can easily access nested lists inside one big list.
Code: Select all
CG-USER(69): (format t "~a ~a ~a" '(1 . 2) '(3 . 4) '(5 . 6))
(1 . 2) (3 . 4) (5 . 6)
NILRe: Pairing list elementes
This isn't a lispy-way to do this. Essentially you are collecting the result of the recursion in some external box. The way you want to think about this is that as the call stack unwinds, the result is accumulated:Code: Select all
(defparameter *y* '()) (defun make-point (list) (let ((x (cons (first list) (second list)))) (setf *y* (push x *y*)) (if (cddr list) (make-point (cddr list)) (progn (print (reverse *y*)) (setf *y* '())))))
Code: Select all
* (defun make-point-r (list)
(cond
((null list) nil)
(t (cons (cons (car list) (cadr list)) (make-point-r (cddr list))))))
MAKE-POINT-R
* (make-point-r '(1 2 3 4 5 6 7 8 9 10))
((1 . 2) (3 . 4) (5 . 6) (7 . 8) (9 . 10))
* (make-point-r '(1 2 3 4 5 6 7 8 9))
((1 . 2) (3 . 4) (5 . 6) (7 . 8) (9))
if you care about tail recursion, you can:
Code: Select all
* (defun make-point-t (list &optional (res nil))
(cond
((null list) res)
(t (make-point-t (cddr list) (cons (cons (car list) (cadr list)) res)))))
;
MAKE-POINT-T
* (make-point-t '(1 2 3 4 5 6 7 8 9 10))
((9 . 10) (7 . 8) (5 . 6) (3 . 4) (1 . 2))
* (make-point-t '(1 2 3 4 5 6 7 8 9))
((9) (7 . 8) (5 . 6) (3 . 4) (1 . 2))
-
I X Code X 1
- Posts: 59
- Joined: Sun May 29, 2011 8:52 pm
- Location: NY
- Contact:
Re: Pairing list elementes
Very nice approach at solving this! I am trying to get into the lispy mindset, but it's tough to break my Java rootscrabbe wrote:
This isn't a lispy-way to do this. Essentially you are collecting the result of the recursion in some external box. The way you want to think about this is that as the call stack unwinds, the result is accumulated:Code: Select all
* (defun make-point-r (list) (cond ((null list) nil) (t (cons (cons (car list) (cadr list)) (make-point-r (cddr list))))))
Re: Pairing list elementes
Ugh.
Code: Select all
(defun make-points (list)
(loop for x on list by #'cddr collect (cons (first x) (second x))))
-
I X Code X 1
- Posts: 59
- Joined: Sun May 29, 2011 8:52 pm
- Location: NY
- Contact:
Re: Pairing list elementes
And nice use of the loop, you know.. I was trying to write this before I wrote mine. Just didn't know about the 'by', thanks for sharing that. Will definitely come in handy!Paul wrote:Ugh.
Code: Select all
(defun make-points (list) (loop for x on list by #'cddr collect (cons (first x) (second x))))
Re: Pairing list elementes
Welllll. I suppose that - being the 23rd - there is no problem giving a way a piece of the assignment
Cheers
Code: Select all
(defun make-points (l)
(loop for (x y) on l by #'cddr collect (make-point x y)))
Marco Antoniotti