finding member in nested lists netlogo - list

i'm trying to solve a problem in netlogo that has me stuck for a while now. i've got two lists (of turtles i've collaborated with and of "successful"/"unsuccessful" judgments). the two lists are mapped like so [[(turtle 10) "successful"] [(turtle 11) "unsuccessful"] with the following:
let general-history (map list collaborators my-success)
where the collaborators are the who numbers and my-success is a string (either "successful" or "unsuccessful")
now, i would like to check whether a turtle has, in its general-history list, at least one successful and one unsuccessful collaborator, to be able to proceed. this is where i've gotten to:
ifelse not empty? general-history and member? "successful " last general-history and member? "unsuccessful" last general-history
i know this is wrong because last here implies that i'll be looking only at the last list of general-history (i.e., [] [] [this one]). what i want it to do is assess whether there are at least two lists (one with "successful" as index 1 and one with "unsuccessful" as index 1) in the whole general-history nested list.
would foreach work better here or is it possible to still use member? but with some kind of element + list indexing? thank you very much for the help!

If I have understood your question correctly, you can use map to create a list of all the last items (success or not) and then apply member? to that list. Here is a complete model example that constructs some test data and the applies this approach.
to testme
clear-all
; create some test data
create-turtles 10
let collaborators sort n-of 3 turtles
let list-both (map list collaborators (list "yes" "no" "no"))
print list-both
; check condition
print member? "yes" map last list-both
end

Related

Prolog - split a list into lists of lists

The list to be split is a list of guests that attend a dinner. The dinner has three meals (appetizer, main, and dessert). The result of the type list of lists should be a list for each of the meals with the sub-lists showing the people who eat that meal together.
eg.:
Appetizer: [[Tick, Trick, Track],[Tic, Tac, Toe], [Jerry, Larry, Harry]]
Main: [[Tick, Tic, Jerry], [Trick, Tac, Larry],[Track, Toe, Harry]]
Dessert: [[Tick, Tac, Larry], [Trick, Toe, Harry], [Track, Tic, Jerry]]
The function I have to code:
make_dinner(?Starters, ?Main, ?Dessert, +List_of_Persons, +Group_size):-
Group size is the size of the groups (in the example above three)
I don't know how to approach this problem using prolog language. I can easily code this in Java, which I'm really good at. But the recursion and logic here are very confusing to me. There's no "return" argument, no "if" statement", just a bunch of commas :")
My idea was to:
find out how many groups I need (depends on group size and list length)
fill the appetizer list with the original order of the list. Count it off and split the list after every group size position to get the list of lists for an appetizer (the most intuitive way I think)
fill the first sub-list of the "main" list with the first element of the list, then the second element of the other sub-lists from the "appetizer" list. Fill the second sub-list with the second element of the first sub-list of "appetizer", then the third element of the next sub-lists in "appetizer", and so on and so forth.
If the number doesn't match (eg. list length 10 but group size 3), I will simply have one group that's smaller. No person eats twice with the same person.
Does my idea work in Prolog? Can I implement that logic?
I don't really know how to approach this task because I'm very new to Prolog. I will have the main function below, then I need a helper_function called get_number_of_groups to know how many elements go into each list. And I have one function to get the size of the list.
How do I make the starters, main, and dessert into a list of lists? I know about recursion but somehow I don't know where to go from here.
%make_rudi: main function
%return: starters, main, and dessert; each list of lists
make_rudi(Starters, Main, Dessert, List_of_Persons, Group_size):-
get_number_of_groups(List_of_Persons, Group_size, Number),
%get_number_of_groups(+List_of_Persons, +Group_size, ?Number)
%return: the number of groups I have for each meal
get_number_of_groups(List_of_Persons, Group_size, Number):-
Number is list_length(Xs, List_of_Persons)/Group_size.
%list_length(?Xs,+L)
%the length of the list
list_length(Xs,L) :-
list_length(Xs,0,L) .
list_length( \[\] , L , L ) .
list_length( \[\_|Xs\] , T , L ) :-
T1 is T+1 ,
list_length(Xs,T1,L).

How to select element from tuple by index in list?

I want to select elements from a list, [[1,2],[3,4],[5,6]] once the first, than the second, than again the first and so on.
I figured that i could use zip to add a counter in front of the pairs and use modulo to select the part, and now my list looks like this:
let a = [(0,[1,2]),(1,[3,4]),(2,[5,6]),(3,[7,8]),(4,[9,10])]
but how can I now select the elements?
the pseudocode would be
for each tuple in list:
first part of tuple is the selector, second part is the pair
if selector mod 2 : choose pair[0] else choose pair[1]
the output for the list a should be: 1,4,5,7,9
Perhaps:
> zipWith (!!) [[1,2],[3,4],[5,6],[7,8],[9,10]] (cycle [0,1])
[1,4,5,8,9]
If you know you're working with lists of length two inside, you should probably be using pairs instead.
> zipWith ($) (cycle [fst, snd]) [(1,2),(3,4),(5,6),(7,8),(9,10)]
[1,4,5,8,9]
I like #DanielWagner answer a lot. The first is so simple and effective. His second is a just a little harder to understand but simple, too. When theories are simple, it increases their veracity. Here is my sorry solution but it does use your structure. (Association lists are tuples. It was suggested you use tuples but for this, what you have and probably need is okay.)
a = [(0,[1,2]),(1,[3,4]),(2,[5,6]),(3,[7,8]),(4,[9,10])]
[if even i then x else y | (i,(x:y:z)) <- a]
[1,4,5,8,9]

Netlogo: delete list content

How do I delete the content of a list in Netlogo?
This is a tuned-down version of my code to function as an example:
to calculate_SN
ask turtles [
set subjective_norm_list []
set subjective_norm_list [1 2 3 4 5]
set subjective_norm ( sum subjective_norm_list / length subjective_norm_list)
*delete content of subjective_norm_list so that it is empty again*
end
The part between asterisks I don't know.
Based on your shared code so far, you should take a different approach: create a function.
to-report subjective-norm [#lst]
report (sum #lst) / (length #lst)
end
It is unclear that you will ever need to assign a variable name to your list. You may be able to use it upon creation and then forget about it. (It will be garbage collected.)
If you want subjective_norm_list to be an empty list, you can set it to an empty list, just like you did when you initialized it the first time around:
set subjective_norm_list []
Note that, technically, NetLogo lists are immutable, so you're not deleting the elements in the list: you're just creating a new list with no elements in it and assigning it to the same variable. But for all intents and purposes, it's the same: subjective_norm_list is empty again.

How to implement a numerical formula across the items in a netlogo list

I have to do some operations in netlogo using Lists. While i can do simple tasks with them i am not yet proficient enough to code my current requirements.
I have a scenario where turtles have variables called Current-Age and Previous-Age. And turtles can be born and die if they don't meet a certain threshold.
I want to implement the following formula for each patch.
Best-list = (-1/Previous-Age) * (Distance between Patch & Turtle) for all the turtles
Best = Min [ Best-list]
I know the steps involved but have been unsuccessful in coding them. Following are the steps:
Create a list with all the current turtles that are alive
Create a second list which contains the Previous-Age
Create a third list with the distance between an individual patch and each of the live turtles
Then create another list with the output from the the Best-List formula for all the turtles in the list
Finally find the Min value in the list and store the name/who# of turtle with the minimum value in a separate variable called Best-Turtle
This is the code that i tried but didn't work.
set turtle-list (list turtles)
set turtle-age-list n-values length(turtle-list) [0]
set turtle-patch-dist-list n-values length(turtle-list) [0]
set best-list n-values length(turtle-list) [0]
ask patches[
foreach turtle-list(
set turtle-age-list replace-item ?1 turtle-age-list Previous-Age of turtles with [turtle= ?1]
)
]
I couldn't proceed to the next steps since the above code itself was not correct.
Would appreciate help with the code, thanks in advance.
Regards
First, lists are probably not the simplest way to do this. However, if you must use lists for some reason, I think what you're asking for is possible. I'm not exactly sure what you mean with best- are you trying to have each patch assess which turtle is the best turtle for that patch, and store that variable in a global list? I'm going to assume that's what you mean, but if I'm misunderstanding I think you can adapt what I do here to what you need.
First, any list passed to foreach must be the same length. So, since you mean to do this per-patch, make sure that every patch calls the procedure of list creation, not just for checking the lists. Next, review the dictionary for n-values- the syntax for the reporter means you need to use the reporter you're trying to receive- using n-values length(turtle-list) [0] will just give you a list of zeroes that is the same length as the number of turtles.
So each patch needs to create these lists- make sure you either define the patches-own for the list variables, or just use let to define the lists inside the procedure. You would need a list of ordered turtles, their previous ages, and the distance from the patch calling the procedure to each turtle. Next, you can create a list that generates a value according to your formula. Then, you can use the position primitive to find the location of the minimum value in your formula-generated list and use that to index the turtle with that value.
It might look something like
to numerical
set best-turtle []
ask patches [
let turtle-list (sort turtles) ;;; list of sorted turtles
let turtle-prev-age-list n-values length(turtle-list) [ [i] -> [pre_age] of turtle i ] ;;; list of previous ages of turtles, in same order as above
let turtle-patch-dist n-values length(turtle-list) [ [i] -> distance turtle i ] ;;; list of distance from this patch to each turtle, in same order
set best-list n-values length(turtle-list) [ [i] -> ( ( -1 / ( item i turtle-prev-age-list ) ) * ( item i turtle-patch-dist ) ) ] ;;; list of calculated values for each turtle
let best-position position (min best-list) best-list ;;; gets the index of minimum value
set best-turtle lput item best-position turtle-list best-turtle ;;; adds the best turtle for this patch to the global list of best turtles
]
end
The above procedure assumes that your turtles have a pre_age variable, patches have a best-list variable, and the list of each patches 'best turtle' is held in the global variable best-turtle. From there, you can use foreach to ask turtles in the list to do something. Note that if a turtle's previous age is 0, you will get a divide by zero error.
turtles-own [age previous-age]
to-report evalfrom [_patch]
report (- distance _patch) / previous-age
end
to test
ca
crt 25 [
set age (10 + random 75)
set previous-age age - random 10
]
print min-one-of turtles [evalfrom (patch 0 0)]
end

Haskell - get n number of lists from a list of lists

Hey guys so I'm trying and get the n number of lists from a list of lists. I was wondering if there is a method in haskell that works similar to the "take" and "drop" method but instead if would work in my situation. For example:
Input = [ [1,2,3,4], [5,6,7,8], [9,1,2,3], [4,5,6,7], [8,9,1,2], [3,4,5,6] ]
I want to be able to take the first 3 elements from this list of lists and end up with something like this:
Output = [ [1,2,3,4], [5,6,7,8], [9,1,2,3]]
I also want to be able to drop the first 3 elements from this list of lists and end up with something like this:
Output = [[4,5,6,7], [8,9,1,2], [3,4,5,6]]
Is it possible to do something like this in haskell.? Can anyone point me into the right direction on how to tackle this problem. Thanks in advance.
take and drop do exactly that. They work the same for all element types, even if the element type is a list type.
Prelude> take 3 [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18,19,20]]
[[1,2,3,4],[5,6,7,8],[9,10,11,12]]
Prelude> drop 3 [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18,19,20]]
[[13,14,15,16],[17,18,19,20]]