list challenge

list challenge

Moshe-A
Mentor Mentor
1,726 Views
36 Replies
Message 1 of 37

list challenge

Moshe-A
Mentor
Mentor

Hi experts,

 

say i have this sorted list:

'(0 1 4 5 9)

 

looking for an efficient function to return:

'(0 1 nil nil 4 5 nil nil nil 9)

 

e.g add a 'nil' as a placeholder for any missing number.

 

thanks in advance

Moshe

 

0 Likes
Accepted solutions (1)
1,727 Views
36 Replies
Replies (36)
Message 2 of 37

Kent1Cooper
Consultant
Consultant

Always integers only, and always in order?  Would there ever be more than one of the same integer value included?

Kent Cooper, AIA
0 Likes
Message 3 of 37

john.uhden
Mentor
Mentor

@Moshe-A 

This is the first thing that came to mind:

(defun fillnil (old / i new)
  (setq i (1+ (last old)))
  (while (> (setq i (1- i)) -1)
    (if (vl-position i old)
      (setq new (cons i new))
      (setq new (cons nil new))
    )
  )
)

John F. Uhden

0 Likes
Message 4 of 37

Kent1Cooper
Consultant
Consultant

I'm on a no-AutoCAD computer, so I can't check, but does that assume their original list is always going to start with 0, or that if it doesn't, they want all the slots from 0 up covered?  That is, given a list like:

  '(12 14 15 17)

wouldn't it return:
  (nil nil nil nil nil nil nil nil nil nil nil nil 12 nil 14 15 nil 17)

?  And what if there are any negative numbers?

 

@Moshe-A , do you want only the positions within the range of your original numbers?  If so, and for a list of integers only [including negative], maybe something like [untested]:

 

(defun nilgaps (lst / n result)

  (repeat (- (setq n (1+ (apply 'max lst))) (apply 'min lst))

    (setq result (cons (if (member (setq n (1- n)) lst) n nil) result))

  )

)

 

That [if it works...] would not require a list already in numerical order, but would sort the list in the process.  However, it would not account properly for multiple instances of the same integer in the source list, if that's a possibility.

 

EDIT:  Tested now, and it works for me, including the self-sorting and negative-number aspects.

Kent Cooper, AIA
Message 5 of 37

hak_vz
Advisor
Advisor
(defun hak_vz:fillnil (lst / ret a b)
	(setq lst (vl-sort lst '<) a (1-(car lst) ) b (last lst) ret (list))
	(while (<= (setq a (1+ a)) b)(if (not (member a lst)) (setq ret (append ret (list nil)))(setq ret (append ret (list a)))))
)
Command: (HAK_VZ:FILLNIL '(3 5 8))
(3 nil 5 nil nil 8)
Command: (HAK_VZ:FILLNIL '(6 2 7 2))
(2 nil nil nil 6 7)

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 6 of 37

Sea-Haven
Mentor
Mentor

Nice one to add to Challenges (theswamp.org)

0 Likes
Message 7 of 37

Moshe-A
Mentor
Mentor
hi guys

thank you all for your help, i'm now at work will be checking your help tonight.

Moshe
0 Likes
Message 8 of 37

ВeekeeCZ
Consultant
Consultant
Accepted solution
(defun :niltomissing (o / n i)
  (repeat (setq i (1+ (last o)))
    (setq n (cons (car (member (setq i (1- i)) o)) n))))
Message 9 of 37

john.uhden
Mentor
Mentor

@ВeekeeCZ 

I saw what you did there... shorten old to o and new to n so it appears more compact.  <snicker>

Seriously, that's a great use of member.  🙂

But couldn't you have shortened the function name? :n2m, maybe?  Or maybe just :.

John F. Uhden

0 Likes
Message 10 of 37

Kent1Cooper
Consultant
Consultant

That has the same issue as @john.uhden 's if the list doesn't include 0 -- it reaches down that far anyway:

 

Command: (:niltomissing '(8 10 15 17))
(nil nil nil nil nil nil nil nil 8 nil 10 nil nil nil nil 15 nil 17)

 

And it doesn't like negative numbers [it only reaches down as far as 0]:

 

Command: (:niltomissing '(-3 0 2))
(0 nil 2)

 

Mine is made to handle those situations:

Command: (nilgaps '(8 10 15 17))
(8 nil 10 nil nil nil nil 15 nil 17)

 

Command: (nilgaps '(-3 0 2))
(-3 nil nil 0 nil 2)

 

And sorts for itself -- you can give it an unsorted list:

Command: (nilgaps '(-95 -92 -97))
(-97 nil -95 nil nil -92)

Kent Cooper, AIA
0 Likes
Message 11 of 37

ВeekeeCZ
Consultant
Consultant

@Kent1Cooper wrote:

That has the same issue as @john.uhden 's if the list doesn't include 0 -- it reaches down that far anyway:

 

Command: (:niltomissing '(8 10 15 17))
(nil nil nil nil nil nil nil nil 8 nil 10 nil nil nil nil 15 nil 17)

 

And it doesn't like negative numbers [it only reaches down as far as 0]:

....


 

You know that it's simple to fix. 

(defun :niltomissing (o / n i)
  (repeat (- (setq i (1+ (last o))) (car o))
    (setq n (cons (car (member (setq i (1- i)) o)) n))))

 

Btw, your result needs to be localized.

Message 12 of 37

john.uhden
Mentor
Mentor

Hers was almost perfect.

Here's a little tweak for #s out of order...

(defun :n2m (o / n i)

(repeat (- (setq i (1+ (apply 'max o))) (apply 'min o))
(setq n (cons (car (member (setq i (1- i)) o)) n))))

John F. Uhden

Message 13 of 37

ВeekeeCZ
Consultant
Consultant

@john.uhden wrote:

Thank you, @ВeekeeCZ 

I was about to do that for you.


Thank you, John. Also, I prefer the name to remain descriptive. 

0 Likes
Message 14 of 37

Moshe-A
Mentor
Mentor

@ВeekeeCZ ,

 

Your version wins my reward 😀 

 

thank you all other for your effort

 

 Moshe

 

0 Likes
Message 15 of 37

hak_vz
Advisor
Advisor

I have written my code at 2 am. I left my computer turned on, checked the forum and stayed to write the code.

 

What I didn't get from @Moshe-A : do list has to start with 0 or with smallest list member? Are there duplicates and negative values? Code can be optimized and we have here some nice solutions.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 16 of 37

Kent1Cooper
Consultant
Consultant

@ВeekeeCZ wrote:
...

You know that it's simple to fix. 

(defun :niltomissing (o / n i)
  (repeat (- (setq i (1+ (last o))) (car o))
    (setq n (cons (car (member (setq i (1- i)) o)) n))))

Btw, your result needs to be localized.


That's the same approach to the range of values as mine, except for requiring the list to be sorted in order [which maybe it always will be -- we haven't heard back from the OP on that].

 

And yes, I realized at the time of my last Reply that the result should be localized, and had put that in.  But that may not be true if such a function becomes incorporated into a larger operation, depending on what that is, what use is to be made of the result, and whether it will be needed to feed into something other function or routine and maybe should be localized there instead.

Kent Cooper, AIA
0 Likes
Message 17 of 37

john.uhden
Mentor
Mentor

@Kent1Cooper 

That's understandable, but weak.

Maybe not everyone does, but you know quite well that the result can be local and returned to the calling code.

John F. Uhden

0 Likes
Message 18 of 37

john.kaulB9QW2
Advocate
Advocate

A link was posted to this thread at TheSwamp and we decided the initial criteria wasn't fun enough for us so we've added--out of scope--criteria:

 

_$ (fillnill '(0 1 -3 4 6 9 5))
(0 1 nil nil nil -3 nil nil nil nil nil nil 4 nil 6 nil nil 9 nil nil nil 5)

 

I haven't personally had an opportunity to implement this last part but I thought I'd share in case anyone here wanted to play too.

 

Take care.

another swamper
0 Likes
Message 19 of 37

john.uhden
Mentor
Mentor

 

@john.kaulB9QW2 

Yeah, well JohnBoy, that version vacuums.

You should have read further down the thread.  But I have no pride, so it's okay as long as it's for fun.

Meanwhile...

(defun :n2m (o / n i)
(repeat (- (setq i (1+ (apply 'max o))) (apply 'min o))
(setq n (cons (car (member (setq i (1- i)) o)) n))))
:N2M

Command: (:n2m '(0 1 -3 4 6 9 5))
(-3 nil nil 0 1 nil nil 4 5 6 nil nil 9)

John F. Uhden

0 Likes
Message 20 of 37

john.kaulB9QW2
Advocate
Advocate

Please call me by my name (John); I do not like 'JohnBoy'. I refer to people by their screen or real name only.

 

I'm not sure what you mean by `vacuums` or why it wouldn't be okay (and/or `pride' because of what?).

 

Looking at your output I noticed that `:n2m' resorts the list? -i.e. -3 and 5 was moved.

(:n2m '(0 1 -3 4 6 9 5))
(-3 nil nil 0 1 nil nil 4 5 6 nil nil 9)

 

I have only had an opportunity to take a quick stab at the `vacuum` version (if that's what you want to call it)  but I failed first time around so I can only comment a little on the concept. The OP said the list supplied was sorted already but that does not mean the list is sorted from least to greatest or vise versa; the list could be sorted for for any number of reasons or methods so in my opinion, it is a safer bet to assume the list order stays as is and the place-holders are placed in-between.

 

another swamper
0 Likes