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)
I figured it was a bust :) .. just a quick one for the data set provided.Code - Auto/Visual Lisp: [Select]
(nestedlistlevel_rjp '(("(1") "2" "3"))Code - Auto/Visual Lisp: [Select]
(nestedlistlevel_rjp '(((1) (2) (3))))
;)
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. :-)
_$
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...">
_$
(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
)
(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
)
Yes but it is not so bad:
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. :)
(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.
Yeah Alessi - iterating a string makes sence to be faster.(setq alist '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) ); -> 26
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. :)
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(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... ;)
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>
'("a\"(((())))")
Yeah Alessi - iterating a string makes sence to be faster.(setq alist '(((((("A")))((((((((((((((((((((((("B" ("C"))))))))))))))))))))))))("C")))) ); -> 26
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. :)
My version works only on one long string:
Comando: (vl-princ-to-string alist)
"((((((A))) (((((((((((((((((((((((B (C)))))))))))))))))))))))) (C))))"
Code: [Select]'("a\"(((())))")
Comando: (ALE_List_NestedLevel2 '("a\"(((())))"))Code: [Select]'("a\"(((())))")
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
(NestLvl '((1 . 2)))
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 #13Code: [Select](NestLvl '((1 . 2)))
Alessi,For #13 see #23...
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])
(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>
>>> Marcofound one in a book https://issuu.com/enelf/docs/lisp1/382
section 3.3 number 2
it's a bit different but looks good
; глубина = depth
(defun depth (х)
(cond
( (atom x) 1)
(t (max_ (+ 1 (depth (car x))) (depth (cdr x))) )
)
)
(defun max_ (х у) ; встроенная функция MAX
(if (> x y) x y)
)
(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)
)
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
(defun depth (x)
(cond ((atom x) -1)
(t (max (1+ (depth (car x))) (depth (cdr x))))
)
)
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 insteadCode: [Select](defun depth (x)
(cond ((atom x) -1)
(t (max (1+ (depth (car x))) (depth (cdr x))))
)
)
(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>
(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
)
(ALE_List_NestedLevel4 '("\\\""))
...maybe it's time to throw the sponge...Code: [Select](ALE_List_NestedLevel4 '("\\\""))