Author Topic: -={ Challenge }=- Group List by Number  (Read 26870 times)

0 Members and 1 Guest are viewing this topic.

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
-={ Challenge }=- Group List by Number
« on: March 06, 2010, 02:06:36 PM »
The Challenge:

To group a list into sub-lists of a desired length.

Example:

Code: [Select]
(GroupByNum '(1 2 3 4 5 6) 2)

((1 2) (3 4) (5 6))

Code: [Select]
(GroupByNum '(1 2 3 4 5 6) 3)

((1 2 3) (4 5 6))

Have fun!

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: -={ Challenge }=- Group List by Number
« Reply #1 on: March 06, 2010, 02:11:49 PM »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: -={ Challenge }=- Group List by Number
« Reply #2 on: March 06, 2010, 02:12:24 PM »
Ahh... I even did a search first  :-(

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: -={ Challenge }=- Group List by Number
« Reply #3 on: March 06, 2010, 02:15:51 PM »
Oh well, here's my offering anyway...

Code: [Select]
(defun GroupByNum (lst num / rtn) (setq rtn nil) 
  (if lst
    (cons (reverse
            (repeat num
              (progn
                (setq rtn (cons (car lst) rtn) lst (cdr lst)) rtn)))

          (GroupByNum lst num))))
« Last Edit: March 11, 2010, 02:31:22 PM by Lee Mac »

VovKa

  • Water Moccasin
  • Posts: 1626
  • Ukraine
Re: -={ Challenge }=- Group List by Number
« Reply #4 on: March 06, 2010, 06:06:38 PM »
it's past midnight here in Ukraine and can't beat anything better out of my tortured brain
Code: [Select]
(defun GroupByNum (lst num / rslt)
  (if (zerop (car (setq rslt
(if lst
   (if (listp (car (setq rslt (GroupByNum (cdr lst) num))))
     (cons (1- num) (cons (list (car lst)) rslt))
     (cons (1- (car rslt)) (cons (cons (car lst) (cadr rslt)) (cddr rslt)))
   )
   (list num)
)
  )
     )
      )
    (cdr rslt)
    rslt
  )
)

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: -={ Challenge }=- Group List by Number
« Reply #5 on: March 06, 2010, 06:25:59 PM »
Nice one VovKa, that's gonna take me a while to work out....  :oops:

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: -={ Challenge }=- Group List by Number
« Reply #6 on: March 06, 2010, 06:50:55 PM »
That is actually awesome - working from the bottom up... I don't know how you come up with the ideas...!  :lol:

VovKa

  • Water Moccasin
  • Posts: 1626
  • Ukraine
Re: -={ Challenge }=- Group List by Number
« Reply #7 on: March 07, 2010, 03:43:19 AM »
not my idea, actually :(
it's a commonly used way of implementing iteration
another example

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: -={ Challenge }=- Group List by Number
« Reply #8 on: March 07, 2010, 03:49:47 AM »
may boil the brain...  :-D

Code: [Select]
(defun gbn (l n)
 (if l
  (f l nil n n)
 )
)
(defun f (a b n i)
 (if (> n 0)
  (f (cdr a)(cons (car a) b) (1- n) i)
  (cons (reverse b) (gbn a i))
 )
)

test:
Code: [Select]
(gbn '(1 2 3 4 5 6) 1) ;=> '((1) (2) (3) (4) (5) (6))
(gbn '(1 2 3 4 5 6) 2) ;=> '((1 2) (3 4) (5 6))
(gbn '(1 2 3 4 5 6) 3) ;=> '((1 2 3) (4 5 6))
(gbn '(1 2 3 4 5 6) 4) ;=> '((1 2 3 4) (5 6 nil nil))

wizman

  • Bull Frog
  • Posts: 290
Re: -={ Challenge }=- Group List by Number
« Reply #9 on: March 07, 2010, 04:54:31 AM »
Vovka, Lee this gives odd result:

(groupbynum '(1 2 3 4 5 6 7 8 9 10) 3)

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: -={ Challenge }=- Group List by Number
« Reply #10 on: March 07, 2010, 06:36:09 AM »
Very nice Evgeniy!

Bouncing between the two functions for each group!  :lol:

VovKa

  • Water Moccasin
  • Posts: 1626
  • Ukraine
Re: -={ Challenge }=- Group List by Number
« Reply #11 on: March 07, 2010, 09:01:55 AM »
Vovka, Lee this gives odd result:

(groupbynum '(1 2 3 4 5 6 7 8 9 10) 3)

yep, function ends in an unfinished state :(

Evgeniy, mine is boiling :)

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: -={ Challenge }=- Group List by Number
« Reply #12 on: March 07, 2010, 09:15:55 AM »
Not only more concise and smarter, but also faster too:  :evil:

Code: [Select]
(BenchMark '((gbn '(1 2 3 4 5 6) 3) (GroupByNum '(1 2 3 4 5 6) 3) (GroupByNum_vk '(1 2 3 4 5 6) 3)))
Benchmarking ..................Elapsed milliseconds / relative speed for 32768 iteration(s):

    (GBN (QUOTE (1 2 3 4 5 6)) 3)...............1217 / 1.12 <fastest>
    (GROUPBYNUM (QUOTE (1 2 3 4 5 6)) 3)........1264 / 1.07
    (GROUPBYNUM_VK (QUOTE (1 2 3 4 5 6)) 3).....1357 / 1.00 <slowest>
« Last Edit: March 07, 2010, 09:25:11 AM by Lee Mac »

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: -={ Challenge }=- Group List by Number
« Reply #13 on: March 07, 2010, 09:20:17 AM »
Simpler, but perhaps faster:

Code: [Select]
(defun GroupByNum_Mac2 (l n / a b)
  (while l
    (repeat n
      (setq a (cons (car l) a) l (cdr l)))
    (setq b (cons (reverse a) b) a nil))
  (reverse b))

Code: [Select]
(defun GroupByNum_Mac3 (l n / a b i)
  (while l (setq i n)
    (while (< 0 i)
      (setq a (cons (car l) a) l (cdr l) i (1- i)))
    (setq b (cons (reverse a) b) a nil))
  (reverse b))
« Last Edit: March 07, 2010, 09:29:06 AM by Lee Mac »

kraz

  • Guest
Re: -={ Challenge }=- Group List by Number
« Reply #14 on: March 10, 2010, 08:22:59 PM »
(defun list_grouping(lst numb / glist tlist c)
 (if (listp lst)
  (progn
   (setq glist '() tlist '() c 1)
   (foreach e lst
    (if (eq (rem c numb) 0)
     (setq glist (append glist (list (append tlist (list e)))) tlist '())
     (setq tlist (append tlist (list e)))
    )
    (setq c (1+ c))
   )
   (if (> (length tlist) 0)
    (append glist (list tlist))
     glist
   );if
  )
  nil
 )
)

;;;;;;;;;;;;;;;;;
(list_grouping '(1 2 3 4 5 6 7 8 9 10) 3) -> ((1 2 3) (4 5 6) (7 8 9) (10))

hmm...i thought '(1 2 3 4 5 6 7 8 9 10) 3) -> ((1 2 3) (4 5 6) (7 8 9) (10 nil nil)) is not true...so....hehe