NetLogo nested list items to character seperated string - netlogo

I have a triple nested list:
[
[
[a b]
[c d]
...
]
[
[e f]
[g h]
...
]
]
I want a string with the format a,c,... respectively e,g,..
My current approach is to first make a new list with as much items as the first nested list has and add the first items of the lists within said list.
Afterwards then new list is reduced:
let nl ( n-values ( length ( item 0 list) ) [ i -> ( item 0 ( item i ( item 0 list)) ) ] )
reduce [ [a b] -> (word a "," b) ] nl
Is there a better way to do this, as in this approach it is very difficult to maintain the overview of the "denesting" of the list.

Assuming your list looks like:
let a ( list ( list [ "a" "b" ] [ "c" "d" ] ) ( list [ "e" "f" ] [ "g" "h" ] ) )
I'm not sure that this makes it easier to keep track of the denesting, but you could nest a map within another to get the order you want:
print map [ x -> map [ y -> item 0 y ] x ] a
If you want it as a list of strings with commas, I like the csv:to-row primitive from the csv extension:
print map [ x -> csv:to-row map [ y -> item 0 y ] x ] a
Again, not sure that it's more straightforward but it's an alternative approach!
Edit:
As Seth pointed out, map [ y -> item 0 y ] can be replaced with map first- so the modified versions would look like:
print map [ x -> map first x ] a
and
print map [ x -> csv:to-row map first x ] a
Thanks Seth!

Related

Inductive proposition for sublists in Coq

I am struggling with coming up with a notion of sublist of a list, which is created by deleting elements in the list (so that the order is preserved). I need to come up with an inductive proposition that decides if l1 is a sublist of l2.
So far:
I know the empty list is a sublist of all lists.
All lists are sublists of themselves.
If it is known that l1 is a sublist of l2, then lists resulting from appending the same list to both l1 and l2 at the head or tail would result in the former being a sublist of the latter
Now is the hard part. How to provide evidence that a list like ["x";"y"] is a sublist of ["a";"x";"z";"y"]?
The syntax is something like
Inductive Sublist {X : Type} : list X -> list X -> Prop := ..
Can someone please help me with it?
How would you do informally already? Using just your three rules. If you can't manage it means that you have perhaps a too complicated / incomplete definition.
I think instead of trying to think of all those complicated examples you could focus on your example(s) while keeping in mind how lists are constructed.
Why is [ x ; y ] a sublist of [ a ; x ; y ; z ]? Because (without the head of the second list) [ x ; y ] is a sublist of [ x ; y ; z ], and that's because [ y ] is a sublist of [ y ; z ], which is because [] is a sublist of [ z ] which always holds.
Do you see a pattern?

How do I build a list of lists

So I want to build a list x that looks like this: [[a1 b1][a2 b2][a3 b3]...]. A and b are chosen with one-of listA and one-of listB respectively. I can't find how to build a list easily, I can't just add an item to an empty list?
Check out the dictionary entry for lput for the general syntax for adding to a list, and potentially the programming guide entry and this answer for some more info. For this specific question, have a look at the example below:
to build-lists
ca
let a [ 1 2 3 4 5 ]
let b [ "a" "b" "c" "d" "e" ]
; Unordered version:
let ab []
repeat length a [
set ab lput ( list one-of a one-of b ) ab
]
print "Randomly sampled list:"
print ab
; Ordered version:
set ab ( map [ [ i j ] -> list i j ] a b )
print "Ordered list: "
print ab
reset-ticks
end
Which gives an output something like:
Randomly sampled list:
[[2 a] [2 c] [1 d] [4 d] [1 e]]
Ordered list:
[[1 a] [2 b] [3 c] [4 d] [5 e]]
Slight variation on Luke C's answer, using, respectively, n-values and the concise syntax for anonymous procedures:
let a [ 1 2 3 4 5 ]
let b [ "a" "b" "c" "d" "e" ]
; Unordered version:
print n-values length a [ list one-of a one-of b ]
; Ordered version:
print (map list a b)

Array of arrays of arrays in qw representation in Perl

Hello I'd like to form a data structure like this:
my #AoAoA = (
[ qw/ [a b] [c d] [e f] / ],
[ qw/ [r t] [m n] [k l] / ],
[ qw/ [z x] [b a] [p u] / ]
);
In this structure which I call array of arrays of arrays in qw representation, AoAoA for short, when I want to access the first array's first array's first value:
my $first_elt = #{$AoAoA[0]}[0];# supposed to be [a b]
my $first_val = #{$first_elt}[0];# supposed to be 'a'
print "$first_val\n";
it prints nothing. How sould I arrange it so I can access that value correctly? Thank you.
qw is short for quote words. It will implicitly quote every non-space substring for you, which is often very useful. But you can't add complex data structures using the same construct
Your assignment
my #AoAoA = (
[ qw/ [a b] [c d] [e f] / ],
[ qw/ [r t] [m n] [k l] / ],
[ qw/ [z x] [b a] [p u] / ]
)
is the same as
my #AoAoA = (
[ '[a', 'b]', '[c', 'd]', '[e', 'f]' ],
[ '[r', 't]', '[m', 'n]', '[k', 'l]' ],
[ '[z', 'x]', '[b', 'a]', '[p', 'u]' ]
)
which is unlikely to be what you want. Instead you must use qw// to define only the strings in your structure, like this
my #AoAoA = (
[ [ qw/ a b / ], [ qw/ c d / ], [ qw/ e f / ] ],
[ [ qw/ r t / ], [ qw/ m n / ], [ qw/ k l / ] ],
[ [ qw/ z x / ], [ qw/ b a / ], [ qw/ p u / ] ]
)
Then you can write
my $first_elt = $AoAoA[0][0]; # ['a', 'b']
my $first_val = $first_elt->[0]; # 'a'
Or you can use just
my $first_val = $AoAoA[0][0][0]; # 'a'
This doesn't work since inside qw you can't use the square brackets. so the elements in your qw are "[a", "b]", ... .
What you probably want is:
my #AoAoA = (
[ [qw/a b/], [qw/c d/], [qw/e f/] ],
[ [qw/r t/], [qw/m n/], [qw/k l/] ],
[ [qw/z x/], [qw/b a/], [qw/p u/] ]
);
Trying to make it shorter:
my #AoAoA = map {[map {[split ' ']} split /,/]} (
"a b,c d,e f",
"r t,m n,k l",
"z x,b a,p u"
);

Double foreach loop

I have the following code.
turtles-own [age]
set list1 (list 2 1 4 6)
set list2 (list (turtle 1) (turtle 0) (turtle 0) (turtle 0))
foreach list2 [ x ->
foreach list1 [ y ->
if (position x list2 = position y list1) [
ask x [ set age (item(position y list1) list1 ]
]
]
]
What I am trying to do is to iterate though the list of turtles and the list of ages. If the index of the turtle matches the index of the value then set turtle's age to that value. I works to some extent but it appears that the values in list1 affects the foreach loops in some way. For example, I use sliders to determine the age values in list1. List1 one is written in the form list1 (list a1 a2 a3 a4) and for each a1, a2 a3, a4 I have a slider. Depending on the values I set on the slider, some turtles get the values while other don't.Sometimes all turtles get the age values, all depending on the values I set using the slides.
If there is a better way to do this then that would also be helpful. All I need is to use a loop that would set age values to their corresponding turtle. I have a much larger list of turtles which is why I need to use a loop.
Much appreciated.
position only reports the first value of the item in the list. In this example, for every turtle 0 in your foreach loop, the position x list2 will report 1. For this to work as-is, I think you'd need to have every item in each list be unique.
Not exactly sure what you're after here, but I think you can get around your issue by just including a counter in each loop, and use that to compare index values, as well as setting age using item:
turtles-own [age]
globals [ list1 list2 ]
to setup
ca
crt 2
set list1 (list 2 1 4 6)
set list2 (list (turtle 1) (turtle 0) (turtle 1) (turtle 0))
let l2counter 0
foreach list2 [ x ->
let l1counter 0
foreach list1 [ y ->
if l2counter = l1counter [
ask x [
set age item l1counter list1
show ( word "my age is now " age )
]
]
set l1counter l1counter + 1
]
set l2counter l2counter + 1
]
reset-ticks
end
Edit:
If you don't need to use indexing, this is probably the better way:
to setup-2
ca
crt 2
set list1 (list 2 1 4 6)
set list2 (list (turtle 1) (turtle 0) (turtle 1) (turtle 0))
( foreach list2 list1 [
[ _turt _age ] ->
ask _turt [
set age _age
]
]
)
end

How to select first n items of list in netlogo

I have a list and i want to do an operation on first 3 items of list if they are not 0.i can do my operation on each item by code below,but dont know how to do it for first 3 items.
foreach list2
[
if (item ? list2 != 0)
[
set candidatelist lput (item ? list3) candidatelist
]
]
Here's a helper for getting the first n elements:
to-report take [n xs]
report sublist xs 0 min list n (length xs)
end
Now we can write:
filter [x -> x != 0] take 3 ...
sample run:
observer> show filter [x -> x != 0] take 3 [1 0 3 4 5]
observer: [1 3]
(That's NetLogo 6 syntax. In NetLogo 5, write [? != 0] instead of [x -> x != 0].)
i wrote code below to solve it:
let m 0
foreach list2
[
if (m < 3)
[
if (item ? list2 != 0)
[
set candidatelist lput (item ? list3) candidatelist
]
set m m + 1
]
]