I have two lists, both will always be the same length. The first is binary and says whether an agent will move this round, the second contains a set of agents that will need to do something, based on the first list. Something like:
list1 = [0 1 1 1 0]
list2 = [turtle-1 turtle-2 turtle-55 turtle-6 turtle-8]
My objective is to create a third list with only the active turtles in it. Accordingly this list will comprise: turtle-2 turtle-55 and turtle-6. What's the best way to do this?
Like this:
map last filter [first ? = 1] (map list list1 list2)
sample run:
observer> crt 10
observer> set list1 [0 1 1 1 0]
observer> set list2 map turtle [1 2 5 6 8]
observer> show map last filter [first ? = 1] (map list list1 list2)
observer: [(turtle 2) (turtle 5) (turtle 6)]
I am not sure how you can do it with map (Map is cleaner and more efficient) but with foreach you can do it as follow :
to test-lists
let list3 []
foreach list2 [
if (item (position ? list2) list1 = 1)[
set list3 lput ? list3
]
]
print (word "List1 is " list1)
print (word "List2 is " list2)
print (word "List3 is " list3)
end
This is the output:
List1 is [0 1 1 1 0]
List2 is [(turtle 1) (turtle 2) (turtle 55) (turtle 6) (turtle 8)]
List3 is [(turtle 2) (turtle 55) (turtle 6)]
Related
I am looking for a solution in Netlogo to get a value from a list of lists with the minimum pair value.
((value1,value2)(value1,value2)...)
As an example I have a list:
ListofLists = ((2,3)(5,8)(1,9))
I want to select the list with the minimum first value. --> here (1,9) and write the second value out of it.
Goal: Get 9!
my try looks like this:
ListofLists = ((2,3)(5,8)(1,9))
let ChoosedList []
set ChoosedList min (item 0 ListofLists)
set ChoosedValue item 1 ChoosedList
Do you have a solution for this?
The easiest way to do this is to sort the list of lists by the first element of each sublist, then take the second element of the first sublist in the sorted list of lists. Here it is in stages:
let sorted-list sort-by [[a b] -> item 0 a < item 0 b] [[2 3] [5 8] [1 9]]
let ChoosedList first sorted-list
let ChoosedValue item 1 of ChoosedList
or, in one line,
let ChoosedValue item 1 first sort-by [[a b] -> item 0 a < item 0 b] [[2 3] [5 8] [1 9]]
sort-by is very useful for sorting lists of lists.
Came across this interesting implementation of Fibonacci generator in clojure. Bit difficult to understand the self-reference part. Any help on mental modelling this would be very useful.
(def fib-seq
(lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))
Macroexpanding (lazy-cat [0 1] (map + (rest fib-seq) fib-seq) leads to:
(concat (lazy-seq [0 1]) (lazy-seq (map + (rest fib-seq) fib-seq)))
(map + coll1 coll2) returns a new collection where the first item of the first list is added to the first item of the second list, the second item of the first list is added to the second item of the second list, and so on.
user> (map + [1 2 3 4] [1 2 3 4])
(2 4 6 8)
So we start with 0 and 1, and then we get the first of the rest of the fib-seq (1) to the first element of the fib-seq (0), this leads to 1. Then we get the next element of the fib-seq again, which is the 1 we just realized and add it to the second item of the fib-seq (1), which leads to 2, and so on.
So we lazily concat [0 1] to the result of summing the two collections after it shifted by 1:
[0 1] <+ concat>
[1 + 0
1 + 1
2 + 1
3 + 2
...]
user> (take 10 fib-seq)
(0 1 1 2 3 5 8 13 21 34)
Hope this helps.
Suppose I have a list of lists I want to filter. The list is such that, in each element, the first two strings are the contents
I want to keep, the third number is the number of times it should appear in the filtered list, and the
last element is the value of the list determining what particular combination appears.
The idea is to keep only the n most valuable items of each, where n is the third element of each list inside, and the value is
determined by the last entry, but also, if there are less combinations than the third item, keep as many as possible.
Thus, in the example below, I would like to have only the first "a", "b" combination, keep the first two "a" "c" ones,
and retain the last, (even though there is no further "a" "d" combinations in it):
I have been trying to use several combinations of filter and thought about ways to retain list elements,
without success for this particular problem.
to setup
let temp-example []
set temp-example [["a" "b" 1 5] ["a" "b" 1 3] ["a" "c" 2 4] ["a" "c" 2 2]
["a" "c" 2 1] ["a" "d" 4 1]]
end
Desired output is the following list:
[["a" "b" 1 5]["a" "c" 2 4]["a" "c" 2 2] ["a" "d" 4 1]]
I'm sure one of the heavyweights around here will chime in soon with a one-or-two line solution, but for now I think this does what you're after. With these reporters:
to-report multifilter [ list_ ]
; Get the content pairs
let content-pairs remove-duplicates map [ i -> sublist i 0 2 ] list_
; Reorganize list into sublists for each content pair
let by-content-pairs map [ i -> filter [ j -> sublist j 0 2 = i ] list_ ] content-pairs
; Sort the sublists
let sorted-by-value map [ i -> sort-with 3 i ] by-content-pairs
; Keep only first n items of each sublist,
report reduce sentence map [ i -> keep-n 2 i ] sorted-by-value
end
to-report sort-with [ ind lst ]
; Sort the sublists by one of their indexed values
report sort-by [ [ a b ] -> ( item ind a ) > ( item ind b ) ] lst
end
to-report keep-n [ ind lst ]
; Keep only as many values as are passed by ind, or the length
; of the list, whichever value is smaller
let n item ind first lst
if n > length lst [
set n length lst
]
report sublist lst 0 n
end
Call multifilter on a list with the format you've shown and you should get your desired output:
to filter-multi
let temp-example [
["a" "b" 1 5] ["a" "b" 1 3] ["a" "c" 2 1]
["a" "c" 2 4] ["a" "c" 2 2] ["a" "d" 4 1]
]
print multifilter temp-example
end
Output:
[[a b 1 5] [a c 2 4] [a c 2 2] [a d 4 1]]
Another example:
to filter-multi
let temp-example [
["a" "b" 1 31] ["a" "b" 1 15] ["a" "b" 1 -53] ["a" "b" 1 10] ["a" "b" 1 3000]
["a" "c" 2 1] ["a" "c" 2 4] ["a" "c" 2 2] ["a" "c" 2 -10] ["a" "c" 2 14] ["a" "c" 2 40]
["a" "d" 4 1] ["a" "d" 4 12]
]
print multifilter temp-example
end
Output:
[[a b 1 3000] [a c 2 40] [a c 2 14] [a d 4 12] [a d 4 1]]
I think this more or less answers it as well:
to-report frequency [an-item a-list]
report length (filter [ i -> i = an-item] a-list)
end
; Reporter to keep the n most valuable combinations
to-report take [n xs]
report sublist xs 0 min list n (length xs)
end
to go
set temp-1[]
set temp-2[]
set temp-3[]
set temp-4[]
foreach temp-example[[i] ->
set temp-1 lput (list item 0 i item 1 i) temp-1
set temp-2 lput item 2 i temp-2]
foreach temp-1[[j] ->
set temp-3 lput frequency j temp-1 temp-3
]
;First: obtain all existing combinations between the two letters:
foreach (range 0 (length temp-example)) [[j]->
ifelse item j temp-2 <= item j temp-3 [set temp-4 lput take (item j temp-2)
filter [i -> (list item 0 i item 1 i) = item j temp-1] temp-example temp-4];
[set temp-4 lput item j temp-example temp-4]; caso contrario, colocar so ate aos
item 2 j:
]
show remove-duplicates temp-4
end
I tried to do my first steps with "lambda" in Dr Racket. (Advanced language)
Everything was fine until I tried out the following piece of code:
(map (lambda (list1 list2)
[map list (foldr + 0 (map * list1 list2 ) ) ] )
(list 1 2 3 4 5)
(list 6 7 8 9 10)
)
I tried to adapt my code according to the Racket dokumentation as good as possible.
But I just don't get what's wrong here.
http://docs.racket-lang.org/reference/pairs.html#(def._((lib._racket/private/map..rkt)._map))
It should output a single list consisting of the droduct of the 2 input list elements with the same index.
Console output says:
map: 2nd argument must be a list, given 1
whereas 1 is always the first element of list1
Subconsciousness says I just messed with ( ) anywhere.
You seem to be misunderstanding what the arguments to the lambda mean in a map. The arguments to the lambda are not the lists, they are elements of the lists.
In a normal one-argument map it's not:
(map (lambda (list1)
....)
(list 1 2 3 4 5))
But actually:
(map (lambda (elem1) ; elem1 is an element of the list
....)
(list 1 2 3 4 5))
It's the same with two-argument map. The arguments to the lambda are elements of their respective lists:
(map (lambda (elem1 elem2) ; elem1 is an element of the first list, elem2 is an element of the second list
....)
(list 1 2 3 4 5)
(list 6 7 8 9 10))
In your example, the two lists are [Listof Number], so the arguments to the lambda are Number.
(map (lambda (elem1 elem2) ; elem1 : Number, elem2 : Number
; here you have two numbers, so you can multiply them,
; but `map`-ing over the numbers doesn't make sense
(* elem1 elem2))
(list 1 2 3 4 5) ; [Listof Number]
(list 6 7 8 9 10)) ; [Listof Number]
Does the Clojure library have a "drop-every" type function? Something that takes a lazy list and returns a list with every nth item dropped?
Can't quite work out how to make this.
cheers
Phil
(defn drop-every [n xs]
(lazy-seq
(if (seq xs)
(concat (take (dec n) xs)
(drop-every n (drop n xs))))))
Example:
(drop-every 2 [0 1 2 3 4 5])
;= (0 2 4)
(drop-every 3 [0 1 2 3 4 5 6 7 8])
;= (0 1 3 4 6 7)
As a side note, drop-nth would be a tempting name, as there is already a take-nth in clojure.core. However, take-nth always returns the first item and then every nth item after that, whereas the above version of drop-every drops every nth item beginning with the nth item of the original sequence. (A function dropping the first item and every nth item after the first would be straightforward to write in terms of the above.)
If the input list length is a multiple of n you can use the partition function:
(defn drop-every [n lst] (apply concat (map butlast (partition n lst))))
(take 5 (drop-every 3 (range)))
; (0 1 3 4 6)