TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: David Bethel on March 31, 2017, 09:01:54 AM

Title: Auditing a list of numerical string atoms
Post by: David Bethel on March 31, 2017, 09:01:54 AM
Good morning,

Dealing with items number bubble identifiers

I'm looking to audit a list of string values that :



Code: [Select]
(setq nl '("12" "13" "14" "1" "3" "4" "6" "7" "2" "8" "9" "10" "16" "17" "18" "22" "24" "26" "27" "20" "21" "19" "23" "15" "29" "34" "35" "36" "37" "29" "31" "32" "33" "30" "38" "39" "40" "41" "42" "43" "49" "44" "45" "46" "47" "48" "50" "50" "48" "5" "25" "28"))

I am looking to report :

*** ( In Plain AutoLisp )

So far :
Code - Auto/Visual Lisp: [Select]
  1. (defun anum (nl / il minn maxn i ml dl)
  2.  
  3. (setq il (mapcar 'atoi nl)
  4.     minn (apply 'min il)
  5.     maxn (apply 'max il)
  6.        i minn)
  7.  
  8. (while (<= i maxn)
  9.        (cond ((not (member i il))
  10.               (setq ml (cons i ml)))
  11.              ((and (member i (cdr (member i il)))
  12.                    (not (member i dl)))
  13.               (setq dl (cons i dl))))
  14.        (setq i (1+ i)))
  15.  
  16. (princ "\nDuplicates : ")
  17. (prin1 dl)
  18. (princ "\nMissing : ")
  19. (prin1 ml)
  20.  

(member (member))  is a horrible test
I don't think (atoi) will return an error that can be captured

 Any suggestions to make this more robust ?

TIA  -David
Title: Re: Auditing a list of numerical string atoms
Post by: Grrr1337 on March 31, 2017, 09:51:03 AM
Hi David,

For the first report task:
Code - Auto/Visual Lisp: [Select]
  1. _$ (mapcar
  2.   '(lambda (x / n) (setq n (read x)) (or (minusp n) (eq 'REAL (type n))))
  3.   '("1.1" "2" "3" "4" "5.6" "-6")
  4. )
  5. (T nil nil nil T T)
  6. _$

For the second report task:
Use these:
Code - Auto/Visual Lisp: [Select]
  1. (defun FindDifference ( nl / n L )
  2.   (setq n 0)
  3.   (repeat (fix (apply 'max (mapcar 'read nl)))
  4.     (setq L (cons (itoa (setq n (1+ n))) L))
  5.   )
  6.   ; Start comparing:
  7.   (LM:ListDifference
  8.     (setq L (acad_strlsort L))
  9.     (setq nl (acad_strlsort nl))
  10.   )
  11. ); defun FindDifference
  12.  
  13. ;; List Duplicates  -  Lee Mac
  14. ;; Returns a list of items appearing more than once in a supplied list
  15.  
  16. (defun LM:ListDupes ( l )
  17.   (if l
  18.     (if (member (car l) (cdr l))
  19.       (cons (car l) (LM:ListDupes (vl-remove (car l) (cdr l))))
  20.       (LM:ListDupes (vl-remove (car l) (cdr l)))
  21.     )
  22.   )
  23. )
  24.  
  25. ;;-------------------=={ List Difference }==------------------;;
  26. ;;                                                            ;;
  27. ;;  Returns items appearing exclusively in one list but not   ;;
  28. ;;  another, i.e. the relative complement: l1 \ l2            ;;
  29. ;;------------------------------------------------------------;;
  30. ;;  Author: Lee Mac, Copyright © 2011 - www.lee-mac.com       ;;
  31. ;;------------------------------------------------------------;;
  32. ;;  Arguments:                                                ;;
  33. ;;  l1,l2 - lists for which to return the difference          ;;
  34. ;;------------------------------------------------------------;;
  35. ;;  Returns:  List of items appearing exclusively in list l1  ;;
  36. ;;------------------------------------------------------------;;
  37.  
  38. (defun LM:ListDifference ( l1 l2 )
  39.   (if l1
  40.     (if (member (car l1) l2)
  41.       (LM:ListDifference (cdr l1) l2)
  42.       (cons (car l1) (LM:ListDifference (cdr l1) l2))
  43.     )
  44.   )
  45. )

Result:
Code - Auto/Visual Lisp: [Select]
  1. (setq nl
  2.   '("12" "13" "14" "1" "3" "4" "6" "7" "2" "8" "9" "10"
  3.     "16" "17" "18" "22" "24" "26" "27" "20" "21" "19" "23"
  4.     "15" "29" "34" "35" "36" "37" "29" "31" "32" "33" "30"
  5.     "38" "39" "40" "41" "42" "43" "49" "44" "45" "46" "47"
  6.     "48" "50" "50" "48" "5" "25" "28"
  7.   )
  8. )
  9. _$ (FindDifference nl)
  10. ("11") ; this means that eleven is missing
  11. _$ (LM:ListDupes nl)
  12. ("29" "48" "50") ; these occur more than once
  13. _$
Title: Re: Auditing a list of numerical string atoms
Post by: David Bethel on March 31, 2017, 10:13:56 AM
Thanks Grrr

I'll take  look, but I don't have access to any vl-  type calls, only plain autolisp.

-David
Title: Re: Auditing a list of numerical string atoms
Post by: Grrr1337 on March 31, 2017, 10:46:30 AM
Oops, sorry David!
I did not notice that LM:ListDupes uses (vl-remove) - my other thought is to create unique item counter, which should do something like:
Code: [Select]
'("A" "B" "C" "D" "D" "A") -> '(("A" . 2) ("B" . 1) ("C" . 1) ("D" . 2))And by that way the duplicates can be found.
Title: Re: Auditing a list of numerical string atoms
Post by: roy_043 on March 31, 2017, 10:51:30 AM
To check for 'pos. int string':
Code: [Select]
(wcmatch str "~*[~0-9]*")
You should do this before using atoi as that function will always return an integer.
Title: Re: Auditing a list of numerical string atoms
Post by: CAB on March 31, 2017, 12:15:03 PM
A different approach, return numbers though
Code: [Select]
(defun anum (lst / lastitm neg missing)
  (foreach itm (vl-sort (mapcar 'atoi lst) '>)
    (cond
      ((minusp itm) (setq neg (cons itm neg)))
      ((null lastitm) (setq lastitm itm))
      (t (if (/= (1- lastitm) itm)
           (progn (while (/= (1- lastitm) itm)
             (setq missing (cons (1- lastitm) missing)
                 lastitm (1- lastitm)))(setq lastitm (1- lastitm)))
           (setq lastitm itm)
         )
       )
    )
  )
  (list neg missing)
)
Title: Re: Auditing a list of numerical string atoms
Post by: David Bethel on March 31, 2017, 01:16:02 PM
A different approach, return numbers though

That is a bit different.  I'll have to dig into it.  I do roll your own sort routines so that's not a problem

Thanks All !  -David
Title: Re: Auditing a list of numerical string atoms
Post by: Lee Mac on March 31, 2017, 01:29:44 PM
This avoids the (member (member)), but it's not particularly pretty:

Code - Auto/Visual Lisp: [Select]
  1. (defun checklist ( lst / dun dup int inv mim mis mxm )
  2.     (foreach itm lst
  3.         (if (wcmatch itm "*[~0-9]*")
  4.             (or (member itm inv) (setq inv (cons itm inv)))
  5.             (setq int (cons itm int))
  6.         )
  7.     )
  8.     (setq int (mapcar 'atoi int)
  9.           mxm (apply  'max  int)
  10.           mim (apply  'min  int)
  11.     )
  12.     (foreach itm int
  13.         (and (<= mim mxm)
  14.              (or (member mxm int)
  15.                  (setq mis (cons (itoa mxm) mis))
  16.              )
  17.              (setq mxm (1- mxm))
  18.         )
  19.         (or (and (member itm dun)
  20.                  (or (member (itoa itm) dup)
  21.                      (setq dup (cons (itoa itm) dup))
  22.                  )
  23.             )
  24.             (setq dun (cons itm dun))
  25.         )
  26.     )
  27.     (while (<= mim mxm)
  28.         (or (member mxm int)
  29.             (setq mis (cons (itoa mxm) mis))
  30.         )
  31.         (setq mxm (1- mxm))
  32.     )
  33.     (princ "\nInvalid items: ")
  34.     (prin1 inv)
  35.     (princ "\nMissing items: ")
  36.     (prin1 mis)
  37.     (princ "\nDuplicate items: ")
  38.     (prin1 dup)
  39.     (princ)
  40. )
Title: Re: Auditing a list of numerical string atoms
Post by: David Bethel on March 31, 2017, 01:54:35 PM
I was heading towards adding a bad list also.

The list is normally less than 100 atoms so I guess (member) testing is not all that bad.

It does seem that there should be a simple solution.  But here accuracy is going to rule.  Thanks!  _David
Title: Re: Auditing a list of numerical string atoms
Post by: ronjonp on March 31, 2017, 03:10:13 PM
..
The list is normally less than 100 atoms so I guess (member) testing is not all that bad.
..
You don't need to worry about performance then .. go for your own readability :)
Title: Re: Auditing a list of numerical string atoms
Post by: CAB on March 31, 2017, 04:03:01 PM
Had a few minutes to make another run at this one with Gile's Sort

Code - Auto/Visual Lisp: [Select]
  1. ;;;=============================================================
  2. ;;;Gile's Insert Sort                                          
  3. ;;;=============================================================
  4. (defun G:InsertSort (lst / insert)
  5.  
  6.   (defun insert    (ele lst)
  7.     (cond
  8.       ((null lst) (list ele))
  9.       ((> ele (car lst)) (cons ele lst))
  10.       ((cons (car lst) (insert ele (cdr lst))))
  11.     )
  12.   )
  13.  
  14.   (if lst
  15.     (insert (car lst) (G:InsertSort (cdr lst)))
  16.   )
  17. )
  18.  
  19.  
  20.  
  21. (defun anum (lst / lastitm neg missing doup)
  22.   (foreach itm (G:InsertSort (mapcar 'atoi lst))
  23.     (cond
  24.       ((minusp itm) (setq neg (cons itm neg)))
  25.       ((null lastitm) (setq lastitm itm))
  26.       ((= lastitm itm) ; douplicates
  27.            (setq doup (cons lastitm doup)
  28.                  lastitm itm)
  29.        )
  30.       ((if (/= (1- lastitm) itm) ; missing from list
  31.            (progn (while (/= (1- lastitm) itm)
  32.              (setq missing (cons (1- lastitm) missing)
  33.                  lastitm (1- lastitm)))(setq lastitm (1- lastitm)))
  34.            (setq lastitm itm)
  35.          )
  36.        )
  37.     )
  38.   )
  39.   (list neg missing doup)
  40. )
Title: Re: Auditing a list of numerical string atoms
Post by: Lee Mac on March 31, 2017, 07:17:35 PM
I like your method Alan - here is another variation, using the same process:
Code - Auto/Visual Lisp: [Select]
  1. (defun checklist ( l / d i m r )
  2.     (foreach x l
  3.         (if (wcmatch x "*[~0-9]*")
  4.             (or (member x i) (setq i (cons x i)))
  5.             (setq r (cons (atoi x) r))
  6.         )
  7.     )
  8.     (mapcar
  9.        '(lambda ( a b )
  10.             (cond
  11.                 (   (= a b) (or (member (itoa a) d) (setq d (cons (itoa a) d))))
  12.                 (   (< 1 (- b a))
  13.                     (while (< (setq a (1+ a)) b) (setq m (cons (itoa a) m)))
  14.                 )
  15.             )
  16.         )
  17.         (setq r (qs r)) (cdr r)
  18.     )
  19.     (princ "\nInvalid items: ")
  20.     (prin1 i)
  21.     (princ "\nMissing items: ")
  22.     (prin1 m)
  23.     (princ "\nDuplicate items: ")
  24.     (prin1 d)
  25.     (princ)
  26. )
  27. (defun qs ( l )
  28.     (   (lambda ( f ) (if l (f (car l) (cdr l))))
  29.         (lambda ( x l / a b )
  30.             (foreach y l
  31.                 (if (< y x)
  32.                     (setq a (cons y a))
  33.                     (setq b (cons y b))
  34.                 )
  35.             )
  36.             (append (qs a) (cons x (qs b)))
  37.         )
  38.     )
  39. )
Title: Re: Auditing a list of numerical string atoms
Post by: David Bethel on April 01, 2017, 06:38:04 AM
Code: [Select]
(defun qs ( l )
    (   (lambda ( f ) (if l (f (car l) (cdr l))))
        (lambda ( x l / a b )
            (foreach y l
                (if (< y x)
                    (setq a (cons y a))
                    (setq b (cons y b))
                )
            )
            (append (qs a) (cons x (qs b)))
        )
    )
)

I must admit, that is 1 of the simplest sorting functions I've seen.  Nice

Thanks!  -David
Title: Re: Auditing a list of numerical string atoms
Post by: Lee Mac on April 01, 2017, 07:23:51 AM
Thanks David!  :-)
Title: Re: Auditing a list of numerical string atoms
Post by: CAB on April 01, 2017, 08:28:47 AM
Nice job Lee  8)
Title: Re: Auditing a list of numerical string atoms
Post by: Lee Mac on April 01, 2017, 08:50:26 AM
Nice job Lee  8)

Thanks Alan - you too  :-)
Title: Re: Auditing a list of numerical string atoms
Post by: roy_043 on April 01, 2017, 11:14:22 AM
Another:
Code - Auto/Visual Lisp: [Select]
  1. (defun AuditList (lst / doneLst dubLst i invLst misLst)
  2.   (foreach itm lst
  3.     (cond
  4.       ((wcmatch itm "*[~0-9]*")
  5.         (if (not (member itm invLst)) (setq invLst (cons itm invLst)))
  6.       )
  7.       ((member (setq itm (atoi itm)) doneLst)
  8.         (if (not (member itm dubLst)) (setq dubLst (cons itm dubLst)))
  9.       )
  10.       (T
  11.         (setq doneLst (cons itm doneLst))
  12.       )
  13.     )
  14.   )
  15.   (repeat (- (apply 'max doneLst) (setq i (apply 'min doneLst)) 1)
  16.     (if (not (member (setq i (1+ i)) doneLst))
  17.       (setq misLst (cons i misLst))
  18.     )
  19.   )
  20.   (list
  21.     invLst ; Invalid.
  22.     dubLst ; Duplicate.
  23.     misLst ; Missing.
  24.   )
  25. )
Title: Re: Auditing a list of numerical string atoms
Post by: Grrr1337 on April 01, 2017, 02:01:55 PM
Code - Auto/Visual Lisp: [Select]
  1. (defun qs ( l )
  2.     (   (lambda ( f ) (if l (f (car l) (cdr l))))
  3.         (lambda ( x l / a b )
  4.             (foreach y l
  5.                 (if (< y x)
  6.                     (setq a (cons y a))
  7.                     (setq b (cons y b))
  8.                 )
  9.             )
  10.             (append (qs a) (cons x (qs b)))
  11.         )
  12.     )
  13. )

The idea of this is to function as acad_strlsort ?
Just asking because the foreach and the recursion part confuses me.  :thinking:
Title: Re: Auditing a list of numerical string atoms
Post by: Lee Mac on April 01, 2017, 02:16:34 PM
Code - Auto/Visual Lisp: [Select]
  1. (defun qs ( l )
  2.     (   (lambda ( f ) (if l (f (car l) (cdr l))))
  3.         (lambda ( x l / a b )
  4.             (foreach y l
  5.                 (if (< y x)
  6.                     (setq a (cons y a))
  7.                     (setq b (cons y b))
  8.                 )
  9.             )
  10.             (append (qs a) (cons x (qs b)))
  11.         )
  12.     )
  13. )

The idea of this is to function as acad_strlsort ?
Just asking because the foreach and the recursion part confuses me.  :thinking:

It's an implementation of the Quicksort algorithm (i.e. a Vanilla equivalent to vl-sort), with the first item of the list selected as the pivot.

The function may be easily modified to accept an arbitrary comparison function, e.g.:
Code - Auto/Visual Lisp: [Select]
  1. (defun qs ( l c )
  2.     (   (lambda ( f ) (if l (f c (car l) (cdr l))))
  3.         (lambda ( c x l / a b )
  4.             (foreach y l
  5.                 (if (apply c (list y x))
  6.                     (setq a (cons y a))
  7.                     (setq b (cons y b))
  8.                 )
  9.             )
  10.             (append (qs a c) (cons x (qs b c)))
  11.         )
  12.     )
  13. )
Code - Auto/Visual Lisp: [Select]
  1. _$ (qs '(5 6 2 4 1 7 3 8) '<)
  2. (1 2 3 4 5 6 7 8)
  3. _$ (qs '(5 6 2 4 1 7 3 8) '>)
  4. (8 7 6 5 4 3 2 1)
Title: Re: Auditing a list of numerical string atoms
Post by: Grrr1337 on April 01, 2017, 02:32:33 PM
It's an implementation of the Quicksort algorithm (i.e. a Vanilla equivalent to vl-sort), with the first item of the list selected as the pivot.

The function may be easily modified to accept an arbitrary comparison function, e.g.:
Code - Auto/Visual Lisp: [Select]
  1. _$ (qs '(5 6 2 4 1 7 3 8) '<)
  2. (1 2 3 4 5 6 7 8)
  3. _$ (qs '(5 6 2 4 1 7 3 8) '>)
  4. (8 7 6 5 4 3 2 1)

Very impressive function, especially when you must deal only with vanilla lisp!
Would be very handy for David, if he defuns it as vl-sort. :)
Title: Re: Auditing a list of numerical string atoms
Post by: Lee Mac on April 01, 2017, 02:37:50 PM
It's an implementation of the Quicksort algorithm (i.e. a Vanilla equivalent to vl-sort), with the first item of the list selected as the pivot.

The function may be easily modified to accept an arbitrary comparison function, e.g.:
Code - Auto/Visual Lisp: [Select]
  1. _$ (qs '(5 6 2 4 1 7 3 8) '<)
  2. (1 2 3 4 5 6 7 8)
  3. _$ (qs '(5 6 2 4 1 7 3 8) '>)
  4. (8 7 6 5 4 3 2 1)

Very impressive function, especially when you must deal only with vanilla lisp!

Thanks - though of course, Quicksort is only one possible sorting algorithm - you might be interested in this thread (https://www.theswamp.org/index.php?topic=38292.0).  :-)
Title: Re: Auditing a list of numerical string atoms
Post by: Grrr1337 on April 01, 2017, 03:16:03 PM
Thanks - though of course, Quicksort is only one possible sorting algorithm - you might be interested in this thread (https://www.theswamp.org/index.php?topic=38292.0).  :-)

Thanks Lee, I've seen that thread before - but nothing similair like the function you wrote here.
Although the algorithm might be the same, for me it looks completely different (atleast comparing to the Gile's quicksort).

:)
Title: Re: Auditing a list of numerical string atoms
Post by: David Bethel on April 01, 2017, 04:40:55 PM
What I really like about this kind of problems is that it makes one think :idiot2:


Without a sorting or recursive

Code - Text: [Select]
  1. (defun db:anum (nl / il minn maxn i ml dl bl gl fl)
  2. ;;;GOOD AND BAD LISTS
  3.   (foreach a nl
  4.      (if (wcmatch a "*[~0-9]*")
  5.          (setq bl (cons a bl))
  6.          (setq gl (cons a gl))))
  7.  
  8.   (setq il (mapcar 'atoi gl)
  9.       minn (apply 'min il)
  10.       maxn (apply 'max il)
  11.          i minn)
  12.  
  13.   (repeat (1+ (- maxn minn))
  14.       (setq fl (cons (list i 0) fl))
  15.       (setq i (1+ i)))
  16.  
  17.   (foreach n il
  18.     (if (assoc n fl)
  19.         (setq fl (subst (list n (1+ (cadr (assoc n fl))))
  20.                         (assoc n fl) fl))))
  21.  
  22.   (foreach n fl
  23.     (cond ((= 1 (cadr n)))
  24.           ((= 0 (cadr n)) (setq ml (cons (car n) ml)))
  25.           ((< 1 (cadr n)) (setq dl (cons (car n) dl)))))
  26.  
  27.   (princ "\nFull List : \t")(prin1 fl)
  28.   (princ "\nDuplicate : \t")(prin1 dl)
  29.   (princ "\n  Missing : \t")(prin1 ml)
  30.   (princ "\n      Bad : \t")(prin1 bl)
  31.   (prin1))
  32.  

I'll have to noddle on the rest of variations.  Thanks to all !  -David