TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: snownut2 on December 28, 2013, 08:44:09 AM

Title: List Functions
Post by: snownut2 on December 28, 2013, 08:44:09 AM
Time for some additional basic List Functions;
       ListSum = Sum of all numbers in a numbered list
       ListMax = Largest number contained in a numbered list
       ListMin  = Smallest "                                                      "

I'm sure there are tons more !!
Title: Re: List Functions
Post by: ribarm on December 28, 2013, 10:06:30 AM
Code - Auto/Visual Lisp: [Select]
  1. (defun ListSum ( lst / x xx )
  2.   (setq xx 0)
  3.   (while lst
  4.     (setq x (car lst))
  5.     (setq xx (+ x xx))
  6.     (setq lst (cdr lst))
  7.   )
  8.   xx
  9. )
  10.  
  11. (defun ListMax ( lst / x xx )
  12.   (while lst
  13.     (setq x (car lst))
  14.     (setq xx (cond (xx) ((cadr lst))))
  15.     (setq xx (max x xx))
  16.     (setq lst (cdr lst))
  17.   )
  18.   xx
  19. )
  20.  
  21. (defun ListMin ( lst / x xx )
  22.   (while lst
  23.     (setq x (car lst))
  24.     (setq xx (cond (xx) ((cadr lst))))
  25.     (setq xx (min x xx))
  26.     (setq lst (cdr lst))
  27.   )
  28.   xx
  29. )
  30.  
Title: Re: List Functions
Post by: CAB on December 28, 2013, 10:11:55 AM
Code: [Select]
(defun ListSum ( lst)
 (apply '+ lst)
)
 
(defun ListMax ( lst / x xx )
 (apply 'max lst)
)
 
(defun ListMin ( lst / x xx )
 (apply 'min lst)
)
Title: Re: List Functions
Post by: snownut2 on December 28, 2013, 10:15:21 AM
Code: [Select]
(defun ListSum ( lst)
 (apply '+ lst)
)
 
(defun ListMax ( lst / x xx )
 (apply 'max lst)
)
 
(defun ListMin ( lst / x xx )
 (apply 'min lst)
)

Thanks CAB, I'm not that familiar with the apply function.  This is a good example though.

Bruce
Title: Re: List Functions
Post by: Tharwat on December 28, 2013, 10:17:20 AM
CAB , you have localized variables that are not needed .
Title: Re: List Functions
Post by: Lee Mac on December 28, 2013, 10:22:20 AM
I'm not that familiar with the apply function.

If you have an aversion to the apply function:
Code - Auto/Visual Lisp: [Select]
  1. (defun listsum ( l ) (eval (cons '+ l)))
  2. (defun listmin ( l ) (eval (cons 'min l)))
  3. (defun listmax ( l ) (eval (cons 'max l)))
Title: Re: List Functions
Post by: Lee Mac on December 28, 2013, 10:35:51 AM
Or, if you wanted to iterate over the lists...
Code - Auto/Visual Lisp: [Select]
  1. (defun listsum ( l / r )
  2.     (setq r 0)
  3.     (foreach x l (setq r (+ x r)))
  4.     r
  5. )
  6. (defun listmin ( l / r )
  7.     (setq r (car l))
  8.     (foreach x (cdr l) (setq r (min r x)))
  9.     r
  10. )
  11. (defun listmax ( l / r )
  12.     (setq r (car l))
  13.     (foreach x (cdr l) (setq r (max r x)))
  14.     r
  15. )
Title: Re: List Functions
Post by: CAB on December 28, 2013, 12:32:57 PM
CAB , you have localized variables that are not needed .
Yes, I was being lazy, copy & paste from previous post.
Title: Re: List Functions
Post by: snownut2 on December 28, 2013, 06:54:22 PM
Lee, for the "SUM" result your last post is exactly how I had accomplished it, for the MIN/MAX I had sorted the list </> then selected the 1st element.  I was not real keen on the sort idea.

Thanks guys for the quick response's

Bruce
Title: Re: List Functions
Post by: Lee Mac on December 28, 2013, 07:07:16 PM
I was not real keen on the sort idea.

Yes - sorting all items in the list is very inefficient if you are only interested in the min/max  ;-)
Title: Re: List Functions
Post by: David Bethel on December 29, 2013, 08:51:32 AM
Maybe flush out the functions :

Code: [Select]
;;;Product of a list
  (defun ListProd (l)
    (apply '* l))

;;;Mean or Average of a list
  (defun ListAvg (l)
    (/ (apply '+ l) (float (length l))))

;;;Median of a SORTED list
  (defun ListMed (l / c)
    (setq c (length l))
    (if (= (rem c 2) 1)
        (nth (fix (/ c 2.0)) l)
        (/ (+ (nth (1- (fix (/ c 2.0))) l)
              (nth (fix (/ c 2.0)) l))
           2.0)))

;;;Range of a list
  (defun ListRng (l / c)
    (- (apply 'max l)
       (apply 'min l)))

;;;Mode of a list
  (defun ListMode (l / c r x m)
    (setq c nil)
    (foreach a l
      (setq c (if (assoc a c)
                  (subst (list a (1+ (cadr (assoc a c))))
                         (assoc a c) c)
                  (cons (list a 1) c))))
    (setq r (mapcar ' reverse c)
          x (apply 'max (mapcar 'car r)))
    (cond ((= x 1) (setq m "None"))
          (T
           (foreach a r
             (if (= (car a) x)
                 (setq m (cons (cadr a) m))))))
    m)


Prime Factors & Least Common Multiple would be cool

-David
Title: Re: List Functions
Post by: Lee Mac on December 29, 2013, 10:25:16 AM
Another for mode:

http://www.theswamp.org/index.php?topic=45195.msg503882#msg503882
Title: Re: List Functions
Post by: Lee Mac on December 29, 2013, 10:46:37 AM
Least Common Multiple would be cool

A possible candidate for LCM:
Code - Auto/Visual Lisp: [Select]
  1. (defun lcm ( l / f )
  2.     (defun f ( a b / m )
  3.         (if (apply '= a)
  4.             (car a)
  5.             (progn
  6.                 (setq m (apply 'min a))
  7.                 (f (mapcar '(lambda ( a b ) (if (= a m) (+ a b) a)) a b) b)
  8.             )
  9.         )
  10.     )
  11.     (f l l)
  12. )
Code - Auto/Visual Lisp: [Select]
  1. _$ (lcm '(22 16 31))
  2. 5456
Title: Re: List Functions
Post by: Lee Mac on December 29, 2013, 11:03:58 AM
Another:
Code - Auto/Visual Lisp: [Select]
  1. (defun lcm ( l )
  2.     (/ (apply '* l) (apply '* (mapcar 'gcd l (cdr l))))
  3. )
Title: Re: List Functions
Post by: David Bethel on December 29, 2013, 11:11:26 AM
Another:
Code - Auto/Visual Lisp: [Select]
  1. (defun lcm ( l )
  2.     (/ (apply '* l) (apply '* (mapcar 'gcd l (cdr l))))
  3. )

That'a a good 1 !


PS

On second look, I don't think this 1 works
Code: [Select]
  (setq lst '(2 5 5 5 6 7 10 10 10 12))
  (lcm lst)
  25200
Title: Re: List Functions
Post by: Lee Mac on December 29, 2013, 11:22:10 AM
That'a a good 1 !

Thanks David  :-)

This version might be more efficient:
Code - Auto/Visual Lisp: [Select]
  1. (defun lcm ( l )
  2.     (if (cdr l)
  3.         (* (/ (car l) (gcd (car l) (cadr l))) (lcm (cdr l)))
  4.         (car l)
  5.     )
  6. )
Title: Re: List Functions
Post by: Lee Mac on December 29, 2013, 11:52:26 AM
On second look, I don't think this 1 works
Code: [Select]
  (setq lst '(2 5 5 5 6 7 10 10 10 12))
  (lcm lst)
  25200

Back to the drawing board on that one :-(
Title: Re: List Functions
Post by: David Bethel on December 29, 2013, 12:02:12 PM
I tried removing the duplicate atoms to no avail.  -David
Title: Re: List Functions
Post by: Lee Mac on December 29, 2013, 12:20:30 PM
New method:
Code - Auto/Visual Lisp: [Select]
  1. (defun lcm ( l )
  2.     (if (cddr l)
  3.         (lcm (list (car l) (lcm (cdr l))))
  4.         (/ (apply '* l) (apply 'gcd l))
  5.     )
  6. )
Title: Re: List Functions
Post by: Lee Mac on December 29, 2013, 12:24:51 PM
Or perhaps more efficiently:
Code - Auto/Visual Lisp: [Select]
  1. (defun lcml ( l )
  2.     (if (cddr l)
  3.         (lcm (car l) (lcml (cdr l)))
  4.         (apply 'lcm l)
  5.     )
  6. )
  7. (defun lcm ( a b ) (* b (/ a (gcd a b))))
Code - Auto/Visual Lisp: [Select]
  1. _$ (lcml '(2 5 5 5 6 7 10 10 10 12))
  2. 420
Title: Re: List Functions
Post by: Lee Mac on December 29, 2013, 12:30:45 PM
And an iterative version:
Code - Auto/Visual Lisp: [Select]
  1. (defun lcml ( l / r )
  2.     (setq r (lcm (car l) (cadr l)))
  3.     (foreach x (cddr  l) (setq r (lcm r x)))
  4.     r
  5. )
  6. (defun lcm ( a b ) (* b (/ a (gcd a b))))
Title: Re: List Functions
Post by: gile on December 29, 2013, 06:13:09 PM
Hi,

Inspired by the F# List.reduce function (http://msdn.microsoft.com/en-us/library/ee370239.aspx).

F# doesn't have an OOTB 'gcd' function, but it's easy to implement.

Code - F#: [Select]
  1. let rec gcd x y = if y = 0 then x else gcd y (x % y)
  2.    
  3. let lcm = List.reduce(fun a b -> a * b / gcd a b)

With AutoLISP, using a reusable 'gc:reduce' function:

Code - Auto/Visual Lisp: [Select]
  1. ;; gc:reduce
  2. ;; (gc:reduce 'f '(i0 i1 i2 ... in)) computes: (f ... (f (f i0 i1) i2) ... in)
  3. (defun gc:reduce (fun lst)
  4.   (setq fun (eval fun))
  5.   (while (cdr lst)
  6.     (setq lst (cons (fun (car lst) (cadr lst)) (cddr lst)))
  7.   )
  8.   (car lst)
  9. )
  10.  
  11. (defun lcm (lst) (gc:reduce '(lambda (a b) (/ (* a b) (gcd a b))) lst))

You can find some others List Functions here (http://gilecad.azurewebsites.net/LISP/gc_List.lsp) (sorry for the french comments)
Title: Re: List Functions
Post by: Lee Mac on December 29, 2013, 07:09:31 PM
Prime Factors would be cool

Not quite as easy:

Code - Auto/Visual Lisp: [Select]
  1. (defun pf ( n / c i p r )
  2.     (setq p 2)
  3.     (while (< 1 n)
  4.         (if (< 0 (rem n p))
  5.             (progn
  6.                 (setq c (fix (1+ (sqrt n)))
  7.                       i 3
  8.                       p n
  9.                 )
  10.                 (while (< i c)
  11.                     (if (zerop (rem n i))
  12.                         (setq p i
  13.                               i c
  14.                         )
  15.                     )
  16.                     (setq i (+ i 2))
  17.                 )
  18.             )
  19.         )
  20.         (setq r (cons p r)
  21.               n (/ n p)
  22.         )
  23.     )
  24.     (reverse r)
  25. )

Or, recursively:
Code - Auto/Visual Lisp: [Select]
  1. (defun pf ( n / f )
  2.     (defun f ( n p / c i )
  3.         (if (< 1 n)
  4.             (if (zerop (rem n p))
  5.                 (cons p (f (/ n p) p))
  6.                 (progn
  7.                     (setq c (fix (1+ (sqrt n)))
  8.                           i 3
  9.                           p n
  10.                     )
  11.                     (while (< i c)
  12.                         (if (zerop (rem n i))
  13.                             (setq p i
  14.                                   i c
  15.                             )
  16.                         )
  17.                         (setq i (+ i 2))
  18.                     )
  19.                     (cons p (f (/ n p) p))
  20.                 )
  21.             )
  22.         )
  23.     )
  24.     (f n 2)
  25. )

Code - Auto/Visual Lisp: [Select]
  1. _$ (pf 360315)
  2. (3 3 3 5 17 157)
Title: Re: List Functions
Post by: gile on December 30, 2013, 06:24:01 AM
A more efficient implementation of gc:reduce (I forgot I posted this (http://www.theswamp.org/index.php?topic=37362.msg423677#msg423677))

Code - Auto/Visual Lisp: [Select]
  1. ;; gc:reduce
  2. ;; (gc:reduce 'f '(i0 i1 i2 ... in)) computes: (f ... (f (f i0 i1) i2) ... in)
  3. (defun gc:reduce (fun lst / acc)
  4.   (setq fun (eval fun)
  5.         acc (car lst)
  6.   )
  7.   (foreach n (cdr lst) (setq acc (fun acc n)))
  8. )
Title: Re: List Functions
Post by: Lee Mac on December 30, 2013, 06:31:43 AM
Look back at our prime factorisation thread (http://www.theswamp.org/index.php?topic=42965.0), this would be more efficient:

Code - Auto/Visual Lisp: [Select]
  1. (defun pf ( n / m p r )
  2.     (setq p 2)
  3.     (while (< 1 n)
  4.         (while (zerop (rem n p))
  5.             (setq r (cons p r)
  6.                   n (/ n p)
  7.             )
  8.         )
  9.         (if (< 1 (setq m (sqrt n)) (setq p (if (= p 2) 3 (+ 2 p))))
  10.             (setq r (cons n r)
  11.                   n 0
  12.             )
  13.             (while (and (<= p m) (< 0 (rem n p)))
  14.                 (setq p (+ 2 p))
  15.             )
  16.         )
  17.     )
  18.     (reverse r)
  19. )
Title: Re: List Functions
Post by: David Bethel on December 30, 2013, 09:01:21 AM
Maybe like thus ?

Least Common Multiple - Product of the prime factors


using Lee's pf prime_factor's:

Code: [Select]
(defun pf ( n / m p r ) ; LeeMac
  (setq p 2)
  (while (< 1 n)
         (while (zerop (rem n p))
                (setq r (cons p r)
                      n (/ n p)))
         (if (< 1 (setq m (sqrt n))
                  (setq p (if (= p 2) 3 (+ 2 p))))
             (setq r (cons n r)
                   n 0)
             (while (and (<= p m)
                         (< 0 (rem n p)))
                    (setq p (+ 2 p)))))
  (reverse r))

(defun ListLCM (l / pl fl)
  (foreach a l
    (setq pl (pf a))
    (foreach f pl
       (if (not (member f fl))
           (setq fl (cons f fl)))))
  (apply '* fl))


-David
Title: Re: List Functions
Post by: Lee Mac on December 30, 2013, 09:19:20 AM
Maybe like thus ?

Least Common Multiple - Product of the prime factors

I could be wrong, but I thought:

LCM = product of distinct prime factors with the highest powers

So the function may need to be something like:
Code: [Select]
(defun listlcm ( l / a n p r x )
    (while l
        (setq x (car l)
              l (vl-remove x (cdr l))
              p (pf x)
        )
        (while p
            (setq x (car p)
                  n (length p)
                  p (vl-remove x (cdr p))
                  n (- n (length p))
                  a (assoc x r)
            )
            (if a
                (if (< (cadr a) n)
                    (setq r (subst (list x n) a r))
                )
                (setq r (cons (list x n) r))
            )
        )
    )
    (apply '* (mapcar '(lambda ( x ) (apply 'expt x)) r))
)
Code: [Select]
_$ (listlcm '(2 5 5 5 6 7 10 10 10 12))
420
Title: Re: List Functions
Post by: roy_043 on December 30, 2013, 10:08:19 AM
Are negative integers allowed in the input list for the LCM function?
Code: [Select]
(listlcm '(-24  18  10)) =>  90
(listlcm '( 24 -18  10)) => 120
(listlcm '( 24  18 -10)) =>  72
(listlcm '(-24 -18  10)) =>  10
(listlcm '(-24  18 -10)) =>  18
(listlcm '( 24 -18 -10)) =>  24
(listlcm '(-24 -18 -10)) =>   0
Title: Re: List Functions
Post by: David Bethel on December 30, 2013, 10:22:37 AM
http://en.wikipedia.org/wiki/Least_common_multiple (http://en.wikipedia.org/wiki/Least_common_multiple)

Quote
The LCM of more than two integers is also well-defined: it is the smallest integer that is divisible by each of them

Looks like mine is it working properly.........  -David
Title: Re: List Functions
Post by: Lee Mac on December 30, 2013, 10:37:41 AM
http://en.wikipedia.org/wiki/Least_common_multiple (http://en.wikipedia.org/wiki/Least_common_multiple)

Quote
The LCM of more than two integers is also well-defined: it is the smallest integer that is divisible by each of them

Looks like mine is it working properly.........  -David

Testing yours:
Code - Auto/Visual Lisp: [Select]
  1. _$ (ListLCM '(2 5 5 5 6 7 10 10 10 12))
  2. 210
  3. _$ (/ 210 12.)
  4. 17.5
Correct LCM is 420 (http://www.wolframalpha.com/input/?i=lcm%282+5+5+5+6+7+10+10+10+12%29)
Title: Re: List Functions
Post by: David Bethel on December 30, 2013, 12:27:35 PM
I meant to say NOT working properly.  Sorry.  -David
Title: Re: List Functions
Post by: Lee Mac on December 30, 2013, 01:17:05 PM
I meant to say NOT working properly.  Sorry.  -David

No worries!  :-)
Title: Re: List Functions
Post by: edata on December 31, 2013, 10:19:52 AM
About "eval" .if (length > 255),An error will occur. :-)
Title: Re: List Functions
Post by: snownut2 on December 31, 2013, 01:34:18 PM
to Mark or other Mod.  any way to create a reference section, where threads like this one can be posted, due to its large amount of "reference material" maybe to help limit the amount of future duplicate type threads. Maybe not allow anyone to post new threads but moved there by moderators when a good reference thread is developed.  I am not saying lock the actual threads themselves, but to only have good reference threads there. 

There are many such threads and searching for them sometimes becomes a challenge if the searcher does not use the exact right search words.

Bruce