From: Natalia
Subject: new to lisp (back again)
Date: 
Message-ID: <38D78D0E.ADF3F09@one.net.au>
--------------29AD9FE46F6193DB435854B3
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Thanks for all the clues received last time, here is another question i
hope
someone can help me with it.

given the following input

>(BAG-TO-SET '(A A C A B C A B))
(A C B)

basically the function needs to remove duplicates and keep the order of
the elements.

I wrote the following:

(DEFUN MY-MEMBER (ITEM MYLIST)
      (COND ((NULL MYLIST) NIL)
            ((EQUAL (FIRST MYLIST) ITEM) T)
            (T(MY-MEMBER ITEM(REST MYLIST)))
      )
)
(DEFUN BAG-TO-SET (MYLIST)
   (COND ((NULL MYLIST) NIL)
         ((ATOM MYLIST) (LIST MYLIST))
         ((MY-MEMBER (FIRST MYLIST) (REST MYLIST))
          (APPEND NIL (BAG-TO-SET (REST MYLIST))))
         (T (APPEND (LIST (FIRST MYLIST)) (BAG-TO-SET (REST MYLIST))))
    )
)

which when given the same input as specified above
will return the following

>(BAG-TO-SET '(A A C A B C A B))
(C A B)

I can see that the error is where i test if the item is in the rest of
the list
and if it is i do APPEND NIL so that causes for the last A to get
appended
and therefore i lose the order of my set. I am not at all sure how to
fix this
problem. Would it be better if i was using a stack structure or should
i keep a second list that i keep comparing to the original every time i
check
an atom?
HELP PLEASE
thank you
Natalia

--------------29AD9FE46F6193DB435854B3
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<tt>Thanks for all the clues received last time, here is another question
i hope</tt>
<br><tt>someone can help me with it.</tt><tt></tt>
<p><tt>given the following input</tt><tt></tt>
<p><tt>>(BAG-TO-SET '(A A C A B C A B))</tt>
<br><tt>(A C B)</tt><tt></tt>
<p><tt>basically the function needs to remove duplicates and keep the order
of the elements.</tt><tt></tt>
<p><tt>I wrote the following:</tt><tt></tt>
<p><tt>(DEFUN MY-MEMBER (ITEM MYLIST)</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (COND ((NULL MYLIST) NIL)</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
((EQUAL (FIRST MYLIST) ITEM) T)</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
(T(MY-MEMBER ITEM(REST MYLIST)))</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )</tt>
<br><tt>)</tt>
<br><tt>(DEFUN BAG-TO-SET (MYLIST)</tt>
<br><tt>&nbsp;&nbsp; (COND ((NULL MYLIST) NIL)</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((ATOM MYLIST)
(LIST MYLIST))</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((MY-MEMBER (FIRST
MYLIST) (REST MYLIST))</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (APPEND
NIL (BAG-TO-SET (REST MYLIST))))</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (T (APPEND (LIST
(FIRST MYLIST)) (BAG-TO-SET (REST MYLIST))))</tt>
<br><tt>&nbsp;&nbsp;&nbsp; )</tt>
<br><tt>)</tt><tt></tt>
<p><tt>which when given the same input as specified above</tt>
<br><tt>will return the following</tt><tt></tt>
<p><tt>>(BAG-TO-SET '(A A C A B C A B))</tt>
<br><tt>(C A B)</tt><tt></tt>
<p><tt>I can see that the error is where i test if the item is in the rest
of the list</tt>
<br><tt>and if it is i do APPEND NIL so that causes for the last A to get
appended</tt>
<br><tt>and therefore i lose the order of my set. I am not at all sure
how to fix this</tt>
<br><tt>problem. Would it be better if i was using a stack structure or
should</tt>
<br><tt>i keep a second list that i keep comparing to the original every
time i check</tt>
<br><tt>an atom?</tt>
<br><tt>HELP PLEASE</tt>
<br><tt>thank you</tt>
<br><tt>Natalia</tt></html>

--------------29AD9FE46F6193DB435854B3--

From: Joe Marshall
Subject: Re: new to lisp (back again)
Date: 
Message-ID: <ur9d49xg1.fsf@alum.mit.edu>
Natalia <····@one.net.au> writes:

> Thanks for all the clues received last time, here is another question i hope
> someone can help me with it.
> 
> given the following input
> 
> >(BAG-TO-SET '(A A C A B C A B))
> (A C B)
> 
> basically the function needs to remove duplicates and keep the order of the elements.
> 
> I wrote the following:
> 
> (DEFUN MY-MEMBER (ITEM MYLIST)
> ����� (COND ((NULL MYLIST) NIL)
> ����������� ((EQUAL (FIRST MYLIST) ITEM) T)
> ����������� (T(MY-MEMBER ITEM(REST MYLIST)))
> ����� )
> )
> (DEFUN BAG-TO-SET (MYLIST)
> �� (COND ((NULL MYLIST) NIL)
> �������� ((ATOM MYLIST) (LIST MYLIST))
> �������� ((MY-MEMBER (FIRST MYLIST) (REST MYLIST))
> ��������� (APPEND NIL (BAG-TO-SET (REST MYLIST))))
> �������� (T (APPEND (LIST (FIRST MYLIST)) (BAG-TO-SET (REST MYLIST))))
> ��� )
> )

Some hints:  (append nil <anything>)           => <anything>

             (append (list <anything>) <tail>) => (cons <anything> <tail>)

> which when given the same input as specified above
> will return the following
> 
> >(BAG-TO-SET '(A A C A B C A B))
> (C A B)
> 
> I can see that the error is where i test if the item is in the rest of the list
> and if it is i do APPEND NIL so that causes for the last A to get appended
> and therefore i lose the order of my set. I am not at all sure how to fix this
> problem. Would it be better if i was using a stack structure or should
> i keep a second list that i keep comparing to the original every time i check
> an atom?

Keep a second list.  In fact, this second list is the result!
Instead of checking each element of MYLIST against the remaining
elements to see if it will be added later on, check each element of
MYLIST against what you have accumulated so far to see if you need to
add it.

> HELP PLEASE
> thank you

Hope this gets you started.

--
~jrm
From: Martti Halminen
Subject: Re: new to lisp (back again)
Date: 
Message-ID: <38D79838.CC6DA5BC@solibri.com>
Natalia wrote:

> given the following input
> 
> >(BAG-TO-SET '(A A C A B C A B))
> (A C B)
 
> basically the function needs to remove duplicates and keep the
> order of the elements.

While doing this yourself is useful for learning the basics, if
you only wanted the thing done there is a ready-made operation
for this in Common Lisp:

 (remove-duplicates <set> :from-end T)



> (DEFUN BAG-TO-SET (MYLIST)
>    (COND ((NULL MYLIST) NIL)
>          ((ATOM MYLIST) (LIST MYLIST))
>          ((MY-MEMBER (FIRST MYLIST) (REST MYLIST))
>           (APPEND NIL (BAG-TO-SET (REST MYLIST))))
>          (T (APPEND (LIST (FIRST MYLIST)) (BAG-TO-SET (REST
> MYLIST))))
>     )
> )
> 
> which when given the same input as specified above
> will return the following
> 
> >(BAG-TO-SET '(A A C A B C A B))
> (C A B)
> 
> I can see that the error is where i test if the item is in the
> rest of the list
> and if it is i do APPEND NIL so that causes for the last A to
> get appended
> and therefore i lose the order of my set. I am not at all sure
> how to fix this
> problem. 

NIL -> (first mylist), (REST MYLIST) -> (remove (first mylist)
(rest mylist))


> Would it be better if i was using a stack structure
> or should
> i keep a second list that i keep comparing to the original
> every time i check
> an atom?

The easiest way to implement a stack in this kind of use is just
a list, operated on by push and pop.

- You'll probably find reverse or nreverse useful, too, with a
stack.




-- 


> Natalia
From: Andrew Cooke
Subject: Re: new to lisp (back again)
Date: 
Message-ID: <8b87ro$fs2$1@nnrp1.deja.com>
In article <················@one.net.au>,
Natalia <····@one.net.au> wrote:
> >(BAG-TO-SET '(A A C A B C A B))
> (A C B)

someone's already posted the simplest soln, but if you have to write the
code yourself, using loop is perhaps simplest (i didn't learn loop at
first because it seemed complicated, but it can be very useful).  you'd
need to "collect into" a list, and use a when clause to make sure that
the item you were collecting wasn't already in that list (if you don't
need to define your own test function, you can use member).

andrew


Sent via Deja.com http://www.deja.com/
Before you buy.
From: Natalia
Subject: Re: new to lisp (back again)
Date: 
Message-ID: <38D822D3.ADDD8DC4@one.net.au>
Andrew Cooke wrote:

> In article <················@one.net.au>,
> Natalia <····@one.net.au> wrote:
> > >(BAG-TO-SET '(A A C A B C A B))
> > (A C B)
>
> someone's already posted the simplest soln, but if you have to write the
> code yourself, using loop is perhaps simplest (i didn't learn loop at
> first because it seemed complicated, but it can be very useful).  you'd
> need to "collect into" a list, and use a when clause to make sure that
> the item you were collecting wasn't already in that list (if you don't
> need to define your own test function, you can use member).
>
> andrew
>

I thought of using a loop, but unfortunately the questions asks us to
do the solution recursively : (
From: Christopher Browne
Subject: Re: new to lisp (back again)
Date: 
Message-ID: <slrn8dgaqu.f8.cbbrowne@knuth.brownes.org>
Centuries ago, Nostradamus foresaw a time when Natalia would say:
>I thought of using a loop, but unfortunately the questions asks us to
>do the solution recursively : (

This is the unfortunate part of much of the teaching that is done with
"non-Algol-descended" languges; they tend to be used solely to exercise
the bit of functionality that the instructor feels is the "point" of the 
language.

In the case of Lisp, that is recursion.
-- 
((lambda (foo) (bar foo)) (baz))
········@ntlug.org - - <http://www.hex.net/~cbbrowne/lisp.html>
From: Fernando D. Mato Mira
Subject: Re: new to lisp (back again)
Date: 
Message-ID: <38D8A383.FA6C7A21@iname.com>
Natalia wrote:

> I thought of using a loop, but unfortunately the questions asks us to
> do the solution recursively : (

Show your prof this "solution". He can download the next version of Series
when it comes out ;)

* (defvar *must-not-destroy1* '(a b c))
*MUST-NOT-DESTROY1*
* (defvar *must-not-destroy2* '(a c e))
*MUST-NOT-DESTROY2*
* (delete-duplicates (append *must-not-destroy1* *must-not-destroy2*)
:from-end t)
(A B C E)
* (collect 'ordered-set (catenate (scan *must-not-destroy1*)  (scan
*must-not-destroy2*)))
(A B C E)
* (collect 'set (catenate (scan *must-not-destroy1*)  (scan
*must-not-destroy2*)))
(E C B A)
* *must-not-destroy1*
(A B C)
* *must-not-destroy2*
(A C E)
* (macroexpand '(collect 'ordered-set (catenate (scan *must-not-destroy1*)
(scan *must-not-destroy2*))))
(COMMON-LISP:LET (#:OUT-949
                  #:OUT-954
                  #:ELEMENTS-946
                  #:LISTPTR-947
                  #:ELEMENTS-951
                  #:LISTPTR-952
                  #:ITEMS-943
                  (#:FLAG-944 NIL)
                  #:TABLE-933
                  #:LASTCONS-934
                  (#:LST-935 NIL))
  (DECLARE (TYPE BOOLEAN #:FLAG-944) (TYPE LIST #:LST-935))
  (LOCALLY
   (DECLARE (TYPE LIST #:LISTPTR-947)
            (TYPE LIST #:LISTPTR-952)
            (TYPE CONS #:LASTCONS-934))
   (SETQ #:OUT-949 *MUST-NOT-DESTROY1*)
   (SETQ #:OUT-954 *MUST-NOT-DESTROY2*)
   (SETQ #:LISTPTR-947 #:OUT-949)
   (SETQ #:LISTPTR-952 #:OUT-954)
   (SETQ #:LASTCONS-934 (LIST NIL))
   (SETQ #:LST-935 #:LASTCONS-934)
   (SETQ #:TABLE-933 (MAKE-HASH-TABLE))
   (TAGBODY
    #:LL-955
     (IF #:FLAG-944 (GO #:B-938))
     (IF (ENDP #:LISTPTR-947) (GO #:F-939))
     (SETQ #:ELEMENTS-946 (THE T (CAR #:LISTPTR-947)))
     (SETQ #:LISTPTR-947 (CDR #:LISTPTR-947))
     (SETQ #:ITEMS-943 #:ELEMENTS-946)
     (GO #:D-936)
    #:F-939
     (SETQ #:FLAG-944 T)
    #:B-938
     (IF (ENDP #:LISTPTR-952) (GO SERIES::END))
     (SETQ #:ELEMENTS-951 (THE T (CAR #:LISTPTR-952)))
     (SETQ #:LISTPTR-952 (CDR #:LISTPTR-952))
     (SETQ #:ITEMS-943 #:ELEMENTS-951)
    #:D-936
     (COMMON-LISP:LET* ((SERIES::ITEM #:ITEMS-943)
                        (SERIES::VAL (GETHASH SERIES::ITEM #:TABLE-933)))
       (UNLESS SERIES::VAL
         (SETF (GETHASH SERIES::ITEM #:TABLE-933) T)
         (SETQ #:LASTCONS-934
                 (SETF (CDR #:LASTCONS-934) (CONS SERIES::ITEM NIL)))))
     (GO #:LL-955)
    SERIES::END)
   (CDR #:LST-935)))
T
* (macroexpand '(collect 'set (catenate (scan *must-not-destroy1*)  (scan
*must-not-destroy2*))))
(COMMON-LISP:LET (#:OUT-972
                  #:OUT-977
                  #:ELEMENTS-969
                  #:LISTPTR-970
                  #:ELEMENTS-974
                  #:LISTPTR-975
                  #:ITEMS-966
                  (#:FLAG-967 NIL)
                  #:TABLE-957
                  (#:LST-958 NIL))
  (DECLARE (TYPE BOOLEAN #:FLAG-967) (TYPE LIST #:LST-958))
  (LOCALLY
   (DECLARE (TYPE LIST #:LISTPTR-970) (TYPE LIST #:LISTPTR-975))
   (SETQ #:OUT-972 *MUST-NOT-DESTROY1*)
   (SETQ #:OUT-977 *MUST-NOT-DESTROY2*)
   (SETQ #:LISTPTR-970 #:OUT-972)
   (SETQ #:LISTPTR-975 #:OUT-977)
   (SETQ #:TABLE-957 (MAKE-HASH-TABLE))
   (TAGBODY
    #:LL-978
     (IF #:FLAG-967 (GO #:B-961))
     (IF (ENDP #:LISTPTR-970) (GO #:F-962))
     (SETQ #:ELEMENTS-969 (THE T (CAR #:LISTPTR-970)))
     (SETQ #:LISTPTR-970 (CDR #:LISTPTR-970))
     (SETQ #:ITEMS-966 #:ELEMENTS-969)
     (GO #:D-959)
    #:F-962
     (SETQ #:FLAG-967 T)
    #:B-961
     (IF (ENDP #:LISTPTR-975) (GO SERIES::END))
     (SETQ #:ELEMENTS-974 (THE T (CAR #:LISTPTR-975)))
     (SETQ #:LISTPTR-975 (CDR #:LISTPTR-975))
     (SETQ #:ITEMS-966 #:ELEMENTS-974)
    #:D-959
     (SETF (GETHASH #:ITEMS-966 #:TABLE-957) T)
     (GO #:LL-978)
    SERIES::END)
   (WITH-HASH-TABLE-ITERATOR (SERIES::NEXT-ENTRY #:TABLE-957)
     (LOOP
      (MULTIPLE-VALUE-BIND (SERIES::MORE SERIES::KEY SERIES::VAL)
                           (SERIES::NEXT-ENTRY)
                           (DECLARE (IGNORE SERIES::VAL))
                           (UNLESS SERIES::MORE (RETURN #:LST-958))
                           (PUSH SERIES::KEY #:LST-958))))
   #:LST-958))


It's the compiler's job to get rid of redundant variables, of course ;)

--
Fernando D. Mato Mira
Real-Time SW Eng & Networking
Advanced Systems Engineering Division
CSEM
Jaquet-Droz 1                   email: matomira AT acm DOT org
CH-2007 Neuchatel                 tel:       +41 (32) 720-5157
Switzerland                       FAX:       +41 (32) 720-5720

www.csem.ch      www.vrai.com     ligwww.epfl.ch/matomira.html
From: Fernando D. Mato Mira
Subject: Re: new to lisp (back again)
Date: 
Message-ID: <38D8D0D2.DE02D040@iname.com>
"Fernando D. Mato Mira" wrote:

> * (defvar *must-not-destroy2* '(a c e))
> *MUST-NOT-DESTROY2*
> * (delete-duplicates (append *must-not-destroy1* *must-not-destroy2*)
> :from-end t)
> (A B C E)

This is called being lucky in inputs.

(A A C E)
* (delete-duplicates (append *must-not-destroy1* *must-not-destroy2*)
:from-end t)
(A B C E)
* *must-not-destroy2*
(A A C E)

And this is called being lucky in implementation.

The correct code is:

(delete-duplicates (append *must-not-destroy1* (copy-list
*must-not-destroy2*)) :from-end t)


And Series touches home again twice!  It's the World Series :)


--
Fernando D. Mato Mira
Real-Time SW Eng & Networking
Advanced Systems Engineering Division
CSEM
Jaquet-Droz 1                   email: matomira AT acm DOT org
CH-2007 Neuchatel                 tel:       +41 (32) 720-5157
Switzerland                       FAX:       +41 (32) 720-5720

www.csem.ch      www.vrai.com     ligwww.epfl.ch/matomira.html
From: Fernando D. Mato Mira
Subject: Re: new to lisp (back again)
Date: 
Message-ID: <38D9E9BE.4046F75A@iname.com>
"Fernando D. Mato Mira" wrote:

> (A A C E)
> * (delete-duplicates (append *must-not-destroy1* *must-not-destroy2*)
> :from-end t)
> (A B C E)
> * *must-not-destroy2*
> (A A C E)
>
> And this is called being lucky in implementation.

Stiil lucky with inputs

* (defvar *must-not-destroy2* '(e c a))
*MUST-NOT-DESTROY2*
* (delete-duplicates (append *must-not-destroy1* *must-not-destroy2*)
:from-end t)
(A B C E)
* *MUST-NOT-DESTROY2*
(E)

--
Fernando D. Mato Mira
Real-Time SW Eng & Networking
Advanced Systems Engineering Division
CSEM
Jaquet-Droz 1                   email: matomira AT acm DOT org
CH-2007 Neuchatel                 tel:       +41 (32) 720-5157
Switzerland                       FAX:       +41 (32) 720-5720

www.csem.ch      www.vrai.com     ligwww.epfl.ch/matomira.html