TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Grrr1337 on October 18, 2017, 01:31:53 PM

Title: Find the nest level of a list
Post by: Grrr1337 on October 18, 2017, 01:31:53 PM
Hey guys,
Anyone wanna play?  :idea:

The task is to find the "deepest" nesting level of a list:

Code - Auto/Visual Lisp: [Select]
  1. _$ (NestedListLevel "string") -> nil
  2. _$ (NestedListLevel nil ) -> nil
  3. _$ (NestedListLevel '("A" "B" "C") ) -> 0
  4. _$ (NestedListLevel '(("A")("B")("C")) ) -> 1
  5. _$ (NestedListLevel '(("A")(("B"))("C")) ) -> 2
  6. _$ (NestedListLevel '(("A")((((("B")))))("C")) ) -> 5
  7. _$ (NestedListLevel '(((("A")))((((((("B")))))))("C")) ) -> 7
  8. _$ (NestedListLevel '(((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")) ) -> 24

I hope the above example is clear enough.  :rolleyes2:

Heres my attempt with this:
Code - Auto/Visual Lisp: [Select]
  1. ; _$ (NestedListLevel "string") -> nil
  2. ; _$ (NestedListLevel nil ) -> nil
  3. ; _$ (NestedListLevel '("A" "B" "C") ) -> 0
  4. ; _$ (NestedListLevel '(("A")("B")("C")) ) -> 1
  5. ; _$ (NestedListLevel '(("A")(("B"))("C")) ) -> 2
  6. ; _$ (NestedListLevel '(("A")((((("B")))))("C")) ) -> 5
  7. ; _$ (NestedListLevel '(((("A")))((((((("B")))))))("C")) ) -> 7
  8. ; _$ (NestedListLevel '(((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")) ) -> 24
  9. (defun NestedListLevel ( L / rec )
  10.   (defun rec ( L i )
  11.     (or i (setq i 0))
  12.     (cond
  13.       ( (not L) (list i))
  14.       ( (and (listp L) (listp (car L))) (append (rec (car L) (1+ i)) (rec (cdr L) i)) )
  15.       ( (listp L) (rec (cdr L) i) )
  16.     )
  17.   )
  18.   (if (and L (listp L)) (apply 'max (rec L nil)) )
  19. ); defun NestedListLevel
IMO my code is a bit sloppy (sorry about that  - haven't done much recursions recently).
Title: Re: Find the nest level of a list
Post by: Lee Mac on October 18, 2017, 02:01:47 PM
Quick one:
Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( lst )
  2.     (apply 'max (mapcar '(lambda ( x ) (if (listp x) (if (< 0 (vl-list-length x)) (+ 1 (foo x)) 1) 0)) lst))
  3. )
Title: Re: Find the nest level of a list
Post by: ronjonp on October 18, 2017, 02:37:52 PM
Here's mine:
Code - Auto/Visual Lisp: [Select]
  1.  
  2. (defun nestedlistlevel_rjp (l)
  3.   (if (listp l)
  4.     (apply 'max
  5.            (mapcar (function (lambda (x)
  6.                                (if (listp x)
  7.                                  (length (vl-remove-if-not
  8.                                            (function (lambda (y) (= 40 y)))
  9.                                            (vl-string->list (vl-princ-to-string x))
  10.                                          )
  11.                                  )
  12.                                  0
  13.                                )
  14.                              )
  15.                    )
  16.                    l
  17.            )
  18.     )
  19.   ))
Title: Re: Find the nest level of a list
Post by: Lee Mac on October 18, 2017, 03:18:17 PM
Code - Auto/Visual Lisp: [Select]
  1. (nestedlistlevel_rjp '(("(1") "2" "3"))

Code - Auto/Visual Lisp: [Select]
  1. (nestedlistlevel_rjp '(((1) (2) (3))))

:wink:
Title: Re: Find the nest level of a list
Post by: Grrr1337 on October 18, 2017, 03:22:04 PM
Wow Lee, you always keep up with this super-advanced lisp level!
Guess I still have to figure out the mapcar with a recursive function combo.

Ron, interesting technique, but here are some bad news:

Code - Auto/Visual Lisp: [Select]
  1. _$ (NestedListLevel '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) )
  2. 26
  3. _$ (NESTEDLISTLEVEL_RJP '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) )
  4. 30
  5. _$ (foo '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) )
  6. 26
Title: Re: Find the nest level of a list
Post by: Lee Mac on October 18, 2017, 03:28:03 PM
Thanks Grrr1337  :-)

Here's another:
Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( l )
  2.     (cond
  3.         (   (/= 'list (type l)) 0)
  4.         (   (listp (car l)) (max (+ 1 (foo (car l))) (foo (cdr l))))
  5.         (   (foo (cdr l)))
  6.     )
  7. )
Title: Re: Find the nest level of a list
Post by: Lee Mac on October 18, 2017, 03:47:26 PM
Another, RJP-style :-)

Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( l / n r x )
  2.     (setq l (vl-string->list (vl-prin1-to-string l)) r 0 n -1)
  3.     (while (setq x (car l))
  4.         (cond
  5.             (   (= 34 x) (setq l (member 34 (cdr l))))
  6.             (   (= 40 x) (setq n (1+ n)))
  7.             (   (= 41 x) (setq r (max n r) n (1- n)))
  8.         )
  9.         (setq l (cdr l))
  10.     )
  11.     r
  12. )
Title: Re: Find the nest level of a list
Post by: Grrr1337 on October 18, 2017, 03:49:37 PM
Lee, the second one is outstanding! :-o
As I understood,
First you dig into the levels and then the recursion 'exits out'
by comparing each pair of lists (where the more nested has a higher priority for the max function [due the sum of the increasing 1+ increment]).

Even if I had the thought just for the idea I would be unable to write it correctly.
Actually now I see that in your both codes you are able to avoid to pass an index variable.
(BTW such complex subfunctions hint themselves about their author, even if its not mentioned)
Title: Re: Find the nest level of a list
Post by: Lee Mac on October 18, 2017, 04:12:22 PM
Lee, the second one is outstanding! :-o
As I understood,
First you dig into the levels and then the recursion 'exits out'
by comparing each pair of lists (where the more nested has a higher priority for the max function [due the sum of the increasing 1+ increment]).

Thank you Grrr1337 - the recursion is perhaps best demonstrated by a trace call:
Code - Auto/Visual Lisp: [Select]
  1. _$ (foo '(("A")((((("B")))))("C")))
  2. 5
Code - Auto/Visual Lisp: [Select]
  1. Entering (FOO (("A") ((((("B"))))) ("C")))
  2.   Entering (FOO ("A"))
  3.     Entering (FOO nil)
  4.     Result:  0
  5.   Result:  0
  6.   Entering (FOO (((((("B"))))) ("C")))
  7.     Entering (FOO ((((("B"))))))
  8.       Entering (FOO (((("B")))))
  9.         Entering (FOO ((("B"))))
  10.           Entering (FOO (("B")))
  11.             Entering (FOO ("B"))
  12.               Entering (FOO nil)
  13.               Result:  0
  14.             Result:  0
  15.             Entering (FOO nil)
  16.             Result:  0
  17.           Result:  1
  18.           Entering (FOO nil)
  19.           Result:  0
  20.         Result:  2
  21.         Entering (FOO nil)
  22.         Result:  0
  23.       Result:  3
  24.       Entering (FOO nil)
  25.       Result:  0
  26.     Result:  4
  27.     Entering (FOO (("C")))
  28.       Entering (FOO ("C"))
  29.         Entering (FOO nil)
  30.         Result:  0
  31.       Result:  0
  32.       Entering (FOO nil)
  33.       Result:  0
  34.     Result:  1
  35.   Result:  5
  36. Result:  5

Even if I had the thought just for the idea I would be unable to write it correctly.
Actually now I see that in your both codes you are able to avoid to pass an index variable.
(BTW such complex subfunctions hint themselves about their author, even if its not mentioned)

That's very kind of you to say, but don't be so down on yourself - your programming abilities have already improved significantly over the last few months since you started participating on the forums, and so with continued study & practice, there's no reason why you can't continue to progress. :-)
Title: Re: Find the nest level of a list
Post by: ronjonp on October 18, 2017, 04:15:03 PM
Code - Auto/Visual Lisp: [Select]
  1. (nestedlistlevel_rjp '(("(1") "2" "3"))

Code - Auto/Visual Lisp: [Select]
  1. (nestedlistlevel_rjp '(((1) (2) (3))))

 ;)
I figured it was a bust :) .. just a quick one for the data set provided.
Title: Re: Find the nest level of a list
Post by: Grrr1337 on October 18, 2017, 05:32:52 PM
That's very kind of you to say, but don't be so down on yourself

I'm more like impressed on what you guys can do in this forum (so I'm trying to learn whatever I possibly can).

your programming abilities have already improved significantly over the last few months since you started participating on the forums

I guess that once you get to know any programming language + doing alot of experiments and practice (which are results of high interest) the results are shown...
And then you can get a brief idea of what this language is capable of, so one could give inputs with his ideas about helpful functions (obviously you've been through all of this).

But ofcourse the learning process is not everything.. the tutoring part is (or the good explaining guys are) very important.
Just imagine if in every different programming language there was a Lee Mac guy helping you out with C++/VBA/Ruby/Python...
Its no secret about your huge impact over LISP.

In other words when I attempt to write any decend code in private and I get stuck somewhere in an unknown area,
ofcourse at first I google for a solution... what do I find? - similar question/issue by user X which years ago is solved by Lee Mac.
Then I spend some time to investigate Lee's code to understand or learn something new - so I end up with aside experiment codes where I learned more than I've expected.
Although for some this might sound like a annoying painful process with too much effort, I know that most of you guys here know what is to be driven by your own interest to explore even more in this LISP world.

and so with continued study & practice, there's no reason why you can't continue to progress. :-)

Well with that  trace call  you just revealed how such complex iterations/recursions can be visualised, so that shall be my small step of another adventure. :)
Like I previously mentioned, a I'm a NP++ user, that visualises in his head how the code runs (evaluation by evaluation)
and if stuck - just check the doubtful evaluations in VLIDE's console. So you know that didn't used any other advantages from VLIDE.

I always thought can I impress one of the best LISPers with any code(s) and ended up with progress.  :-D
atleast this idea boosted some motivation
Title: Re: Find the nest level of a list
Post by: ronjonp on October 19, 2017, 09:16:03 AM

For $h!+$ :)
Quote
_$


NESTEDLISTLEVEL
LEEFOO1
LEEFOO2
LEEFOORJPSTYLE
(((("A"))) ((((((((((((((((((((((("B" ("C")))))))))))))))))))))))) ("C")) Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):


    (LEEFOO2 L).............1329 / 1.99 <fastest>
    (LEEFOORJPSTYLE L)......1375 / 1.92
    (NESTEDLISTLEVEL L).....1547 / 1.71
    (LEEFOO1 L).............2641 / 1 <slowest>


 
; 6 forms loaded from #<editor "<Untitled-1> loading...">
_$
Title: Re: Find the nest level of a list
Post by: Marc'Antonio Alessi on October 19, 2017, 11:23:44 AM
My humble different approach only with strings, slower   :oops: , maybe good for lists with many numbers... >:D
Code: [Select]
(defun ALE_List_NestedLevel (l / r s e c i o)
  (setq i (vl-princ-to-string l) s 2 c 0 o 0)
  (while (setq e (vl-string-position 41 i s))
    (cond
      ( (= "(" (setq r (substr i s 1))) (setq c (1+ c) s (1+ s)) )
      ( (= ")" r)           (setq o (max c o) c (1- c) s (1+ s)) )
      ( (> (vl-string-position 40 i s) e)        (setq s (1+ e)) )
      ( T                                        (setq s (1+ s)) )
    )
  )
  o
)
Title: Re: Find the nest level of a list
Post by: Grrr1337 on October 19, 2017, 12:15:16 PM
The only easy iterative approach that comes to my mind is this:

Code - Auto/Visual Lisp: [Select]
  1. (defun NestLvl ( L / i )
  2.   (and L (listp L) (setq i 0)
  3.     (while (and L (vl-some (function vl-consp) L))
  4.       (setq L (apply (function append) (mapcar (function (lambda (x) (cond ( (listp x) x) ( (list x) )))) L)))
  5.       (setq i (1+ i))
  6.     )
  7.   )
  8.   i
  9. )

Code - Auto/Visual Lisp: [Select]
  1. _$ (NestLvl "string") -> nil
  2. _$ (NestLvl nil ) -> nil
  3. _$ (NestLvl '("A" "B" "C") ) -> 0
  4. _$ (NestLvl '(("A")("B")("C")) ) -> 1
  5. _$ (NestLvl '(("A")(("B"))("C")) ) -> 2
  6. _$ (NestLvl '(("A")((((("B")))))("C")) ) -> 5
  7. _$ (NestLvl '(((("A")))((((((("B")))))))("C")) ) -> 7
  8. _$ (NestLvl '(((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")) ) -> 24
  9. _$ (NestLvl '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) ) -> 26

IMO converting the whole list to a string and then processing is more frustrating. :)

Thanks for the benchmark Ron - I suspected that Lee's second suggestion would be the fastest.
Title: Re: Find the nest level of a list
Post by: Marc'Antonio Alessi on October 19, 2017, 01:09:50 PM
maybe it needs some tweaking ...
Code: [Select]
(defun ALE_List_NestedLevel2 (l / r s e c i o m)
  (setq i (vl-princ-to-string l) s 2 c 0 o 0)
  (while (setq e (vl-string-position 41 i s))
    (cond
      ( (= "(" (setq r (substr i s 1))) (setq c (1+ c) s (1+ s)) )
      ( (= ")" r)           (setq o (max c o) c (1- c) s (1+ s)) )
      ( (or
          (not (setq m (vl-string-position 40 i s)))
          (> m e)
        )
        (setq s (1+ e))
      )
      ( T (setq s (1+ s)) )
    )
  )
  o
)
Title: Re: Find the nest level of a list
Post by: Marc'Antonio Alessi on October 20, 2017, 03:38:30 AM


The only easy iterative approach that comes to my mind is this:
...
IMO converting the whole list to a string and then processing is more frustrating. :)

Yes but it is not so bad:

Code: [Select]
(setq alist '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) )
Benchmark.lsp | © 2005 Michael Puckett | All Rights Reserved
Elapsed milliseconds / relative speed for 32768 iteration(s):
    (LEEFOO2 ALIST)...................1375 / 3.89 <fastest>
    (ALE_LIST_NESTEDLEVEL2 ALIST).....2391 / 2.23
    (NESTLVL ALIST)...................5343 / 1 <slowest>

Thanks for the benchmark Ron - I suspected that Lee's second suggestion would be the fastest.

The recursion to Lee's levels is not in my reach, it's really on another planet for me  :oops: :'( (and for many others too)  ::)
Title: Re: Find the nest level of a list
Post by: Grrr1337 on October 20, 2017, 04:42:10 AM
Yeah Alessi - iterating a string makes sence to be faster.

This is my attempt with it - which ended up a bit more understandable version of Lee's 3rd code (the RJP-Style) :
Code - Auto/Visual Lisp: [Select]
  1. (defun nlvls ( L / sL n x isStr nL r )
  2.   (and L (listp L) (setq sL (mapcar 'chr (vl-string->list (vl-prin1-to-string L))))
  3.     (progn (setq n -1)
  4.       (while sL (setq x (car sL)) (setq sL (cdr sL))
  5.         (cond
  6.           ( (and (= "(" x) (not isStr) )
  7.             (setq n (1+ n))
  8.           )
  9.           ( (and (= ")" x) (not isStr) )
  10.             (setq n (1- n))
  11.           )
  12.           ( (= "\"" x) (setq isStr (if isStr nil T)) ) ; shift the string state
  13.         ); cond
  14.         (setq nL (cons n nL))
  15.       ); while
  16.       (setq r (apply 'max nL))
  17.     ); progn
  18.   ); and
  19.   r
  20. ); defun nlvls

Code - Auto/Visual Lisp: [Select]
  1. _$ (nlvls "string") -> nil
  2. _$ (nlvls nil ) -> nil
  3. _$ (nlvls '("A" "B" "C") ) -> 0
  4. _$ (nlvls '(("A")("B")("C")) ) -> 1
  5. _$ (nlvls '(("A")(("B"))("C")) ) -> 2
  6. _$ (nlvls '(("A")((((("B")))))("C")) ) -> 5
  7. _$ (nlvls '(((("A")))((((((("B")))))))("C")) ) -> 7
  8. _$ (nlvls '(((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")) ) -> 24
  9. _$ (nlvls '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) ) -> 26
  10. _$ (nlvls '(("(1") "2" "3")) -> 1
  11. _$ (nlvls '(((1) (2) (3)))) -> 2

And sorry I'm not that good string manipulator. :)


Title: Re: Find the nest level of a list
Post by: Marc'Antonio Alessi on October 20, 2017, 05:02:14 AM

Yeah Alessi - iterating a string makes sence to be faster.
This is my attempt with it - which ended up a bit more understandable version of Lee's 3rd code (the RJP-Style) :
...
And sorry I'm not that good string manipulator. :)
(setq alist '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) ); -> 26
My version works only on one long string:
Comando: (vl-princ-to-string alist)
"((((((A))) (((((((((((((((((((((((B (C)))))))))))))))))))))))) (C))))"


Not with a list of strings:
Comando: (mapcar 'chr (vl-string->list (vl-prin1-to-string alist)))

("(" "(" "(" "(" "(" "(" "\"" "A" "\"" ")" ")" ")" " " "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "(" "\"" "B" "\"" " " "(" "\"" "C" "\"" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" ")" " " "(" "\"" "C" "\"" ")" ")" ")" ")")
Code: [Select]
Benchmark.lsp | © 2005 Michael Puckett | All Rights Reserved

Elapsed milliseconds / relative speed for 32768 iteration(s):
    (LEEFOORJPSTYLE ALIST)............1547 / 1.88 <fastest>
    (ALE_LIST_NESTEDLEVEL2 ALIST).....2406 / 1.21
    (NLVLS ALIST).....................2907 / 1 <slowest>
I think that a good solution (not recursive) is to modifiy Lee's LEEFOORJPSTYLE
Code: [Select]
(defun LEEFOORJPSTYLE ( l / n r x )
    (setq l (vl-string->list (vl-prin1-to-string l)) r 0 n -1)
    (while (setq x (car l))
        (cond
            (   (= 34 x) (setq l (member 34 (cdr l))))
            (   (= 40 x) (setq n (1+ n)))
            (   (= 41 x) (setq r (max n r) n (1- n)))
        )
        (setq l (cdr l))
    )
    r
)
to skip numbers as it skip strings... ;)
Title: Re: Find the nest level of a list
Post by: Marc'Antonio Alessi on October 20, 2017, 05:11:52 AM
This is a test with Strings and Numbers;
(setq alist '((((((1212121212 12121212 12121212 1 233333333)))((((((((((((((((((((((("BBBBBBBB" (121233333 211212 121212 12121212 12121212 12121212 1233333312))))))))))))))))))))))))("CBBBBBBB")))))
Code: [Select]
Elapsed milliseconds / relative speed for 16384 iteration(s):
    (ALE_LIST_NESTEDLEVEL2 ALIST).....1391 / 2.34 <fastest>
    (LEEFOORJPSTYLE ALIST)............1515 / 2.15
    (NLVLS ALIST).....................3250 / 1 <slowest>
Title: Re: Find the nest level of a list
Post by: VovKa on October 20, 2017, 05:16:41 AM
Code: [Select]
'("a\"(((())))")
Title: Re: Find the nest level of a list
Post by: Grrr1337 on October 20, 2017, 05:48:59 AM


Yeah Alessi - iterating a string makes sence to be faster.
This is my attempt with it - which ended up a bit more understandable version of Lee's 3rd code (the RJP-Style) :
...
And sorry I'm not that good string manipulator. :)
(setq alist '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) ); -> 26
My version works only on one long string:
Comando: (vl-princ-to-string alist)
"((((((A))) (((((((((((((((((((((((B (C)))))))))))))))))))))))) (C))))"


Yeah, I noticed that.. thats why I apologise. :)

Code: [Select]
'("a\"(((())))")

Blew my head.  :-o
I guess this shows that processing the whole list as a string would be even more complex.
Title: Re: Find the nest level of a list
Post by: Marc'Antonio Alessi on October 20, 2017, 05:55:31 AM

Code: [Select]
'("a\"(((())))")
Comando: (ALE_List_NestedLevel2  '("a\"(((())))"))
4
Comando: (LEEFOORJPSTYLE  '("a\"(((())))"))
4
Comando: (nlvls  '("a\"(((())))"))
4
Comando: (foo  '("a\"(((())))"))
0
Yes... Lee's Foo is the best,  8)
Title: Re: Find the nest level of a list
Post by: Grrr1337 on October 20, 2017, 06:12:47 AM
Alessi,
The codes on replies #1 #5 #13 aswell the first one in my post should work on this (since they don't process the list as a string).

This mod of the code in my main post should be slightly faster:
Code - Auto/Visual Lisp: [Select]
  1. ; _$ (NestedListLevel "string") -> nil
  2. ; _$ (NestedListLevel nil ) -> nil
  3. ; _$ (NestedListLevel '("A" "B" "C") ) -> 0
  4. ; _$ (NestedListLevel '(("A")("B")("C")) ) -> 1
  5. ; _$ (NestedListLevel '(("A")(("B"))("C")) ) -> 2
  6. ; _$ (NestedListLevel '(("A")((((("B")))))("C")) ) -> 5
  7. ; _$ (NestedListLevel '(((("A")))((((((("B")))))))("C")) ) -> 7
  8. ; _$ (NestedListLevel '(((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")) ) -> 24
  9. ; _$ (NestedListLevel '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) ) -> 26
  10. ; _$ (NestedListLevel '(("(1") "2" "3")) -> 1
  11. ; _$ (NestedListLevel '(((1) (2) (3)))) -> 2
  12. ; _$ (NestedListLevel '("a\"(((())))")) -> 0
  13. (defun NestedListLevel ( L / rec )
  14.   (defun rec ( L i )
  15.     (cond
  16.       ( (not L) (list i))
  17.       ( (eq 'LIST (type L))
  18.         (cond
  19.           ( (eq 'LIST (type (car L))) (append (rec (car L) (1+ i)) (rec (cdr L) i)) )
  20.           ( (rec (cdr L) i) )
  21.         )
  22.       )
  23.     )
  24.   )
  25.   (if (and L (listp L)) (apply 'max (rec L 0)) )
  26. ); defun NestedListLevel

I assume that Lee's code in Reply #5 is the fastest, but I'm not sure how it compares to the one in Reply #13.
Theoretically the strategy you mentioned would be the fastest, until Vovka pointed out the nested strings problem.

(Sorry not sure how to address you [Mark/Antonio/Alessi])
Title: Re: Find the nest level of a list
Post by: VovKa on October 20, 2017, 06:33:56 AM
I assume that Lee's code in Reply #5 is the fastest, but I'm not sure how it compares to the one in Reply #13.
as to the code in Reply #13
Code: [Select]
(NestLvl '((1 . 2)))
Title: Re: Find the nest level of a list
Post by: Grrr1337 on October 20, 2017, 07:46:30 AM
I assume that Lee's code in Reply #5 is the fastest, but I'm not sure how it compares to the one in Reply #13.
as to the code in Reply #13
Code: [Select]
(NestLvl '((1 . 2)))

Unexpected! <duh> :)
Title: Re: Find the nest level of a list
Post by: Marc'Antonio Alessi on October 20, 2017, 07:49:37 AM


Alessi,
The codes on replies #1 #5 #13 aswell the first one in my post should work on this (since they don't process the list as a string).

This mod of the code in my main post should be slightly faster:
...
I assume that Lee's code in Reply #5 is the fastest, but I'm not sure how it compares to the one in Reply #13.
Theoretically the strategy you mentioned would be the fastest, until Vovka pointed out the nested strings problem.

(Sorry not sure how to address you [Mark/Antonio/Alessi])
For #13 see #23...
Code: [Select]
(setq alist '((((((1212121212 12121212 12121212 1 233333333)((1 . 2)))("a\"(((())))")))((((((((((((((((((((((("BBBBBBBB" (121233333 211212 121212 12121212 12121212 12121212 1233333312))))))))))))))))))))))))("CBBBBBBB"))))
Elapsed milliseconds / relative speed for 32768 iteration(s):
    (FOO#5 ALIST)..................1750 / 1.76 <fastest>
    (FOO#1 ALIST)..................1891 / 1.63
    (NESTEDLISTLEVEL#22 ALIST).....3078 / 1 <slowest>
>>> Marco



Title: Re: Find the nest level of a list
Post by: Grrr1337 on October 20, 2017, 08:31:49 AM
I thought that #22 would be close to #5, but it seems that append and maybe (apply 'max ...) slows down the process.
Thanks Marco!
Title: Re: Find the nest level of a list
Post by: VovKa on October 20, 2017, 10:08:09 AM
found one in a book https://issuu.com/enelf/docs/lisp1/382
section 3.3 number 2
it's a bit different but looks good
Title: Re: Find the nest level of a list
Post by: Grrr1337 on October 20, 2017, 11:21:24 AM
found one in a book https://issuu.com/enelf/docs/lisp1/382
section 3.3 number 2
it's a bit different but looks good

Cool book!
However the function you pointed doesn't work:

Code: [Select]
; глубина = depth
(defun depth (х)
  (cond
    ( (atom x) 1)
    (t (max_ (+ 1 (depth (car x))) (depth (cdr x))) )
  )
)

(defun max_ (х у) ; встроенная функция MAX
  (if (> x y) x y)
)

Returns a value of 1 for all of our performed tests.
Title: Re: Find the nest level of a list
Post by: Marc'Antonio Alessi on October 20, 2017, 11:38:54 AM

Code: [Select]
(defun depth (x)
  (cond
    ( (atom x) 1)
    (t (max_ (+ 1 (depth (car x))) (depth (cdr x))) )
  )
)
(defun max_ (x y)
  (if (> x y) x y)
)
Code: [Select]
Comando: (setq alist '((((((1212121212 12121212 12121212 1 233333333)((1 . 2)))("a\"(((())))")))((((((((((((((((((((((("BBBBBBBB" (121233333 211212 121212 12121212 12121212 12121212 1233333312))))))))))))))))))))))))("CBBBBBBB"))))
((((((1212121212 12121212 12121212 1 233333333) ((1 . 2))) ("a\"(((())))"))) ((((((((((((((((((((((("BBBBBBBB" (121233333 211212 121212 12121212 12121212 12121212 1233333312)))))))))))))))))))))))) ("CBBBBBBB")))
Comando: (FOO#5 ALIST)
25
Comando: (depth AList)
27
Comando: (setq alist '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) )
(((((("A"))) ((((((((((((((((((((((("B" ("C")))))))))))))))))))))))) ("C"))))
Comando: (FOO#5 ALIST)
26
Comando: (depth AList)
28
Title: Re: Find the nest level of a list
Post by: VovKa on October 20, 2017, 12:22:52 PM
could it be that there's a misprint in the book, shouldn't it be -1?
and there is no need to define max_ function, we can use built-in max instead
Code: [Select]
(defun depth (x)
  (cond ((atom x) -1)
(t (max (1+ (depth (car x))) (depth (cdr x))))
  )
)
Title: Re: Find the nest level of a list
Post by: Marc'Antonio Alessi on October 20, 2017, 12:36:04 PM

could it be that there's a misprint in the book, shouldn't it be -1?
and there is no need to define max_ function, we can use built-in max instead
Code: [Select]
(defun depth (x)
  (cond   ((atom x) -1)
   (t (max (1+ (depth (car x))) (depth (cdr x))))
  )
)
Code: [Select]
(setq alist '(((((("A") ("a\"(((())))") ((1 . 2))  ))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) ); -> 26
Elapsed milliseconds / relative speed for 65536 iteration(s):
    (DEPTH ALIST).....2000 / 1.53 <fastest>
    (FOO#5 ALIST).....3063 / 1 <slowest>
Title: Re: Find the nest level of a list
Post by: Lee Mac on October 20, 2017, 01:03:37 PM
Which is it?
Code - Auto/Visual Lisp: [Select]
  1. _$ (depth '())
  2. -1
  3. _$ (foo '())
  4. 0
Title: Re: Find the nest level of a list
Post by: JohnK on October 20, 2017, 01:49:19 PM
I havent read the thread but I don't think that classifies as a tree, Lee. However, I guess it's depth would technically be zero if it were classified as one. But I think I would still want my function to return -1 in the case of a null tree.
Title: Re: Find the nest level of a list
Post by: Grrr1337 on October 20, 2017, 02:26:42 PM
Damn I'm so close fixing this (iterative) code from reply #13:

Code - Auto/Visual Lisp: [Select]
  1. (defun NestLvl ( L / i r )
  2.   (and L (listp L) (setq i 0)
  3.     (while (and L (vl-some (function vl-consp) L))
  4.       (setq L
  5.         (apply (function append)
  6.           (setq r ; only for debugging purpose
  7.             (mapcar
  8.               (function
  9.                 (lambda (x / v )
  10.                   (cond
  11.                     ( (atom x) nil)
  12.                     (  
  13.                       (if (atom (setq v (cdr x))) ; dotted pair
  14.                         (cons (car x) (list v))
  15.                         x
  16.                       )
  17.                     )
  18.                   ); cond
  19.                 ); lambda
  20.               ); function
  21.               L
  22.             ); mapcar
  23.           )
  24.         )
  25.       )
  26.       (setq i (1+ i))
  27.     )
  28.   )
  29.   i
  30. ); defun NestLvl

Code - Auto/Visual Lisp: [Select]
  1. _$ (setq aL
  2.   '(
  3.     ((1 . 2))
  4.     ("a\"(((())))")
  5.     "string"
  6.     nil
  7.     ("A" "B" "C")
  8.     (("A")("B")("C"))
  9.     (("A")(("B"))("C"))
  10.     (("A")((((("B")))))("C"))
  11.     (((("A")))((((((("B")))))))("C"))
  12.     (((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C"))
  13.     (((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C"))))
  14.     (("(1") "2" "3")
  15.     (((1) (2) (3)))
  16.     ("a\"(((())))")
  17.   )
  18. )
  19.  
  20. _$ (mapcar 'NestLvl aL)
  21. (1 0 nil nil 0 1 2 5 7 24 26 1 2 0)
  22. _$ (mapcar 'NestedListLevel aL)
  23. (0 0 nil nil 0 1 2 5 7 24 26 1 2 0) ; this is the correct result for reference
Yet so far.
Title: Re: Find the nest level of a list
Post by: Marc'Antonio Alessi on October 23, 2017, 10:54:07 AM
; Just for fun - iterative - string based
; (mapcar 'ALE_List_NestedLevel3 aL) > (1 0 0 0 0 1 2 5 7 24 26 1 2 0)
Code: [Select]
(defun ALE_List_NestedLevel4 (l / r s e c i o m)
  (setq i (vl-prin1-to-string l)  s 0  c -1  o 0)
  (while (vl-string-position 92 i) (setq i (vl-string-subst "" "\\\"" i)))
  (while (setq e (vl-string-position 41 i s))
    (cond
      ( (= "\"" (setq r (substr i (setq s (1+ s)) 1))) (setq s (1+ (vl-string-position 34 i s))) )
      ( (= "(" r) (setq c (1+ c)) )
      ( (= ")" r) (setq o (max c o)  c (1- c)) )
      ( (or (not (setq m (vl-string-position 40 i (1- s)))) (> m e)) (setq s e) )
    )
  )
  o
)
Title: Re: Find the nest level of a list
Post by: VovKa on October 23, 2017, 05:10:38 PM
Code: [Select]
(ALE_List_NestedLevel4 '("\\\""))
Title: Re: Find the nest level of a list
Post by: Marc'Antonio Alessi on October 24, 2017, 03:04:13 PM
Code: [Select]
(ALE_List_NestedLevel4 '("\\\""))
...maybe it's time to throw the sponge...