From: Atte
Subject: Initial subset
Date: 
Message-ID: <1121595885.237771.253170@g14g2000cwa.googlegroups.com>
A newbie asks:

I'd like to get '(5 1 3 9) as an output when the original set is

(5 1 3 3 5 9 1 4 0 5 9 1 4 10).

This doesn't work:

(defun create_initial_set (original_set)
  (if (= (length (remove-duplicates *initial_set*)) 4) *initial_set*
      (setf *initial_set*
            (append (list (first original_set))
              (create_initial_set (rest original_set))))))

What's wrong there?

From: Gareth McCaughan
Subject: Re: Initial subset
Date: 
Message-ID: <87oe91zpc4.fsf@g.mccaughan.ntlworld.com>
"Atte" wrote:

> I'd like to get '(5 1 3 9) as an output when the original set is
> 
> (5 1 3 3 5 9 1 4 0 5 9 1 4 10).

Why. I mean, what *in the general case* is it that you want?
First four unique elements?

> This doesn't work:
> 
> (defun create_initial_set (original_set)
>   (if (= (length (remove-duplicates *initial_set*)) 4) *initial_set*
>       (setf *initial_set*
>             (append (list (first original_set))
>               (create_initial_set (rest original_set))))))
> 
> What's wrong there?

Before even looking at the algorithm, one thing troubles me.
You're using a special[1] variable, but it doesn't seem to
be initialized anywhere.

    [1] You can interpret this as "global" for the time being
        without too much harm, though actually the meaning is
        more subtle than that.

Another, purelty stylistic, thing: the following two forms
produce equivalent results:

    (append (list SOMETHING-OR-OTHER) SOMETHING-ELSE)
    (const SOMETHING-OR-OTHER SOMETHING-ELSE)

and the latter is generally better style.

Are you sure you're removing duplicates from the right thing?

-- 
Gareth McCaughan
.sig under construc
From: Louis Theran
Subject: Re: Initial subset
Date: 
Message-ID: <1121626826.065712.214620@g14g2000cwa.googlegroups.com>
Atte wrote:
> A newbie asks:
>
> I'd like to get '(5 1 3 9) as an output when the original set is
>
> (5 1 3 3 5 9 1 4 0 5 9 1 4 10).

The reason it doesn't work is that you need to use (remove-duplicates
... :from-end t) instead of just (remove-duplicates ...).  You also
don't need the special vairable.  Try something like this:

(defun first-k-unique (k seq)
  (subseq (remove-duplicates seq :from-end t) 0 k))

^L
From: Atte
Subject: Re: Initial subset
Date: 
Message-ID: <1121630140.069487.315210@g49g2000cwa.googlegroups.com>
Thanks for answers. Now I can go on and I learned a new function,
subseq.
From: Larry Clapp
Subject: Re: Initial subset
Date: 
Message-ID: <slrnddksqv.k91.larry@theclapp.ddts.net>
On 2005-07-17, Atte <·······@utu.fi> wrote:
> I'd like to get '(5 1 3 9) as an output when the original set is
>
> (5 1 3 3 5 9 1 4 0 5 9 1 4 10).
>
> This doesn't work:
>
> (defun create_initial_set (original_set)
>   (if (= (length (remove-duplicates *initial_set*)) 4) *initial_set*
>       (setf *initial_set*
>             (append (list (first original_set))
>               (create_initial_set (rest original_set))))))

1)

Perhaps you should first clear up the confusion between ORIGINAL_SET
and *INITIAL_SET*.  Did you want one or the other?

2) 

Some printing might come in handy:

(defun create_initial_set (original_set)
  (format t "create_initial_set called with ~S~%" original_set)
  (if (= (length (remove-duplicates *initial_set*)) 4)
    *initial_set*
    (setf *initial_set*
	  (append (list (first original_set))
		  (create_initial_set (rest original_set))))))

(create_initial_set *initial_set*)
->create_initial_set called with (5 1 3 3 5 9 1 4 0 5 9 1 4 10)
->create_initial_set called with (1 3 3 5 9 1 4 0 5 9 1 4 10)
->create_initial_set called with (3 3 5 9 1 4 0 5 9 1 4 10)
->create_initial_set called with (3 5 9 1 4 0 5 9 1 4 10)
->create_initial_set called with (5 9 1 4 0 5 9 1 4 10)
->create_initial_set called with (9 1 4 0 5 9 1 4 10)
->create_initial_set called with (1 4 0 5 9 1 4 10)
->create_initial_set called with (4 0 5 9 1 4 10)
->create_initial_set called with (0 5 9 1 4 10)
->create_initial_set called with (5 9 1 4 10)
->create_initial_set called with (9 1 4 10)
->create_initial_set called with (1 4 10)
->create_initial_set called with (4 10)
->create_initial_set called with (10)
->create_initial_set called with NIL
->create_initial_set called with NIL
->create_initial_set called with NIL
... etc.

See any problems?  ;)

3)

Also realize 

  (remove-duplicates *initial_set*)
  => (3 0 5 9 1 4 10)

so, at a guess, the best you'd get is (3 0 5 9).

4)

Perhaps you wanted

  (remove-duplicates *initial_set* :from-end t)
  => (5 1 3 9 4 0 10)

5)

I don't want to give the *whole* thing away; perhaps this will help:

  CL-USER> (defvar *initial_set* '(5 1 3 3 5 9 1 4 0 5 9 1 4 10))
  *INITIAL_SET*

  CL-USER> *initial_set*
  (5 1 3 3 5 9 1 4 0 5 9 1 4 10)

  CL-USER> (defvar *new-set* (remove-duplicates *initial_set* :from-end t))
  *NEW-SET*

  CL-USER> *new-set*
  (5 1 3 9 4 0 10)

  CL-USER> (length *new-set*)
  7

  CL-USER> (subseq *new-set* 0 4)
  (5 1 3 9)

-- Larry