Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

grouping numbers

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
markruys2
702 Views, 8 Replies

grouping numbers

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

8 REPLIES 8
Message 2 of 9
Kent1Cooper
in reply to: markruys2


@markruys2 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, AIA
Message 3 of 9
markruys2
in reply to: Kent1Cooper

kent,

thanks for the code, compact and simple

have a nice thankgiving

m

Message 4 of 9
Kent1Cooper
in reply to: markruys2


@markruys2 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, AIA
Message 5 of 9
bobdobbs
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)

 

 

 

Message 6 of 9
Kent1Cooper
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, AIA
Message 7 of 9
pbejse
in reply to: markruys2


@markruys2 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

 

 

Message 8 of 9
phanaem
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))
      )
    )
  )

 

Message 9 of 9
pbejse
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
)

 

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost