Author Topic: [challenge] A03 : Find the number of elements of a list without using LENGTH  (Read 1896 times)

0 Members and 1 Guest are viewing this topic.

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Using only AutoLisp find the number of elements of a list without using LENGTH.
NOTE: The first element in the list is number 0.
NOTE: A NULL list should return NIL.

Example:
(my-count-list '(1 2 3 4 5 6 7))
> 6


EDIT: Added second note about returning NIL for NULL lists.
« Last Edit: December 22, 2021, 05:21:54 PM by John Kaul (Se7en) »
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12696
  • London, England
Code - Auto/Visual Lisp: [Select]
  1. (defun f1 ( l / n )
  2.     (setq n -1)
  3.     (while (setq n (1+ n) l (cdr l)))
  4.     n
  5. )

Lee Mac

  • Seagull
  • Posts: 12696
  • London, England
Assuming no duplicates:
Code - Auto/Visual Lisp: [Select]
  1. (defun f2 ( l )
  2.     (vl-position (last l) l)
  3. )

Lee Mac

  • Seagull
  • Posts: 12696
  • London, England
One more -
Code - Auto/Visual Lisp: [Select]
  1. (defun f3 ( l / n )
  2.     (setq n 0)
  3.     (while (cddddr l) (setq n (+ n 4) l (cddddr l)))
  4.     (while (setq l (cdr l)) (setq n (1+ n)))
  5.     n
  6. )

Stefan

  • Bull Frog
  • Posts: 303
Code - Auto/Visual Lisp: [Select]
  1. (defun my-count-list-stefOne (l)
  2.   (apply '+ (mapcar '(lambda (x) 1) (cdr l)))
  3. )

Edit: why length -1 ?
« Last Edit: December 17, 2021, 11:06:41 AM by Stefan »

Tharwat

  • Swamp Rat
  • Posts: 667
  • Hypersensitive
Code - Auto/Visual Lisp: [Select]
  1. (defun Length_ (lst / rtn)
  2.   ((lambda (i)
  3.      (while (and (nth (setq i (1+ i)) lst) (setq rtn i)))
  4.    )
  5.     -1
  6.   )
  7.   rtn
  8. )
  9.  


Stefan

  • Bull Frog
  • Posts: 303
Code - Auto/Visual Lisp: [Select]
  1. (defun my-count-list-stef2 (l / i)
  2.   (setq i -1)
  3.   (foreach x l
  4.     (setq i (1+ i))
  5.   )
  6. )
« Last Edit: December 17, 2021, 11:06:59 AM by Stefan »

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Assuming no duplicates:
Code - Auto/Visual Lisp: [Select]
  1. (defun f2 ( l )
  2.     (vl-position (last l) l)
  3. )
Sorry, this is disqualified; uses VisualLisp.

Everyone else uses either the name I give or another descriptive name. Please remember these challenges are an opportunity for everyone to learn as well. While I can use my editor to make global changes (to better follow the code posted like this, instead of trying to pick out one letter variables and names) others--who use the old VLIDE, notepad, or other editors--do not have that ability. Functions that use FOO, F, BAR, L, l, etc. is obfuscated code and a bad habit. Please do not do this.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Similar to one already posted but I had this typed up already (I am working on getting future challenges created and am currently working on challenge A18).

Code - Auto/Visual Lisp: [Select]
  1. (defun my-count-list-se7en (aList / cntr)
  2.   (if (null aList)
  3.     '()
  4.   (setq cntr -1))
  5.   (mapcar
  6.     '(lambda (x)
  7.        (set 'cntr (1+ cntr)))
  8.     aList)
  9.   cntr
  10.   )
(my-count-list-se7en '(1 2 3 4 5 6 7))
(my-count-list-se7en nil)


EDIT: Revised (added IF statement) to account for NULL lists.
« Last Edit: December 17, 2021, 10:13:28 AM by John Kaul (Se7en) »
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

gile

  • Water Moccasin
  • Posts: 2392
  • Marseille, France
Code - Auto/Visual Lisp: [Select]
  1. (defun len (l)
  2.   (if l
  3.     (1+ (len (cdr l)))
  4.     0
  5.   )
  6. )
Speaking English as a French Frog

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Code - Auto/Visual Lisp: [Select]
  1. (defun lst_length (l)
  2.   (apply '+ (mapcar '(lambda (x) 1) (cdr l)))
  3. )

Edit: why length -1 ?

I like that!

Code - Auto/Visual Lisp: [Select]
  1. (defun len (l)
  2.   (if l
  3.     (1+ (len (cdr l)))
  4.     0
  5.   )
  6. )

That one too!
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

Stefan

  • Bull Frog
  • Posts: 303
John, please clarify what is expected on an empty list.
I guess, if '(1 2 3 4 5 6 7) -> 6, then '(1) -> 0 and '() - > nil

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
I'd say nil as well. Good call.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

gile

  • Water Moccasin
  • Posts: 2392
  • Marseille, France
John, please clarify what is expected on an empty list.
I guess, if '(1 2 3 4 5 6 7) -> 6, then '(1) -> 0 and '() - > nil
The 'native' length function does not work this way.
(length  '(1 2 3 4 5 6 7)) -> 7
(length  '(1)) - > 1
(length  '()) -> 0
Speaking English as a French Frog

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Acknowledged but if you are using/building this function in a larger procedure you may want to control flow via an conditional like IF or COND ?easier?.
(if (my-count-list aList) ...
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

ronjonp

  • Needs a day job
  • Posts: 7437
John, please clarify what is expected on an empty list.
I guess, if '(1 2 3 4 5 6 7) -> 6, then '(1) -> 0 and '() - > nil
The 'native' length function does not work this way.
(length  '(1 2 3 4 5 6 7)) -> 7
(length  '(1)) - > 1
(length  '()) -> 0
Late to the party but I'd say it should return 0 rather than nil if you're mimicking the length function.
Code - Auto/Visual Lisp: [Select]
  1. (length nil)
  2. 0
« Last Edit: December 17, 2021, 12:13:18 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2022

Custom Build PC

Stefan

  • Bull Frog
  • Posts: 303
John, please clarify what is expected on an empty list.
I guess, if '(1 2 3 4 5 6 7) -> 6, then '(1) -> 0 and '() - > nil
The 'native' length function does not work this way.
(length  '(1 2 3 4 5 6 7)) -> 7
(length  '(1)) - > 1
(length  '()) -> 0

I agree. See Edit note in my first post. John decided to have it that way.

Acknowledged but if you are using/building this function in a larger procedure you may want to control flow via an conditional like IF or COND ?easier?.
(if (my-count-list aList) ...
Well, I play for the fun, but I don't see where this function might be used
(if (my-count-list aList) ... is similar to (if aList.


JohnK

  • Administrator
  • Seagull
  • Posts: 10140
I agree Stefan but this will come up again in later challenges--some of which are actually more useful functions-. I need to determine how many and we can just make this one return nil and let the later challenges error out or return what the programmer wants.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

Stefan

  • Bull Frog
  • Posts: 303
Don't worry John, it is really fun and I appreciate your initiative.

Here is another

Code - Auto/Visual Lisp: [Select]
  1. (defun my-count-list-stef3 (l)
  2.   (cond
  3.     ((cdr l) (1+ (my-count-list-stef3 (cdr l))))
  4.     (l 0)
  5.   )
  6. )
« Last Edit: December 17, 2021, 11:08:21 AM by Stefan »

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
No problem. I have a file with about 18/19 challenges typed up so far and I keep ACCORECONSOLE running on the side so I can test out any solution I type up. Works good but it's a lot of work. :)
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

apricot125

  • Mosquito
  • Posts: 13
Code: [Select]
(defun _length (lst)
  (cond ((not (cdr lst)) 0)
        (t (1+ (_length (cdr lst))))
  )
)

dexus

  • Newt
  • Posts: 75
Here is a different solution:
Code - Auto/Visual Lisp: [Select]
  1. (defun length-dexus (lst / ret)
  2.   (if (vl-consp lst)
  3.     (apply '+ (cdr (mapcar '(lambda (x) 1) lst)))
  4.   )
  5. )


Unless if vl-consp is not allowed, it would be something like this:
Code - Auto/Visual Lisp: [Select]
  1. (defun length-dexus (lst / ret)
  2.   (setq ret (apply '+ (mapcar '(lambda (x) 1) lst)))
  3.   (if (/= ret 0) (1- ret))
  4. )
« Last Edit: December 20, 2021, 07:20:01 AM by dexus »

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Code: [Select]
(defun _length (lst)
  (cond ((not (cdr lst)) 0)
        (t (1+ (_length (cdr lst))))
  )
)
I like that, apricot125.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Here is a different solution:
Code - Auto/Visual Lisp: [Select]
  1. (defun length-dexus (lst / ret)
  2.   (if (vl-consp lst)
  3.     (apply '+ (cdr (mapcar '(lambda (x) 1) lst)))
  4.   )
  5. )


Unless if vl-consp is not allowed, it would be something like this:
Code - Auto/Visual Lisp: [Select]
  1. (defun length-dexus (lst / ret)
  2.   (setq ret (apply '+ (mapcar '(lambda (x) 1) lst)))
  3.   (if (/= ret 0) (1- ret))
  4. )

Correct. VL-CONSP--or anything that starts with VL--is not allowed and would be disqualified.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

dexus

  • Newt
  • Posts: 75
[...]

Correct. VL-CONSP--or anything that starts with VL--is not allowed and would be disqualified.
I see, well, all vl-consp does is check if the type is a list, so this should do exactly the same thing:
Code - Auto/Visual Lisp: [Select]
  1. (defun length-dexus (lst / ret)
  2.   (if (eq (type lst) 'LIST)
  3.     (apply '+ (cdr (mapcar '(lambda (x) 1) lst)))
  4.   )
  5. )

Stefan

  • Bull Frog
  • Posts: 303
Here is a different solution:
Code - Auto/Visual Lisp: [Select]
  1. (defun length-dexus (lst / ret)
  2.   (if (vl-consp lst)
  3.     (apply '+ (cdr (mapcar '(lambda (x) 1) lst)))
  4.   )
  5. )

Not quite different...

dexus

  • Newt
  • Posts: 75
Here is a different solution:
Code - Auto/Visual Lisp: [Select]
  1. (defun length-dexus (lst / ret)
  2.   (if (vl-consp lst)
  3.     (apply '+ (cdr (mapcar '(lambda (x) 1) lst)))
  4.   )
  5. )

Not quite different...
Whoops, I didn't see that one, sorry about that.
« Last Edit: December 21, 2021, 05:29:36 AM by dexus »

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1314
  • Marco
>>> EDIT for null list (IMHO I prefer results LENGHT like…)

Code: [Select]
(defun ALE_Length (l / p c)
  (and
    l
    (setq c 0)
    (while l
      (cond
        ( (setq p (cddddr (cddddr (cddddr l)))) (setq l p  c (+ c 12)) )
        ( (setq p (cddddr (cddddr (cdddr  l)))) (setq l p  c (+ c 11)) )
        ( (setq p (cddddr (cddddr (cddr   l)))) (setq l p  c (+ c 10)) )
        ( (setq p (cddddr (cddddr (cdr    l)))) (setq l p  c (+ c  9)) )
        ( (setq p (cddddr (cddddr         l)))  (setq l p  c (+ c  8)) )
        ( (setq p (cddddr (cdddr          l)))  (setq l p  c (+ c  7)) )
        ( (setq p (cddddr (cddr           l)))  (setq l p  c (+ c  6)) )
        ( (setq p (cddddr (cdr            l)))  (setq l p  c (+ c  5)) )
        ( (setq p (cddddr                 l))   (setq l p  c (+ c  4)) )
        ( (setq p (cdddr                  l))   (setq l p  c (+ c  3)) )
        ( (setq p (cddr                   l))   (setq l p  c (+ c  2)) )
        ( (setq p (cdr                    l))   (setq l p  c (+ c  1)) )
        ( (setq l nil) )
      )
    )
  )
  c
)

Code: [Select]
Old version:
(defun ALE_LengthO (l / p c)
  (setq c 0)
  (while l
    (cond
      ( (setq p (cddddr (cddddr (cddddr l)))) (setq l p  c (+ c 12)) )
      ( (setq p (cddddr (cddddr (cdddr  l)))) (setq l p  c (+ c 11)) )
      ( (setq p (cddddr (cddddr (cddr   l)))) (setq l p  c (+ c 10)) )
      ( (setq p (cddddr (cddddr (cdr    l)))) (setq l p  c (+ c  9)) )
      ( (setq p (cddddr (cddddr         l)))  (setq l p  c (+ c  8)) )
      ( (setq p (cddddr (cdddr          l)))  (setq l p  c (+ c  7)) )
      ( (setq p (cddddr (cddr           l)))  (setq l p  c (+ c  6)) )
      ( (setq p (cddddr (cdr            l)))  (setq l p  c (+ c  5)) )
      ( (setq p (cddddr                 l))   (setq l p  c (+ c  4)) )
      ( (setq p (cdddr                  l))   (setq l p  c (+ c  3)) )
      ( (setq p (cddr                   l))   (setq l p  c (+ c  2)) )
      ( (setq p (cdr                    l))   (setq l p  c (+ c  1)) )
      ( (setq l nil) )
    )
  )
  c
)

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1314
  • Marco
Code: [Select]
-- Benchmark utility: In memory of Michael Puckett ---

List length: 7
Elapsed milliseconds / relative speed for 131072 iteration(s):
    (LEE_F3 SMALLLIST)....................1500 / 1.86 <fastest>
    (LEE_F1 SMALLLIST)....................1547 / 1.81
    (GILE_LEN SMALLLIST)..................1578 / 1.77
    (MY-COUNT-LIST-STEF3 SMALLLIST).......1640 / 1.71
    (TH_LENGTH_ SMALLLIST)................1672 / 1.67
    (APR_LENGTH SMALLLIST)................1687 / 1.66
    (ALE_LENGTH SMALLLIST)................1906 / 1.47
    (MY-COUNT-LIST-SE7EN SMALLLIST).......2281 / 1.23
    (MY-COUNT-LIST-STEFONE SMALLLIST).....2734 / 1.02
    (LENGTH-DEXUS SMALLLIST)..............2797 / 1 <slowest>

List length: 82
Elapsed milliseconds / relative speed for 65536 iteration(s):
    (ALE_LENGTH MEDIUMLIST)................1063 / 2.45 <fastest>
    (LEE_F3 MEDIUMLIST)....................1094 / 2.38
    (LEE_F1 MEDIUMLIST)....................1656 / 1.58
    (GILE_LEN MEDIUMLIST)..................1765 / 1.48
    (MY-COUNT-LIST-STEFONE MEDIUMLIST).....1937 / 1.35
    (LENGTH-DEXUS MEDIUMLIST)..............1938 / 1.35
    (MY-COUNT-LIST-STEF3 MEDIUMLIST).......2172 / 1.2
    (MY-COUNT-LIST-SE7EN MEDIUMLIST).......2344 / 1.11
    (TH_LENGTH_ MEDIUMLIST)................2594 / 1.01
    (APR_LENGTH MEDIUMLIST)................2609 / 1 <slowest>

List length: 4100
Elapsed milliseconds / relative speed for 8192 iteration(s):
    (ALE_LENGTH BIGLIST)................1828 / 4 <fastest>
    (LEE_F3 BIGLIST)....................3094 / 2.36
    (LENGTH-DEXUS BIGLIST)..............3938 / 1.86
    (MY-COUNT-LIST-STEFONE BIGLIST).....3969 / 1.84
    (LEE_F1 BIGLIST)....................6688 / 1.09
    (GILE_LEN BIGLIST)..................7312 / 1 <slowest>

List length: 4198400
Elapsed milliseconds / relative speed for 8 iteration(s):
    (ALE_LENGTH ULTRALIST)................1015 / 3.71 <fastest>
    (LEE_F3 ULTRALIST)....................2344 / 1.61
    (LENGTH-DEXUS ULTRALIST)..............3687 / 1.02
    (MY-COUNT-LIST-STEFONE ULTRALIST).....3765 / 1 <slowest>

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1314
  • Marco
Code: [Select]
; "strange" version - length <= 100
(defun ALE_LengthNth (L)
  (nth 100 (append L
   '( 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80
      79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59
      58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38
      37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17
      16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    )
  )       )
)