Author Topic: Parse a list of integers  (Read 4760 times)

0 Members and 1 Guest are viewing this topic.

David Bethel

  • Swamp Rat
  • Posts: 656
Parse a list of integers
« on: September 10, 2015, 02:33:14 PM »
Greetings

Using vanilla Autolisp :

Given a sorted list of integers that always starts with 1
Code: [Select]
(setq lst '(1 12 16 21 26 32 40 42 56 66 74))

A function to parse the list with a  maximum difference between values of a specified number of units ie 24
Code: [Select]
(parsel lst 24)

And return a list of lists with the start and end positions:
Code: [Select]
'((1 21) (21 42) (42 66) (66 74))

(1 25) would be valid
Code: [Select]
(<= (- 25 1) 24) ->  T

Any ideas ?  Thanks  -David

PS I haven't figured out what to do if the difference is greater than 24 for 2 adjacent atoms.

Here's where I'm at and it aint working !

Code: [Select]
(defun parsel (lst q / s ) ;i  rl)
  (setq s (car lst))
  (while (< s (last lst))
     (setq i 0)
     (repeat (length lst)
        (if (> (+ s q) (- (nth i lst) s))
            (setq i (1+ i))))
     (setq rl (cons (list s (nth (1- i) lst)) rl)
            s (nth (1- i) lst)))
  (setq rl (cons (list s (last lst)) rl))
  (prin1 (reverse rl)))

Any ideas ?  Thanks  -David
R12 Dos - A2K

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Parse a list of integers
« Reply #1 on: September 10, 2015, 03:01:04 PM »
Not pretty but seems to work with your example  :) 
Guess I should have read a bit closer :oops:   .. does not account for adjacent atoms.
Code - Auto/Visual Lisp: [Select]
  1. (setq l '(1 12 16 21 26 32 40 42 56 66 74))
  2. (defun _foo (l / i i2 out)
  3.   (while (setq i (car l)
  4.           l (cdr l)
  5.     )
  6.     (while (and l (<= (- (car l) i) 24))
  7.       (setq i2 (car l)
  8.        l  (cdr l)
  9.       )
  10.     )
  11.     (setq l   (cons i2 l)
  12.      out (cons (cons i i2) out)
  13.     )
  14.   )
  15.   (reverse out)
  16. )
  17. (_foo l)
  18.  
  19.  
  20. ;;;_$
  21. ;;;
  22. ;;;(1 12 16 21 26 32 40 42 56 66 74)
  23. ;;;_FOO
  24. ;;;((1 . 21) (21 . 42) (42 . 66) (66 . 74))
  25. ;;;; 3 forms loaded from #<editor "<Untitled-1> loading...">
  26. ;;;_$
« Last Edit: September 10, 2015, 03:20:32 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

jvillarreal

  • Bull Frog
  • Posts: 332
Re: Parse a list of integers
« Reply #2 on: September 10, 2015, 03:26:28 PM »
Greetings

Using vanilla Autolisp :

Given a sorted list of integers that always starts with 1
Code: [Select]
(setq lst '(1 12 16 21 26 32 40 42 56 66 74))

A function to parse the list with a  maximum difference between values of a specified number of units ie 24
Code: [Select]
(parsel lst 24)

And return a list of lists with the start and end positions:
Code: [Select]
'((1 21) (21 42) (42 66) (66 74))

(1 25) would be valid
Code: [Select]
(<= (- 25 1) 24) ->  T

Any ideas ?  Thanks  -David

PS I haven't figured out what to do if the difference is greater than 24 for 2 adjacent atoms.

Here's where I'm at and it aint working !

Code: [Select]
(defun parsel (lst q / s ) ;i  rl)
  (setq s (car lst))
  (while (< s (last lst))
     (setq i 0)
     (repeat (length lst)
        (if (> (+ s q) (- (nth i lst) s))
            (setq i (1+ i))))
     (setq rl (cons (list s (nth (1- i) lst)) rl)
            s (nth (1- i) lst)))
  (setq rl (cons (list s (last lst)) rl))
  (prin1 (reverse rl)))

Any ideas ?  Thanks  -David

Using your code:
Code: [Select]
(defun parsel (lst q / s i  rl)
  (setq s (car lst))
  (while (< s (last lst))
     (setq i 0)
     (repeat (length lst)
        (if (>= q (- (nth i lst) s));include equal to and adding s is not needed
            (setq i (1+ i))))
    (if (not (zerop (- (nth (1- i) lst) s)))
     (setq rl (cons (list s (nth (1- i) lst)) rl)
            s (nth (1- i) lst))
     (setq s (nth i lst))
    )
)
 ;(setq rl (cons (list s (last lst)) rl));Not sure why this is being done
  (reverse rl));Removed prin1, assuming it was placed for your testing

*Edit* - Added additional if statement in case difference between current and next number exceed maximum diff
« Last Edit: September 10, 2015, 03:52:03 PM by jvillarreal »

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Parse a list of integers
« Reply #3 on: September 10, 2015, 03:51:32 PM »

So far so good !

I figured it was something fairly simple that I was overlooking

 Thanks!  -David
R12 Dos - A2K

jvillarreal

  • Bull Frog
  • Posts: 332
Re: Parse a list of integers
« Reply #4 on: September 10, 2015, 03:52:34 PM »
Edited previous post for a case such as (parsel lst 12)

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Parse a list of integers
« Reply #5 on: September 10, 2015, 04:42:34 PM »

Thanks.  I'm still contemplating a few different scenarios that I know will crash ( or at least give my poor brain and headache.  -David
R12 Dos - A2K

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Parse a list of integers
« Reply #6 on: September 10, 2015, 04:44:27 PM »
Not pretty but seems to work with your example  :) 


I'll have to give this some thought on how it works !  Thanks  -David
R12 Dos - A2K

Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: Parse a list of integers
« Reply #7 on: September 10, 2015, 06:35:31 PM »
Another, not likely to be fast:
Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( l n )
  2.     (if l (bar (car l) (+ (car l) n) n (cdr l)))
  3. )
  4. (defun bar ( a b n l )
  5.     (if (cadr l)
  6.         (if (< b (cadr l))
  7.             (cons (list a (car l)) (foo l n))
  8.             (bar a b n (cdr l))
  9.         )
  10.         (list (list a (car l)))
  11.     )
  12. )
Code - Auto/Visual Lisp: [Select]
  1. _$ (foo lst 24)
  2. ((1 21) (21 42) (42 66) (66 74))

Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: Parse a list of integers
« Reply #8 on: September 10, 2015, 06:52:23 PM »
Another:
Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( l n / x y r )
  2.     (setq x (car  l)
  3.           y (cadr l)
  4.     )
  5.     (foreach z (cddr l)
  6.         (if (< (+ x n) z) (setq r (cons (list x y) r) x y))
  7.         (setq y z)
  8.     )
  9.     (reverse (cons (list x y) r))
  10. )

Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: Parse a list of integers
« Reply #9 on: September 10, 2015, 07:15:45 PM »
Another:
Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( l n )
  2.     (if (caddr l)
  3.         (if (< (+ (car l) n) (caddr l))
  4.             (cons (list (car l) (cadr l)) (foo (cdr l) n))
  5.             (foo  (cons (car l) (cddr l)) n)
  6.         )
  7.         (list l)
  8.     )
  9. )

AIberto

  • Guest
Re: Parse a list of integers
« Reply #10 on: September 10, 2015, 08:55:42 PM »
 :-(
I can't understand.
(setq lst '(1 12 16 21 26 32 40 42 56 66 74))

(parsel lst 24)
why returns '((1 21) (21 42) (42 66) (66 74))

why not '((1 12) (12 16) (16 21) (21 26)..............)

(<= (- 12 1) 24) ->  T , (<= (- 16 12) 24) ->  T........

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Parse a list of integers
« Reply #11 on: September 11, 2015, 03:33:45 AM »
why not '((1 12) (12 16) (16 21) (21 26)..............)
Because
A function to parse the list with a  maximum difference between values of a specified number of units ie 24
Code: [Select]
(parsel lst 24)

A bit unclearly stated, but it seems to mean: Get pairs of values, where their difference is the maximum less than (or equal to) a specified quantizer (in this case 24).

Your scenario (i.e. simply pair consecutive items) would be very easy:
Code - Auto/Visual Lisp: [Select]
  1. (mapcar 'list lst (cdr lst))
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Parse a list of integers
« Reply #12 on: September 11, 2015, 05:44:15 AM »
What should be the result of the function in this case?:
Code: [Select]
(setq lst '(1 12 16 21 26 32 40 42 56 66 74))
(setq dif 2)

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Parse a list of integers
« Reply #13 on: September 11, 2015, 05:57:35 AM »
My offer:
Code - Auto/Visual Lisp: [Select]
  1. ; (Roy_Test_01 '(1 12 16 21 26 32 40 42 56 66 74)  2)
  2. ;   => ((40 . 42))
  3. ; (Roy_Test_01 '(1 12 16 21 26 32 40 42 56 66 74) 10)
  4. ;   => ((12 . 21) (21 . 26) (26 . 32) (32 . 42) (56 . 66) (66 . 74))
  5. ; (Roy_Test_01 '(1 12 16 21 26 32 40 42 56 66 74) 24)
  6. ;   => ((1 . 21) (21 . 42) (42 . 66) (66 . 74))
  7. (defun Roy_Test_01 (lst dif / itm)
  8.   (setq itm (car lst))
  9.     nil
  10.     (mapcar
  11.       '(lambda (cur nxt)
  12.         (if (or (not nxt) (< dif (- nxt itm)))
  13.           (if (< dif (- cur itm))
  14.             (not (setq itm cur))
  15.             (cons itm (setq itm cur))
  16.           )
  17.         )
  18.       )
  19.       (cdr lst)
  20.       (append (cddr lst) '(nil))
  21.     )
  22.   )
  23. )

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Parse a list of integers
« Reply #14 on: September 11, 2015, 06:10:09 AM »
What should be the result of the function in this case?:
Code: [Select]
(setq lst '(1 12 16 21 26 32 40 42 56 66 74))
(setq dif 2)
Agreed - most of the codes here would at worst cause an infinite loop, or need to make some assumption.


@David: Could you please specify what should happen if the quantile is smaller than the difference between some 2 consecutive items in the list?
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

AIberto

  • Guest
Re: Parse a list of integers
« Reply #15 on: September 11, 2015, 06:40:30 AM »
why not '((1 12) (12 16) (16 21) (21 26)..............)
Because
A function to parse the list with a  maximum difference between values of a specified number of units ie 24
Code: [Select]
(parsel lst 24)

A bit unclearly stated, but it seems to mean: Get pairs of values, where their difference is the maximum less than (or equal to) a specified quantizer (in this case 24).

Your scenario (i.e. simply pair consecutive items) would be very easy:
Code - Auto/Visual Lisp: [Select]
  1. (mapcar 'list lst (cdr lst))

? mean:   The dif between the two numbers  must nearest  24 ?

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Parse a list of integers
« Reply #16 on: September 11, 2015, 06:52:50 AM »
? mean:   The dif between the two numbers  must nearest  24 ?
Not quite - as in:
Code - Auto/Visual Lisp: [Select]
  1. (<= (- 12 1) 24) ;T
  2. ;; but, check next in list also
  3. (<= (- 16 1) 24) ;T
  4. ;; Again, check next
  5. (<= (- 21 1) 24) ;T
  6. ;; Still working ...
  7. (<= (- 26 1) 24) ;nil
  8. ;;Finally found the one larger than the quantizer, so return the largest of those which comply
  9.  


As I said, the OP didn't clearly state this. Only from his examples is such inferred.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Parse a list of integers
« Reply #17 on: September 11, 2015, 06:54:05 AM »
@irneb

I do know there are possible scenarios where a crash is possible.

As for using 2 or something small as the max, that was not the intent.

Let's say I have to have an upright at each end of a assembly and there is a maximum width of a glass panel between the middle posts and there a limited number of attachment points available :

Problems I need to think about :
  • What to do if there the distance between the available attachment point is greater than the maximum
  • What to do if there is a very short distance between 2 middle posts

And I'm sure more possibilities are out there

Thanks  -David
R12 Dos - A2K

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Parse a list of integers
« Reply #18 on: September 11, 2015, 07:02:11 AM »
 This is cool !

The largest value of the list will probably be less than 200.  The max spacing may be 48.  So the speed of the function or even a recursive function will not be a problem.

Another:
Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( l n )
  2.     (if (caddr l)
  3.         (if (< (+ (car l) n) (caddr l))
  4.             (cons (list (car l) (cadr l)) (foo (cdr l) n))
  5.             (foo  (cons (car l) (cddr l)) n)
  6.         )
  7.         (list l)
  8.     )
  9. )

Thanks!  -David
R12 Dos - A2K

AIberto

  • Guest
Re: Parse a list of integers
« Reply #19 on: September 11, 2015, 07:02:57 AM »
? mean:   The dif between the two numbers  must nearest  24 ?
Not quite - as in:
Code - Auto/Visual Lisp: [Select]
  1. (<= (- 12 1) 24) ;T
  2. ;; but, check next in list also
  3. (<= (- 16 1) 24) ;T
  4. ;; Again, check next
  5. (<= (- 21 1) 24) ;T
  6. ;; Still working ...
  7. (<= (- 26 1) 24) ;nil
  8. ;;Finally found the one larger than the quantizer, so return the largest of those which comply
  9.  


As I said, the OP didn't clearly state this. Only from his examples is such inferred.


I think OP mean like this:
(<= (- 12 1) 24);T
(<= (- 16 1) 24);T
(<= (- 21 1) 24);T
(<= (- 26 1) 24);nil
SO, keep the previous value (T) , result:(1 .21)

(<= (- 26 21) 24);T
(<= (- 32 21) 24);T
(<= (- 40 21) 24);T
(<= (- 42 21) 24);T
(<= (- 56 21) 24);nil
SO, keep the previous value (T) , result:(21 .42)

(<= (- 56 42) 24);T
(<= (- 66 42) 24);T
(<= (- 74 42) 24);nil
SO, keep the previous value (T) , result:(42 .66)

Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: Parse a list of integers
« Reply #20 on: September 11, 2015, 07:05:10 AM »
This is cool !

The largest value of the list will probably be less than 200.  The max spacing may be 48.  So the speed of the function or even a recursive function will not be a problem.

Another:
Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( l n )
  2.     (if (caddr l)
  3.         (if (< (+ (car l) n) (caddr l))
  4.             (cons (list (car l) (cadr l)) (foo (cdr l) n))
  5.             (foo  (cons (car l) (cddr l)) n)
  6.         )
  7.         (list l)
  8.     )
  9. )

Thanks!  -David

Thank you David - this would be a good 'Challenge' thread  :-)

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Parse a list of integers
« Reply #21 on: September 11, 2015, 07:07:01 AM »
@irneb

I do know there are possible scenarios where a crash is possible.
Ah! I thought this looked familiar. Similar to a length optimization routine (as in reduce the number of panels to the minimum possible), though coming from the other side instead.


So actually you would want to see those which don't fit correctly. You'd want to be warned when 2 consecutive distances are further apart than the maximum panel length. This is why such questions should be asked - else you get assumptions like both Roy and myself made: "Just drop the items which don't fit the parameters".
« Last Edit: September 11, 2015, 07:10:15 AM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Parse a list of integers
« Reply #22 on: September 11, 2015, 07:14:02 AM »

Thank you David - this would be a good 'Challenge' thread  :-)

It's always cool to see a recursive function using a (trace foo) call

Code: [Select]
Command: parsel
  Entering FOO: (1 12 16 21 26 32 40 42 56 66 74) 24
     Entering FOO: (1 16 21 26 32 40 42 56 66 74) 24
        Entering FOO: (1 21 26 32 40 42 56 66 74) 24
            Entering FOO: (21 26 32 40 42 56 66 74) 24
               Entering FOO: (21 32 40 42 56 66 74) 24
                  Entering FOO: (21 40 42 56 66 74) 24
                     Entering FOO: (21 42 56 66 74) 24
                         Entering FOO: (42 56 66 74) 24
                            Entering FOO: (42 66 74) 24
                                Entering FOO: (66 74) 24
                                Result: ((66 74))
                            Result: ((42 66) (66 74))
                         Result: ((42 66) (66 74))
                     Result: ((21 42) (42 66) (66 74))
                  Result: ((21 42) (42 66) (66 74))
               Result: ((21 42) (42 66) (66 74))
            Result: ((21 42) (42 66) (66 74))
        Result: ((1 21) (21 42) (42 66) (66 74))
     Result: ((1 21) (21 42) (42 66) (66 74))
  Result: ((1 21) (21 42) (42 66) (66 74))
((1 21) (21 42) (42 66) (66 74))


It tells the story of what's happening very clearly ( to me any way )

-David
R12 Dos - A2K

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Parse a list of integers
« Reply #23 on: September 11, 2015, 09:12:29 AM »
So actually you would want to see those which don't fit correctly. You'd want to be warned when 2 consecutive distances are further apart than the maximum panel length. This is why such questions should be asked - else you get assumptions like both Roy and myself made: "Just drop the items which don't fit the parameters".

These are called "Action Stations".  Normally the table top equipment is located first based on work flow, then the cart and then the breath guard is assembled.  So the designer needs to have the parameters / restrictions in mind during this process

If this routine were to be done for anyone other than in-house, I'd think I'd add lots of error trapping / warnings / restrictions.

But if I'm going to be dumb, I gotta be tuff.

Thanks !  -David
R12 Dos - A2K

AIberto

  • Guest
Re: Parse a list of integers
« Reply #24 on: September 11, 2015, 10:10:01 AM »
So actually you would want to see those which don't fit correctly. You'd want to be warned when 2 consecutive distances are further apart than the maximum panel length. This is why such questions should be asked - else you get assumptions like both Roy and myself made: "Just drop the items which don't fit the parameters".

These are called "Action Stations".  Normally the table top equipment is located first based on work flow, then the cart and then the breath guard is assembled.  So the designer needs to have the parameters / restrictions in mind during this process

If this routine were to be done for anyone other than in-house, I'd think I'd add lots of error trapping / warnings / restrictions.

But if I'm going to be dumb, I gotta be tuff.

Thanks !  -David


Hi David
It looks beautiful , This is Kitchen stove ?

Can you explain ?
The relationship between
 ((1 21) (21 42) (42 66) (66 74))
and
 you image

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Parse a list of integers
« Reply #25 on: September 11, 2015, 11:39:06 AM »
An action station is a trendy thing where the customer goes up to the counter and orders an item to their specification, or just to watch the chef.  These normally use either induction cooking or heated stone surfaces so that no grease extraction ventilation system is required.


The post upright and / or mounting flanges are normally either 2" round or 2" square.  The center line of the 1st post would then 1" end from 1 end.  The pair represent the center lines of each segment's uprights.

In the example list that I posted, the overall dimension of the assembly would be 75" with (4) segment, but is not very practical.

With the list in hand, a fabricator could easily make and install all of the components and glass panels


HTH  -David
« Last Edit: September 11, 2015, 04:24:36 PM by David Bethel »
R12 Dos - A2K

AIberto

  • Guest
Re: Parse a list of integers
« Reply #26 on: September 11, 2015, 11:49:49 AM »
An action station is a trendy thing where the customer goes up to the counter and orders an item to their specification, or just to watch the chef.  These normally use either induction cooking or heated stone surfaces so that no grease extraction ventilation system is required.


The post upright and / or mounting flanges are normally either 2" round or 2" square.  The center line of the 1st post would then 1" end from 1 end.  The pair represent the center lines of each segment's uprights.

In the example list that I posted, the overall dimension of the assembly would be 76" with (4) segment, but is not very practical.

With the list in hand, a fabricator could easily make and install all of the components and glass panels


HTH  -David

Thank you for your explanation. David
Let me ask you a final question:
Where does these Numbers  come from ?
'(1 12 16 21 26 32 40 42 56 66 74) 

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Parse a list of integers
« Reply #27 on: September 11, 2015, 02:13:02 PM »

Let me ask you a final question:
Where does these Numbers  come from ?
'(1 12 16 21 26 32 40 42 56 66 74)

They would represent all the valid attachment points for the uprights ( theoretically )  -David
R12 Dos - A2K