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
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
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
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 ***
"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
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
"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
"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/