2

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?

ildjarn
63.2k9 gold badges133 silver badges219 bronze badges
asked May 26, 2013 at 2:23
3
  • There's no syntax for a multidimensional array literal. Use array2D operator or Array2D.init function. See MSDN article. Commented May 26, 2013 at 2:52
  • You are creating a int [] [] which might be okay for what you want - the access in grid.[x].[y] which might be awkward though Commented May 26, 2013 at 5:04
  • Instead of hardcoding data into the code I'd go with a text file and data loader function. Commented May 26, 2013 at 13:43

2 Answers 2

7

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.

answered May 26, 2013 at 11:11

3 Comments

Where does map come from? It doesn't seem to work for me. Maybe it requires some opens?
Map is the standard immutable associative array (or dictionary in c#) in f#: msdn.microsoft.com/en-us/library/ee353686.aspx
@svick My bad - map does not actually exist. To construct map, one has to use the long function name - Map.ofSeq.
0

How about this:

let my2DArray = 
 [| for i in 0 .. rowCount - 1 do 
 yield [| for i in 0 ..columnCount - 1 do yield init |] 
 |] |> array2D
Esoteric Screen Name
6,1224 gold badges31 silver badges39 bronze badges
answered Apr 1, 2015 at 10:36

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.