Lisp make a subset

Lisp make a subset

xuantientutungXUK6E
Advocate Advocate
2,144 Views
9 Replies
Message 1 of 10

Lisp make a subset

xuantientutungXUK6E
Advocate
Advocate

hi guys

i have a list ( 1 2 3 4 5)

how can i make a lisp subset with result is a list ( (  1 2) (1 3 ) ( 1 2 3) ..............................v .............v)

hope you guys give me some suggestions.

thank you

0 Likes
Accepted solutions (1)
2,145 Views
9 Replies
Replies (9)
Message 2 of 10

Sea-Haven
Mentor
Mentor

Using the nth function can make list of lists, your pattern does not seem quite correct.  You need to show more to see what sort of result your after. (list (nth x lst)(nth (+ x 1)))

0 Likes
Message 3 of 10

xuantientutungXUK6E
Advocate
Advocate

the result is a list of subset.

example  

list is ( 1 2 3 4)

result is ( (1 2 ) (1 3) (1 4) (2 3) (2 4) (3 4) (1 2 3 ) ( 1 2 4) ( 2 3 4) (1 2 3 4))

thanks 

0 Likes
Message 4 of 10

Sea-Haven
Mentor
Mentor

Need a recursive solution for even more than 4 items. if 4 then total new list is 4+3+2+1=10 items maybe.

 

Its a lambda style answer and not something I am expert at. If have time will have a go.

 

 

 

0 Likes
Message 5 of 10

ВeekeeCZ
Consultant
Consultant
Accepted solution

HERE is a sub from Lee Mac that you need.

0 Likes
Message 6 of 10

pbejse
Mentor
Mentor

@xuantientutungXUK6E wrote:

 

list is ( 1 2 3 4)

result is ( (1 2 ) (1 3) (1 4) (2 3) (2 4) (3 4) (1 2 3 ) ( 1 2 4) ( 2 3 4) (1 2 3 4))

 

 

Are you trying to break somebody's PIN number or something? Smiley Happy

 

is it just so happen that the list is sorted that way?  will it be ever like this '("A" 2 1.5 "A") ? where the order or type has nothing to do with the result? 

 

'cmon guys, crank up that grey matter of yours and start coding 🙂

 

 

 

 

 

 

0 Likes
Message 7 of 10

Kent1Cooper
Consultant
Consultant

@pbejse wrote:

....

is it just so happen that the list is sorted that way?  will it be ever like this '("A" 2 1.5 "A") ? where the order or type has nothing to do with the result? ....


 

Despite the heading on that linked thread, Lee Mac's (nCr) routine works with repeat  items in the list, and  with different kinds  of items.  So, given your example list:

(setq lst '("A" 2 1.5 "A"))

 

Then we do:

 

Command: (setq result (list lst))
  (("A" 2 1.5 "A")) ; initial result list containing original list [last item in final result]

Command: (repeat (setq m (- (length lst) 2)) (setq result (append (nCr lst (1+ m)) result)) (setq m (1- m)))
  0 [what it returns to the Command line at the end, but what it has built is:]

Command: !result
(("A" 2) ("A" 1.5) ("A" "A") (2 1.5) (2 "A") (1.5 "A") ("A" 2 1.5) ("A" 2 "A") ("A" 1.5 "A") (2 1.5 "A") ("A" 2 1.5 "A"))

 

EDIT:  Or, to put it together:

(defun AllSubSets (lst / nCr m)

;; (nCr) function by Lee Mac on "Combinations without
;;   repetition 3 and 4 element." thread, February 9, 2016
  (defun nCr (l r)
    (cond
      ((< r 2)
        (mapcar 'list l)
      )
      (l
        (append
          (mapcar '(lambda ( x ) (cons (car l) x)) (nCr (cdr l) (1- r)))
          (nCr (cdr l) r)
        )
      )
    )
  )

  (setq result (list lst))
  (repeat (setq m (- (length lst) 2))
    (setq result ; not localized 
      (append
        (nCr lst (1+ m))
        result
      ); append
    ); setq
    (setq m (1- m))
  ); repeat
  result ; reported to Command line [also remains in variable]
); defun

 

Usage:

 

Command: (AllSubSets '("A" 2 1.5 "A"))
(("A" 2) ("A" 1.5) ("A" "A") (2 1.5) (2 "A") (1.5 "A") ("A" 2 1.5) ("A" 2 "A") ("A" 1.5 "A") (2 1.5 "A") ("A" 2 1.5 "A"))

Kent Cooper, AIA
Message 8 of 10

ronjonp
Advisor
Advisor

Here's another way using mapcar:

(defun allsubsets (l / i ncr)
  ;; https://www.cadtutor.net/forum/topic/59422-combinations-without-repetition-3-and-4-element/?tab=comments#comment-491704
  (defun ncr (l r)
    (cond ((< r 2) (mapcar 'list l))
	  (l (append (mapcar '(lambda (x) (cons (car l) x)) (ncr (cdr l) (1- r))) (ncr (cdr l) r)))
    )
  )
  (setq i 1)
  (apply 'append (mapcar '(lambda (x) (ncr l (setq i (1+ i)))) l))
)
(allsubsets '("A" 2 1.5 "A"))
;;(("A" 2) ("A" 1.5) ("A" "A") (2 1.5) (2 "A") (1.5 "A") ("A" 2 1.5) ("A" 2 "A") ("A" 1.5 "A") (2 1.5 "A") ("A" 2 1.5 "A"))
0 Likes
Message 9 of 10

dlanorh
Advisor
Advisor

Strictly speaking

 

("A" 2 1.5 "A")

 

is not a subset as a proper subset of a set A is a subset of A that is not equal to A, and so should also include ("A") (2) & (1.5)

I am not one of the robots you're looking for

0 Likes
Message 10 of 10

ronjonp
Advisor
Advisor

@dlanorh wrote:

Strictly speaking

 

("A" 2 1.5 "A")

 

is not a subset as a proper subset of a set A is a subset of A that is not equal to A, and so should also include ("A") (2) & (1.5)


Agreed .. just matching the OP's result list 🙂

 

Here is another variant using more of Lee's code:

(defun allsubsets (l / lm:unique ncr i)
  ;; http://www.lee-mac.com/uniqueduplicate.html#uniquer
  (defun lm:unique (l)
    (if	l (cons (car l) (lm:unique (vl-remove (car l) (cdr l)))))
  )
  ;; https://www.cadtutor.net/forum/topic/59422-combinations-without-repetition-3-and-4-element/?tab=comments#comment-491704
  (defun ncr (l r)
    (cond ((< r 2) (mapcar 'list l))
	  (l (append (mapcar '(lambda (x) (cons (car l) x)) (ncr (cdr l) (1- r))) (ncr (cdr l) r)))
    )
  )
  (setq i 0)
  (lm:unique (apply 'append (mapcar '(lambda (x) (ncr l (setq i (1+ i)))) l)))
)
(allsubsets '("A" 2 1.5 "A"))
;; (("A") (2) (1.5) ("A" 2) ("A" 1.5) ("A" "A") (2 1.5) (2 "A") (1.5 "A") ("A" 2 1.5) ("A" 2 "A") ("A" 1.5 "A") (2 1.5 "A") ("A" 2 1.5 "A"))