From: Christian Soltenborn
Subject: Changing position of two elements in a list
Date: 
Message-ID: <c0emsl$16rp45$1@ID-36219.news.uni-berlin.de>
Hello Lisp-experts,

is there any efficient way to swap two elements in a list?

Something like

(swap '(a b c d e) 1 2)
(a c b d e)

Thanks in advance,

Christian

From: Paul F. Dietz
Subject: Re: Changing position of two elements in a list
Date: 
Message-ID: <NsqdnabYycXPfLfd4p2dnA@dls.net>
Christian Soltenborn wrote:

> (swap '(a b c d e) 1 2)
> (a c b d e)

(defun swap (list pos1 pos2)
   (rotatef (elt list pos1) (elt list pos2))
   list)

I hope this wasn't a homework problem.

	Paul
From: Christian Soltenborn
Subject: Re: Changing position of two elements in a list
Date: 
Message-ID: <c0enr8$15j8bu$1@ID-36219.news.uni-berlin.de>
Paul F. Dietz wrote:

> Christian Soltenborn wrote:
> 
>> (swap '(a b c d e) 1 2)
>> (a c b d e)
> 
> 
> (defun swap (list pos1 pos2)
>   (rotatef (elt list pos1) (elt list pos2))
>   list)
> 
> I hope this wasn't a homework problem.

Let me put it like this: it's part of a much bigger homework problem 
which is due to friday - so be prepared for some more questions :-)

Thanks for the fast answer!

bye,
Christian
From: Barry Margolin
Subject: Re: Changing position of two elements in a list
Date: 
Message-ID: <barmar-DC28E5.01502612022004@comcast.ash.giganews.com>
In article <···············@ID-36219.news.uni-berlin.de>,
 Christian Soltenborn <···················@webmail.de> wrote:

> Let me put it like this: it's part of a much bigger homework problem 
> which is due to friday - so be prepared for some more questions :-)

Then *please* ask questions, don't just ask for solutions.  Explain what 
you tried, what your thought process was, show the code that doesn't 
work.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Tim Bradshaw
Subject: Re: Changing position of two elements in a list
Date: 
Message-ID: <fbc0f5d1.0402120250.17cb0978@posting.google.com>
"Paul F. Dietz" <·····@dls.net> wrote in message news:<······················@dls.net>...
> 
> (defun swap (list pos1 pos2)
>    (rotatef (elt list pos1) (elt list pos2))
>    list)

For the original poster: this may or may not match your notion of
`efficient'.  It's *concise*, but it has to traverse the list to do
its work, the same as any other thing that manipulates lists.

--tim
From: Paul F. Dietz
Subject: Re: Changing position of two elements in a list
Date: 
Message-ID: <PYidnSzwP4Mb_bbdRVn-vA@dls.net>
Tim Bradshaw wrote:
> "Paul F. Dietz" <·····@dls.net> wrote in message news:<······················@dls.net>...
> 
>>(defun swap (list pos1 pos2)
>>   (rotatef (elt list pos1) (elt list pos2))
>>   list)
> 
> 
> For the original poster: this may or may not match your notion of
> `efficient'.  It's *concise*, but it has to traverse the list to do
> its work, the same as any other thing that manipulates lists.

It's as efficient (to within a constant factor) as any other
algorithm for the problem.

	Paul
From: Tim Bradshaw
Subject: Re: Changing position of two elements in a list
Date: 
Message-ID: <fbc0f5d1.0402120832.71561e67@posting.google.com>
"Paul F. Dietz" <·····@dls.net> wrote in message news:<······················@dls.net>...

> 
> It's as efficient (to within a constant factor) as any other
> algorithm for the problem.
> 
Yes, I know.  I was (clumsily) trying to warn the OP that lists aren't
arrays, in case that's what they meant by `efficient'.

--tim
From: Pascal Bourguignon
Subject: Re: Changing position of two elements in a list
Date: 
Message-ID: <87smhgecin.fsf@thalassa.informatimago.com>
"Paul F. Dietz" <·····@dls.net> writes:

> Tim Bradshaw wrote:
> > "Paul F. Dietz" <·····@dls.net> wrote in message news:<······················@dls.net>...
> >
> >>(defun swap (list pos1 pos2)
> >>   (rotatef (elt list pos1) (elt list pos2))
> >>   list)
> > For the original poster: this may or may not match your notion of
> > `efficient'.  It's *concise*, but it has to traverse the list to do
> > its work, the same as any other thing that manipulates lists.
> 
> It's as efficient (to within a constant factor) as any other
> algorithm for the problem.

Actually, if the list  is long and pos1 and pos2 are  big, and this is
done often, it may be worthwhile to implement such a function:

    (defun get-two-cons (list pos1 pos2)
        "walk the list up to (max pos1 pos2) once and return two values:
         the cons cells at pos1 and pos2"
      (error "Not implemented yet: exercice for the reader.")
      (values cons1 cons2))

and:

    (multiple-value-bind (cons1 cons2) (get-two-cons list pos1 pos2)
       (rotatef (car cons1) (car cons2)))

should be twice as fast as the above swap function.


But we're  only playing  with constants here  (unless the  swapping is
done a number of time proportional to the positions...).


-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/