Replacing elements in a list

Discussion of Common Lisp

Replacing elements in a list

Postby Lispoman » Mon Jun 01, 2009 6:43 pm

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.
Lispoman
 
Posts: 12
Joined: Mon Jun 01, 2009 6:09 pm

Re: Replacing elements in a list

Postby Harleqin » Tue Jun 02, 2009 10:42 am

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.
"Just throw more hardware at it" is the root of all evil.
Svante
Harleqin
 
Posts: 71
Joined: Wed Dec 17, 2008 5:18 am
Location: Bonn, Germany

Re: Replacing elements in a list

Postby Jasper » Tue Jun 02, 2009 12:13 pm

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.
Last edited by Jasper on Tue Jun 02, 2009 3:06 pm, edited 1 time in total.
Jasper
 
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands

Re: Replacing elements in a list

Postby Paul Donnelly » Tue Jun 02, 2009 1:11 pm

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.
Paul Donnelly
 
Posts: 148
Joined: Wed Jul 30, 2008 11:26 pm

Re: Replacing elements in a list

Postby Lispoman » Tue Jun 02, 2009 6:09 pm

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
Lispoman
 
Posts: 12
Joined: Mon Jun 01, 2009 6:09 pm

Re: Replacing elements in a list

Postby Paul Donnelly » Tue Jun 02, 2009 7:52 pm

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"?
Paul Donnelly
 
Posts: 148
Joined: Wed Jul 30, 2008 11:26 pm

Re: Replacing elements in a list

Postby gugamilare » Tue Jun 02, 2009 8:15 pm

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.
gugamilare
 
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil

Re: Replacing elements in a list

Postby Paul » Tue Jun 02, 2009 8:52 pm

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)
Paul
 
Posts: 106
Joined: Tue Jun 02, 2009 6:00 am

Re: Replacing elements in a list

Postby Lispoman » Tue Jun 02, 2009 9:10 pm

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.
Lispoman
 
Posts: 12
Joined: Mon Jun 01, 2009 6:09 pm

Re: Replacing elements in a list

Postby Lispoman » Tue Jun 02, 2009 10:10 pm

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?
Lispoman
 
Posts: 12
Joined: Mon Jun 01, 2009 6:09 pm

Next

Return to Common Lisp

Who is online

Users browsing this forum: Google [Bot], Yahoo [Bot] and 2 guests