Visual LISP, AutoLISP and General Customization

Reply
Distinguished Contributor
markruys
Posts: 108
Registered: ‎10-02-2007
Message 1 of 9 (298 Views)
Accepted Solution

grouping numbers

298 Views, 8 Replies
11-21-2012 09:30 AM

i am trying to group nubers together whichever consecutive

for example : original list '(1 2 3 6 9 10 11 44 55 56 77) in a list

outpot list  '((1 2 3)(6)(9 10 11)(44)(55 56)(77))

seems to be simple, but have been strugglig for a day or so...

any help will be gratly appreciated

TIA

*Expert Elite*
Kent1Cooper
Posts: 5,231
Registered: ‎09-13-2004
Message 2 of 9 (290 Views)

Re: grouping numbers

11-21-2012 10:18 AM in reply to: markruys

markruys wrote:

i am trying to group nubers together whichever consecutive

for example : original list '(1 2 3 6 9 10 11 44 55 56 77) in a list

outpot list  '((1 2 3)(6)(9 10 11)(44)(55 56)(77))

....


This seems to do that:

 

(defun CGI (numlist / sublist lastint cumlist); = Consecutively-Grouped Integers
  (setq sublist (list (setq lastint (car numlist)))); start first sublist with first integer
  (foreach int (cdr numlist)
    (if (= int (1+ lastint)); consecutive from previous?
      (setq sublist (append sublist (list int))); then -- add it to consecutive group
      (setq ; else
        cumlist (append cumlist (list sublist)); add so-far group to cumulative list
        sublist (list int); start new sublist
      ); setq
    ); if
    (setq lastint int)
  ); foreach
  (setq cumlist (append cumlist (list sublist))); add last group
); defun

 

Usage:

Command: (cgi '(1 2 3 6 9 10 11 44 55 56 77))

returns
((1 2 3) (6) (9 10 11) (44) (55 56) (77))

Kent Cooper
Distinguished Contributor
markruys
Posts: 108
Registered: ‎10-02-2007
Message 3 of 9 (279 Views)

Re: grouping numbers

11-21-2012 10:41 AM in reply to: Kent1Cooper

kent,

thanks for the code, compact and simple

have a nice thankgiving

m

*Expert Elite*
Kent1Cooper
Posts: 5,231
Registered: ‎09-13-2004
Message 4 of 9 (269 Views)

Re: grouping numbers

11-21-2012 11:22 AM in reply to: markruys

markruys wrote:

kent,

thanks for the code, compact and simple

have a nice thankgiving

m


My pleasure.  It also occurs to me that it would be easy to have the routine sort the initial list into order, if it may not always be already, just in case.

Kent Cooper
Contributor
bobdobbs
Posts: 15
Registered: ‎09-27-2012
Message 5 of 9 (261 Views)

Re: grouping numbers

11-21-2012 12:06 PM in reply to: Kent1Cooper

Dang! I was too slow.

 

The following will sort *and* not drop duplicate numbers (like vl-sort does).

 

(defun gl (lst / sl li ml)
;;; quick number grouping
;;; by me
;;; requires (std-%insertion-sort) 
;;; by Serge Pashkov
;;;
;;; usage example: (gl '(1 3 4 6 7 8 9 1 4 67)) => ((1 1) (3 4 4) (6 7 8 9) (67))
;;;
	(setq sl (list (nth 0 (std-%insertion-sort lst '<))) ml ())
	(foreach li (cdr (std-%insertion-sort lst '<))
		(if (or (member li sl) (= li (1- (last (std-%insertion-sort sl '<)))) (= li (1+ (last (std-%insertion-sort sl '<)))))
			(setq sl (std-%insertion-sort (cons li sl) '<))
			(setq	ml (cons sl ml)
					sl (list li)
			)
		)
	)
	(setq ml (reverse (cons sl ml)))
)
(defun std-%insertion-sort (lst cmp / M N O cO)
;;; --Part of STDLSP.LSP By: Reini Urban
;;; stable insertion sort, fast for already ordered and short lists
;;; very slow for reversed or random lists O(n^2)
;;; by Serge Pashkov
  (setq O (reverse lst) M nil N (list (car O)))
  (while (setq O (cdr O))
    (setq cO (car O))
    (while (and N (apply cmp (list (car N) cO)))
      (setq M (cons (car N) M)
            N (cdr N)))
    (setq N (cons cO N))
    (while M
      (setq N (cons (car M) N) M (cdr M))))
  N)

 

 

 

*Expert Elite*
Kent1Cooper
Posts: 5,231
Registered: ‎09-13-2004
Message 6 of 9 (243 Views)

Re: grouping numbers

11-21-2012 02:08 PM in reply to: bobdobbs

bobdobbs wrote:

.... 

The following will sort *and* not drop duplicate numbers (like vl-sort does).

....


Interesting idea, if duplicates are a possibility.  A more concise way than std-%insertion-sort to sort a list of numerical values and not drop duplicate numbers:
 

;; SKD = Sort, Keep Duplicates [unlike vl-sort, which eliminates them]
;; for a list of numerical values
(defun SKD (numlist oper / sortlist)
  (foreach x (vl-sort numlist oper)
    (setq sortlist (append sortlist (vl-remove-if-not '(lambda (y) (= y x)) numlist)))
  ); foreach
); defun

 

Usage:

Command: (skd '(1 3 4 6 7 8 9 1 4 67) '<)

returns
(1 1 3 4 4 6 7 8 9 67)

 

Incorporating that approach into my earlier CGI function:

 

(defun CGI (numlist / sortlist sublist lastint cumlist); = Consecutively-Grouped Integers

  (vl-load-com); [if needed]
  (foreach x (vl-sort numlist '<)
    (setq sortlist (append sortlist (vl-remove-if-not '(lambda (y) (= y x)) numlist)))
  ); foreach
  (setq sublist (list (setq lastint (car sortlist)))); start first sublist with first integer
  (foreach int (cdr sortlist)
    (if (or (= int lastint) (= int (1+ lastint))); equal to or consecutive from previous?
      (setq sublist (append sublist (list int))); then -- add it to consecutive group
      (setq ; else
        cumlist (append cumlist (list sublist)); add so-far group to cumulative list
        sublist (list int); start new sublist
      ); setq
    ); if
    (setq lastint int)
  ); foreach
  (setq cumlist (append cumlist (list sublist))); add last group
); defun

 

Usage:

Command: (cgi '(1 3 4 6 7 8 9 1 4 67))

returns
((1 1) (3 4 4) (6 7 8 9) (67))

Kent Cooper
*Expert Elite*
pbejse
Posts: 2,406
Registered: ‎11-24-2009
Message 7 of 9 (232 Views)

Re: grouping numbers

11-21-2012 07:43 PM in reply to: markruys

markruys wrote:

i am trying to group nubers together whichever consecutive

for example : original list '(1 2 3 6 9 10 11 44 55 56 77) in a list

outpot list  '((1 2 3)(6)(9 10 11)(44)(55 56)(77))

seems to be simple, but have been strugglig for a day or so...

any help will be gratly appreciated

TIA


Recursion

 

(Defun groupbycon (n ls ls_)
  (setq s (apply 'min ls)
        ls_ (cons s ls_)
	ls  (vl-remove s ls)
  )
  (While (member (Setq s (1+ s)) ls)
    (setq ls_ (cons s ls_)
	  ls  (vl-remove s ls)
    )
  )
  (if ls
    (groupbycon (setq n (cons (reverse ls_) n)) ls nil)
    (reverse (cons ls_ n))
  )
)

 

(groupbycon nil '(1 2 3 6 9 10 11 44 55 56 77) nil)


(groupbycon nil '(56 1 2 10 11 3 55 6 9 44 77) nil)

 

((1 2 3) (6) (9 10 11) (44) (55 56) (77)) 

 

HTH

 

 

Distinguished Contributor
phanaem
Posts: 149
Registered: ‎02-06-2007
Message 8 of 9 (226 Views)

Re: grouping numbers

11-21-2012 10:30 PM in reply to: pbejse

Nice one pBe

Here is mine, for non-duplicates list

(defun group_consecutive (l / r)
  (setq r (list (list (apply 'max l))))
  (foreach x (cdr (vl-sort l '>))
    (if
      (= x (1- (caar r)))
      (setq r (cons (cons x (car r)) (cdr r)))
      (setq r (cons (list x) r))
      )
    )
  )

 

*Expert Elite*
pbejse
Posts: 2,406
Registered: ‎11-24-2009
Message 9 of 9 (223 Views)

Re: grouping numbers

11-21-2012 11:02 PM in reply to: phanaem

phanaem wrote:

Nice one pBe

Here is mine, for non-duplicates list

 


 

Clever using MAX and sort phanaem , i like your code 

 

Iteration version of the code  using max

(Defun groupbycon (ls / n)
  (setq s (apply 'max ls))
  (While ls
    (while (member s ls)
      (setq ls_	(cons s ls_)
	    ls	(vl-remove s ls)
	    s	(1- s)
      )
    )
    (setq n   (cons ls_ n)
	  ls_ nil s (apply 'max ls)
    )
  )
  n
)

 

 

 

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community