I am trying to solve Project Euler Problem #11 using F#, and I am having issues figuring out how to instantiate the original grid.
I've tried:
let grid : int [,] = [|[|08; 02; 22; 97; 38; 15; 00; 40; 00; 75; 04; 05; 07; 78; 52; 12; 50; 77; 91; 08|]
[|49; 49; 99; 40; 17; 81; 18; 57; 60; 87; 17; 40; 98; 43; 69; 48; 04; 56; 62; 00|]
[|81; 49; 31; 73; 55; 79; 14; 29; 93; 71; 40; 67; 53; 88; 30; 03; 49; 13; 36; 65|]
[|52; 70; 95; 23; 04; 60; 11; 42; 69; 24; 68; 56; 01; 32; 56; 71; 37; 02; 36; 91|]
[|22; 31; 16; 71; 51; 67; 63; 89; 41; 92; 36; 54; 22; 40; 40; 28; 66; 33; 13; 80|]
[|24; 47; 32; 60; 99; 03; 45; 02; 44; 75; 33; 53; 78; 36; 84; 20; 35; 17; 12; 50|]
[|32; 98; 81; 28; 64; 23; 67; 10; 26; 38; 40; 67; 59; 54; 70; 66; 18; 38; 64; 70|]
[|67; 26; 20; 68; 02; 62; 12; 20; 95; 63; 94; 39; 63; 08; 40; 91; 66; 49; 94; 21|]
[|24; 55; 58; 05; 66; 73; 99; 26; 97; 17; 78; 78; 96; 83; 14; 88; 34; 89; 63; 72|]
[|21; 36; 23; 09; 75; 00; 76; 44; 20; 45; 35; 14; 00; 61; 33; 97; 34; 31; 33; 95|]
[|78; 17; 53; 28; 22; 75; 31; 67; 15; 94; 03; 80; 04; 62; 16; 14; 09; 53; 56; 92|]
[|16; 39; 05; 42; 96; 35; 31; 47; 55; 58; 88; 24; 00; 17; 54; 24; 36; 29; 85; 57|]
[|86; 56; 00; 48; 35; 71; 89; 07; 05; 44; 44; 37; 44; 60; 21; 58; 51; 54; 17; 58|]
[|19; 80; 81; 68; 05; 94; 47; 69; 28; 73; 92; 13; 86; 52; 17; 77; 04; 89; 55; 40|]
[|04; 52; 08; 83; 97; 35; 99; 16; 07; 97; 57; 32; 16; 26; 26; 79; 33; 27; 98; 66|]
[|88; 36; 68; 87; 57; 62; 20; 72; 03; 46; 33; 67; 46; 55; 12; 32; 63; 93; 53; 69|]
[|04; 42; 16; 73; 38; 25; 39; 11; 24; 94; 72; 18; 08; 46; 29; 32; 40; 62; 76; 36|]
[|20; 69; 36; 41; 72; 30; 23; 88; 34; 62; 99; 69; 82; 67; 59; 85; 74; 04; 36; 16|]
[|20; 73; 35; 29; 78; 31; 90; 01; 74; 31; 49; 71; 48; 86; 81; 16; 23; 57; 05; 54|]
[|01; 70; 54; 71; 83; 51; 54; 69; 16; 92; 33; 48; 61; 43; 52; 01; 89; 19; 67; 48|]|]
and many other permutations with no luck. All my attempts give me:
This expression was expected to have type
int [,]
but here has type'a[]
How do I instantiate the rectangular array without having to set each cell individually?
2 Answers 2
You can use a built-in library function array2D
. It converts array of arrays int[][]
into a two-dimensional array int[,]
. You can call it like this (using a slightly smaller input array):
let grid =
array2D [| [|08; 02; 22; |]
[|49; 49; 99; |]
[|01; 70; 54; |] |]
or you can use the pipelining operator and call it like this:
let grid =
[| [|08; 02; 22; |]
[|49; 49; 99; |]
[|01; 70; 54; |] |] |> array2D
While this is not a special language syntax for building 2D arrays, it practically functions as one.- F# has a number of similar functions that you can use to construct sets, immutable maps and other types. In the following example, seq
and dict
are all functions, but you can see them as syntax (for some other data types, there are longer functions like Map.ofSeq
):
dict [ "cz", "Ahoj"; "en", "Hello" ]
seq { 1 .. 100 }
The function will actually work on any collection of collections (not just array of arrays), because it has the following type:
val array2D : seq<#seq<'a>> -> 'a[,]
This means that it takes any sequence (the outer seq
) of any types that implement the IEnumerable
interface (the inner #seq
) - so you can also produce the data using more complex sequence comprehensions and then pass it to array2D
.
3 Comments
map
come from? It doesn't seem to work for me. Maybe it requires some open
s?map
does not actually exist. To construct map, one has to use the long function name - Map.ofSeq
.How about this:
let my2DArray =
[| for i in 0 .. rowCount - 1 do
yield [| for i in 0 ..columnCount - 1 do yield init |]
|] |> array2D
array2D
operator orArray2D.init
function. See MSDN article.int [] []
which might be okay for what you want - the access ingrid.[x].[y]
which might be awkward though