Page 1 of 3

Replacing elements in a list

Posted: Mon Jun 01, 2009 6:43 pm
by Lispoman
Hi All.
I need some help cause I have no enough knowledge to complete my task. So what's the goal.
I need to define a a function which places a simbol * before every less-than-zero (-1..-5 etc.) element.
For ex. I've (setq a'(1 ,2 ,3 ,-1, -5 ,7 ,-8) a list. So then I should call a function forex MyFunc(x)
(Myfunc A) then I should get (1, 2, 3 ,*-1, *-5, 7 ,8) (i use commas here to separate elements of course no commas in the code).
I'm trying to write this function already 5 days but still can't .
Can someone help me?

So what I get

Code: Select all

(defun myfunc (a x)
 (cond ((null x) nil)
 ((< (car x) 0) (cons a (myfunc a (cdr x))))
 (T (cons (car x) (myfunc a (cdr x))))))
But it just replaces every less-than-zero in a list X to A. But I need a function with just one parameter X-which represents a list.

Re: Replacing elements in a list

Posted: Tue Jun 02, 2009 10:42 am
by Harleqin
What kind of value do you expect "*-1" to be? The way you write it, it can only be a symbol, but the other elements seem to be numbers.

What kind of values should the input list contain?

By the way, you should properly indent your code to help with reading it. A nice explanation can be found in Practical Common Lisp.

Re: Replacing elements in a list

Posted: Tue Jun 02, 2009 12:13 pm
by Jasper
If the symbol * has to be before as element of the list your code is nearly correct:

Code: Select all

(defun myfunc (a x)
  (cond ((null x) nil)
    ((< (car x) 0)
      (append (list a (car x)) (myfunc a (cdr x))))
    (t
      (cons (car x) (myfunc a (cdr x))))))
If you want to attach to things into a string you can use format nil ... (nil indicating that output to string, and you can make strings into a symbol with intern. Left as an exercise.

Re: Replacing elements in a list

Posted: Tue Jun 02, 2009 1:11 pm
by Paul Donnelly
Break it up into two parts. Write a function that returns either the positive number or the... other thing, then use MAPCAR to apply it to the list.

Code: Select all

(defun do-strange-thing (list)
  (mapcar (lambda (number)
            (if (plusp number)
                number
                (cons '* number))) ; Replace this with what you actually wanted.
          list))
Or of course you could write the same thing recursively (or with DO or LOOP) if you wanted, but this strikes me as cleaner.

Re: Replacing elements in a list

Posted: Tue Jun 02, 2009 6:09 pm
by Lispoman
Thanks for your attention.

Ok let me to explain.

So i have a list A(1 2 4 -1 3 -2 6 -8). As you see here is some members which has <0 values For ex. -1 -2 -8. and some members are >0 ok just simple list. ;)
Now the goal. I need a function which place a symbol * before every member which has <0 value. Thats all! :o

One more ex.

list A before
(1 2 4 -1 3 -2 6 -8)

list after A
(1 2 4 *-1 3 *-2 6 *-8)

So if I have a member which value is <0 then I should add a symbol * before. Or by other word it should be combined in one member * and a number. Here: *-1 is one single member and *-8 is another single member

Re: Replacing elements in a list

Posted: Tue Jun 02, 2009 7:52 pm
by Paul Donnelly
Lispoman wrote:Now the goal. I need a function which place a symbol * before every member which has <0 value. Thats all! :o
That seems like a bad idea. What can you do with a symbol like "*-1"?

Re: Replacing elements in a list

Posted: Tue Jun 02, 2009 8:15 pm
by gugamilare
Lispoman wrote:So if I have a member which value is <0 then I should add a symbol * before. Or by other word it should be combined in one member * and a number. Here: *-1 is one single member and *-8 is another single member
Changing Paul Donnelly's code you can do this in a quite simple way. To take a number (e.g. -3) and return the symbol add a * before it (e.g. *-3), you can use this function:

Code: Select all

(defun add-* (number)
  (intern (format nil "*~a" number)))
This should be more than enough information for you to do what you have in mind. This looks like homework and I don't want to do it for you.

But this is a very weird task. This takes a number and returns a symbol. If this is homework, are you sure you haven't gotten the exercise wrong? Because I believe that "add a symbol * before every number in the list", is to do something like this:

Code: Select all

(add-*-before-negatives '(1 2 4 -1 3 -2 6 -8)) => (1 2 4 * -1 3 * -2 6 * -8)
If this is not homework, then I have absolutely no idea of how this can be useful, and you must be doing things the wrong way.

Re: Replacing elements in a list

Posted: Tue Jun 02, 2009 8:52 pm
by Paul
Lispoman wrote:Hi All.
I need some help cause I have no enough knowledge to complete my task. So what's the goal.
I need to define a a function which places a simbol * before every less-than-zero (-1..-5 etc.) element.
For ex. I've (setq a'(1 ,2 ,3 ,-1, -5 ,7 ,-8) a list. So then I should call a function forex MyFunc(x)
(Myfunc A) then I should get (1, 2, 3 ,*-1, *-5, 7 ,8) (i use commas here to separate elements of course no commas in the code).
I rather suspect you want (1 2 3 * -1 * -5 7 8) — i.e., with * symbols appearing before the negative values, not symbols like *-1 as everyone seems to be assuming.

Code: Select all

(defun myfunc (a x)
 (cond ((null x) nil)
 ((< (car x) 0) (cons a (myfunc a (cdr x))))
 (T (cons (car x) (myfunc a (cdr x))))))
But it just replaces every less-than-zero in a list X to A. But I need a function with just one parameter X-which represents a list.
Is this homework?

I'd write

Code: Select all

(loop for x in list when (minusp x) collect '* collect x)

Re: Replacing elements in a list

Posted: Tue Jun 02, 2009 9:10 pm
by Lispoman
Yes you right. This code has no any practical value but. I need a sample how to do such a transform because I need to use it in some functions. I did'n post my code here cause it will take a lot to explain the purpose but I need such a so called transfirmation of the list.
A function above is just what I need It adds a * symbol to anything. But how to connect it with my code I've tryed

Code: Select all


(defun add-*(number)
	   (intern (format nil "*~a" number)))
	   
(defun myfunc (x)
           (cond ((null x) nil)
                 ((< (car x) 0) (cons (add-* (car x)) (myfunc (add-* (car x)) (cdr x)))
                      (T (cons (car x) (myfunc (add-* (car x)) (cdr x)))))))
But it returns NIL insted of list.

Re: Replacing elements in a list

Posted: Tue Jun 02, 2009 10:10 pm
by Lispoman
Yeea! Solved. Nice working.

Code: Select all

(defun add (number)
  	(intern (format nil "*~a" number)))

(defun myfunc (x)
	(cond ((null x) nil)
		((< (car x) 0) (cons (add (car x)) (myfunc (cdr x))))
		(T (cons (car x) (myfunc (cdr x))))))
Thanks

Now the question can lisp differ even and odd numbers? And how can the function above be modified to use with lambda?