How to call a list for update multiple times until a condition is fulfilled in Netlogo

105 views Asked by At

I am new to Netlogo and still learning , what i want to do is call a list after an update is done and do another update to it until a condition is reached , if a have a list

let xy [[-2 6][-1 6][0 6][-1 6][-2 6][1 5][2 5][-3 9][-4 9][-5 9][-6 9][-3 9]] 
let same true

I am trying to remove from the list the first sublist between two same elements [-2 6 ][-1 6][0 6][-1 6][-2 6] then i also want to remove the sublist between the other two same elements [-3 9][-4 9][-5 9][-6 9][-3 9] until there are no more elements that repeat in this case result should be [[1 5] [2 5]] and i control this list after removing the sublists with the condition:

if length xy = length remove-duplicates xy [ set same false ]

I have already done the removal code below and it removes the first sublist but i might have a lot of sublists , and i want to know how after one removal can i get again the updated list (in these case i should somehow take the final-list in the code) and control it again with these condition. I was thinking to do a to-report procedure and a while loop , for example (maybe i am wrong with this)

 to-report update-list [list]

 while [same != false ] 

 [ ; do the removal stuff 
   set list-xy item POSITION (FIRST MODES xy) xy xy
   let first-pos POSITION (FIRST MODES xy)  xy 
   set list-temp remove-item first-pos xy 
   set sec-pos position list-xy list-temp + 1
   set sublist-1 sublist xy 0 first-pos 
   set sublist-2 sublist xy sec-pos length xy
   set final-list sentence sublist-1 sublist-2
   set xy final-list



; the condition if i don't have any duplicates the size of two lists should have the same size , no duplicates

if length xy = length remove-duplicates xy 

   [ set same false ]


  ] 


 report update-list xy 

I am not sure what to report at the end of the procedure and how to recall the list again, so i can remove all those sublists.

Any ideas are appreciated, thank you

2

There are 2 answers

0
Seth Tisue On BEST ANSWER

This is easiest to solve using recursion:

to-report remove-fenced-sublists [xs]
  if empty? xs
    [ report [] ]
  let pos position first xs butfirst xs
  if not is-number? pos
    [ report fput first xs remove-fenced-sublists butfirst xs ]
  report remove-fenced-sublists sublist xs (pos + 2) length xs
end

Sample run:

observer> show remove-fenced-sublists [[-2 6][-1 6][0 6][-1 6][-2 6][1 5][2 5][-3 9][-4 9][-5 9][-6 9][-3 9]]
observer: [[1 5] [2 5]]
0
Alan On

If I understand your goal, your core need can be captured by building up a new list item by item but trimming it whenever a duplicate appears. For a single new item this is:

to-report trim-or-grow [#list #item]
  let _i position #item #list
  report ifelse-value (_i != false) [sublist #list 0 _i] [lput #item #list]
end

You can then reduce with this reporter:

to test
  let xy [[-2 6][-1 6][0 6][-1 6][-2 6][1 5][2 5][-3 9][-4 9][-5 9][-6 9][-3 9]]
  print reduce trim-or-grow fput [] xy
end