Netlogo: Using foreach to iterate over two lists filled with variables - foreach

This may be a beginner question, but after using the NetLogo Progamming Guide I'm unable to find a solution...
I am trying to iterate over a pair of lists and conditionally update the values based on a test condition.
This thread in a Netlogo Forum which gave me the hint to use the LIST primitives reporter but I still can't get the expected output.
Here is a simplified example which describes my problem.
Please note, that listA and listB are both filled with variables.
to test
let a1 1
let a2 5
let listA (list a1 a2)
let b1 6
let b2 3
let listB (list b1 b2)
(foreach (list listA) (list listb) [
[a b] -> ifelse a < b [set a "a"][set b "b"]])
show lista
show listb
end
;expected Output
;observer: [a 5]
;observer: [6 b]
Could someone give me a hint? What am I doing wrong?

Lists in NetLogo are immutable- you can't change the values quite like this approach. map might be more suitable for this:
to test2
let a1 1
let a2 5
let listA (list a1 a2)
let b1 6
let b2 3
let listB (list b1 b2)
show ( map [ [ a b ] ->
ifelse-value ( a < b ) [ "a" ] [ a ] ]
listA listB ;; pass the lists [ 1 5 ] and [ 6 3 ]
)
show ( map [ [ a b ] ->
ifelse-value ( a > b ) [ "b" ] [ b ] ]
listA listB ;; pass the lists [ 1 5 ] and [ 6 3 ]
)
end
Note that I think your expected output for lista should be ["a" 5] not ["a" 0]- is that correct?
If you'd like to do this with foreach to modify the original lists, I would create an index ( 0 to the length of the list ) to pass to replace-item:
to test3
let a1 1
let a2 5
let listA (list a1 a2)
let b1 6
let b2 3
let listB (list b1 b2)
let indexer ( range 0 length listA )
foreach indexer [ ind ->
let current_a item ind listA
let current_b item ind listB
ifelse current_a < current_b [
set listA replace-item ind listA "a"
] [
set listB replace-item ind listB "b"
]
]
print listA
print listB
end

Related

I have two list (list a and list b) , with different lengths, how do i get a new list with all the unique elements of list a?

I have this issue where i need a new list with, all the unique elements from list a, but the issue is that the list have different lengths.
[ 1; 2; 4; 5 ] |> List.except [ 2; 3; 5 ] // [ 1; 4 ]
That is, the following should do what you want
let c = a |> List.except b
Update
As #rcoy pointed out, List.except returns distinct elements only, i.e.
[ 1; 1 ] |> List.except [] = [ 1 ] // true
To keep duplicates, a straightforward way is
let b = [ 2 ]
let toRemove x = not(List.contains x b)
[ 1; 1; 2 ] |> List.filter toRemove // [ 1; 1 ]
Depending on the size of the b list and equivalency function (structural vs. referential), i.e. the cost of traversing and comparing, changing the datastructures might be beneficial. E.g.
open System.Collections.Generic
let b = [ 2 ]
let toRemove = HashSet(b)
[ 1; 1; 2 ] |> List.filter (fun x -> not(toRemove.Contains(x))) // [ 1; 1 ]
which is similar to what List.except does internally.

How to convert a 2d array to a list of lists in F#

I have a 2d array of floats:
let scores = Array2D.init<float> width height (fun _ _ -> 0.)
and I would like to convert it to a list of lists where I have a list of rows and each of these row is a list of column values.
for example:
[
1, 2, 3
4, 5, 6
7, 8, 9
]
would become:
[
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
]
I found this question: F# convert Array2 into a list
but it converts the 2d array into a list, I'm trying to find how to convert it to a list of list.
I could iterate through the elements and build the list, but I'm sure there has to be a better way.
This is made quite readable by F#'s slice operators (now in C# 8 too!).
To slice a multi-dimensional array you can use .[range,range].
For example, .[*,n] for the n-th column, and .[n,*] for the n-th row.
The final piece we need is the height of the array, which is Dimension 0, given by
array.GetLength 0
Now it becomes trivial to slice up the 2D array, using a list comprehension.
[
let height = arr.GetLength 0
for row in 0..height-1 do
yield arr.[row,*] |> List.ofArray
]
For non-zero indexed arrays, as suggested by Henrik Hansen, it is preferable to use:
[
for i in arr.GetLowerBound(0)..arr.GetUpperBound(0)
do yield arr.[i,*] |> List.ofArray
]
Test
let counter = ref 0
//generate the test array
let arr = Array2D.init (3) (3) (fun _ _ -> Interlocked.Increment(counter))
arr |> printfn "%A"
let lists =
[
let height = arr.GetLength 0
for row in 0..height - 1 do
yield arr.[row,*] |> List.ofArray
]
lists |> printfn "%A"
Output:
[[1; 2; 3]
[4; 5; 6]
[7; 8; 9]]
[[1; 2; 3]; [4; 5; 6]; [7; 8; 9]]
Another way building on Asti's ideas:
module Array2D =
let toListOfLists (arr2d: 'a [,]) = [ yield! [arr2d.GetLowerBound(0)..arr2d.GetUpperBound(0)] |> List.map (fun i -> arr2d.[i,*] |> List.ofArray) ]
let base002D = Array2D.init 5 5 (fun x y -> (x, y))
let base152D = Array2D.initBased 1 5 5 5 (fun x y -> (x, y))
printfn "%A" (base002D |> Array2D.toListOfLists)
printfn "%A" (base152D |> Array2D.toListOfLists)
It works with different bases.

NetLogo: break out of nested foreach loop

I'm trying to break out of a nested foreach loop using 2 lists of sorted turtles.
But instead of just leaving the inner loop, netlogo breaks out of the whole procedure.
I have a code like the one below (this one is made up, but has exactly the same structure):
to do-something
let xturtles sort-by [ [a b] -> [birthday] of a > [birthday] of b ] turtles
;; construct an ordered set
foreach xturtles [ the-xturtle ->
ask the-xturtle [
let xage birthday
let yturtles sort-by [ [a b] -> [birthday] of a > [birthday] of b ] turtles with [birthday < xage]
;; construct a second ordered set
foreach yturtles [ the-yturtle ->
let breakout-condition? false
ask the-yturtle [
if (hidden? ) [
set breakout-condition? true
]
]
if breakout-condition? [ stop ]
]
]
]
end
However, when the stop condition is reached, netlogo breaks out of the whole procedure, instead of continuing with the outer loop (the xturtles loop)?
Is that the expected behavior? If so, what is a good practice in this case?
Thanks!
Felix
It looks even nesting the stop within an extra ask procedure in the same procedure doesn't help. However, if you need a quick fix I think you can replace the second foreach loop with a standalone procedure that contains the stop as a workaround. For example, this procedure follows a similar format to yours and the same problem comes up- as soon as stop is called the broader foreach is exited.
to nest-foreach-example
ca
crt 1
let xs [ 1 2 3 4 ]
let ys [ 1 2 3 4 ]
foreach xs [
x ->
foreach ys [
y ->
ask turtles [
if y > x [
stop
]
]
print word x y
]
]
end
This prints out 11.
However, if you make a custom procedure to take the place of your "y" foreach loop, it works (with or without the ask turtles):
to nest-foreach-example-turtles
ca
crt 1
let xs [ 1 2 3 4 ]
let ys [ 1 2 3 4 ]
foreach xs [
x ->
for-y x ys
]
end
to for-y [ x_ ys ]
foreach ys [
y ->
ask turtles [
if y > x_ [
stop
]
]
print word x_ y
]
end
Outputs:
11
21
22
31
32
33
41
42
43
44

Atom for a list in Erlang

Can I create a list with atoms as reference for them to later use it in my move method?
createLists(X) ->
List = [
listA = lists:seq(1, X),
listB = [],
listC = []
],
List.
Then I create like T = hello:createLists(10).
move(List, A, B) ->
...
How can I obtain A and B using atoms? I'm pretty new to Erlang so the answer might be obvious.
move is supposed to move top element of the from A to B but I struggle to pass A and B when I do like hello:move(List, ?, ?).
Regarding the code in your comment, #armedor:
1 move(List, a, b, c) ->
2 Source = proplists:get_value(a, List),
3 Dest = proplists:get_value(b, List),
4 Help = proplists:get_value(c, List),
5 Temp1 = [lists:nth(1,Source)],
6 NewDest = [lists:append(Dest,Temp1)],
7 NewSource = lists:subtract(Source,Temp1),
8 List1=[NewSource,NewDest,Help].
Say List is defined as [ {a, lists:seq(1, 3)}, {b, []}, {c, []} ].
Line 8 isn't going to be a proplist anymore, but just the sublists themselves. Instead, create List1 as [{a, NewSource}, {b, NewDest}, Help].
You also don't need to assign to List1 in line 8, since the function is returning - just make the new list itself the last line, which will be the return value.
And the lists:nth and lists:subtract you're doing can be combined as
[Temp1 | NewSource] = Source

How do I compute the cartesian product of n sequences in F#?

I was given a puzzle as a present. It consists of 4 cubes, arranged side by side. The faces of each cube are one of four colours.
To solve the puzzle, the cubes must be orientated so that all four cubes' tops are different, all their fronts are different, all their backs are different and all their bottom's are different. The left and right sides do not matter.
My pseudo-code solution was:
Create a representation of each
cube.
Get all the possible orientations of
each cube (there are 24 for each).
Get all the possible combinations of
orientations of each cube.
Find the combination of orientations
that satisfies the solution.
I solved the puzzle using an implementation of that pseudo-code in F#, but am not satisifed with the way I did step 3:
let problemSpace =
seq { for c1 in cube1Orientations do
for c2 in cube2Orientations do
for c3 in cube3Orientations do
for c4 in cube4Orientations do
yield [c1; c2; c3; c4] }
The above code is very concrete, and only works out the cartesian product of four sequences of orientations. I started thinking about a way to write it for n sequences of orientations.
I came up with (all the code from now on should execute fine in F# interactive):
// Used to just print the contents of a list.
let print =
Seq.fold (fun s i -> s + i.ToString()) "" >> printfn "%s"
// Computes the product of two sequences - kind of; the 2nd argument is weird.
let product (seq1:'a seq) (seq2:'a seq seq) =
seq { for item1 in seq1 do
for item2 in seq2 do
yield item1 |> Seq.singleton |> Seq.append item2 }
The product function could be used like so...
seq { yield Seq.empty }
|> product [ 'a'; 'b'; 'c' ]
|> product [ 'd'; 'e'; 'f' ]
|> product [ 'h'; 'i'; 'j' ]
|> Seq.iter print
... which lead to ...
let productn (s:seq<#seq<'a>>) =
s |> Seq.fold (fun r s -> r |> product s) (seq { yield Seq.empty })
[ [ 'a'; 'b'; 'c' ]
[ 'd'; 'e'; 'f' ]
[ 'h'; 'i'; 'j' ] ]
|> productn
|> Seq.iter print
This is exactly the usage I want. productn has exactly the signature I want and works.
However, using product involves the nasty line seq { yield Seq.empty }, and it unintuitively takes:
A sequence of values (seq<'a>)
A sequence of sequences of values (seq<seq<'a>>)
The second argument doesn't seem correct.
That strange interface is hidden nicely by productn, but is still nagging me regardless.
Are there any nicer, more intuitive ways to generically compute the cartesian product of n sequences? Are there any built in functions (or combination of) that do this?
Use recursion: the cartesian product of n lists {L1..LN} is the collection of lists you get when you add each element in L1 to each sublist in the cartesian product of lists {L2..LN}.
let rec cart1 LL =
match LL with
| [] -> Seq.singleton []
| L::Ls -> seq {for x in L do for xs in cart1 Ls -> x::xs}
Example:
> cart1 [[1;2];[3;4;5];[6;7]] |> Seq.toList;;
val it : int list list =
[[1; 3; 6]; [1; 3; 7]; [1; 4; 6]; [1; 4; 7]; [1; 5; 6]; [1; 5; 7]; [2; 3; 6];
[2; 3; 7]; [2; 4; 6]; [2; 4; 7]; [2; 5; 6]; [2; 5; 7]]
The cartesian product of [1;2] [3;4;5] and [6;7] is the union of {1 appended to each list in cart [[3;4;5];[6;7]]} and {2 appended to each list in cart [[3;4;5];[6;7]]}. This is the second clause in the match statement.
Here's a solution 'a list list -> Seq<'a list> to calculate the Cartesian product of n lists, with lazy evaluation. I wrote it to be an F# analogue of Python's itertools.product
let product lists =
let folder list state =
state |> Seq.allPairs list |> Seq.map List.Cons
Seq.singleton List.empty |> List.foldBack folder lists
It's based on List.allPairs which was introduced in F# 4.0.
Here's a first try at a list version. I think it could be cleaned up a bit.
let rec cart nll =
let f0 n nll =
match nll with
| [] -> [[n]]
| _ -> List.map (fun nl->n::nl) nll
match nll with
| [] -> []
| h::t -> List.collect (fun n->f0 n (cart t)) h

Resources