Is there a shorthand method for constructing a 2D array?
I really don't want to do the following:
let board = array2D [|
[| 0;0 |]
[| 0;1 |]
[| 0;2 |]
[| 0;3 |]
[| 0;4 |]
[| 0;5 |]
[| 0;6 |]
[| 0;7 |]
[| 1;0 |]
[| 1;1 |]
[| 1;2 |]
...
[| 7;7 |]
|]
I thought I could do something like this:
let board = array2D [|
[| 0;0 |]..[|7;7|]
|]
Or this:
let board = array2D [|
[| 0.., 0..7 |]
|]
Any guidance?
Maybe what you need is a comprehension:
array2D [for i in 0..7 do for j in 0..7 do yield [|i;j|] ]
This returns what seems to be what you want in the order you want:
val it : int [,] = [[0; 0]
[0; 1]
[0; 2]
[0; 3]
[0; 4]
[0; 5]
[0; 6]
[0; 7]
[1; 0]
[1; 1]
[1; 2]
[1; 3]
[1; 4]
[1; 5]
[1; 6]
[1; 7]
[2; 0]
[2; 1]
[2; 2]
[2; 3]
[2; 4]
[2; 5]
[2; 6]
[2; 7]
[3; 0]
[3; 1]
[3; 2]
[3; 3]
[3; 4]
[3; 5]
[3; 6]
[3; 7]
[4; 0]
[4; 1]
[4; 2]
[4; 3]
[4; 4]
[4; 5]
[4; 6]
[4; 7]
[5; 0]
[5; 1]
[5; 2]
[5; 3]
[5; 4]
[5; 5]
[5; 6]
[5; 7]
[6; 0]
[6; 1]
[6; 2]
[6; 3]
[6; 4]
[6; 5]
[6; 6]
[6; 7]
[7; 0]
[7; 1]
[7; 2]
[7; 3]
[7; 4]
[7; 5]
[7; 6]
[7; 7]]
Ringil's answer is more correct (for what you asked). However, if you are looking for another way with a slightly different array shape, you can do the following:
You can use Array2D.init:
> let board = Array2D.init 8 8 (fun x y -> (x,y));;
val board : (int * int) [,] =
[[(0, 0); (0, 1); (0, 2); (0, 3); (0, 4); (0, 5); (0, 6); (0, 7)]
[(1, 0); (1, 1); (1, 2); (1, 3); (1, 4); (1, 5); (1, 6); (1, 7)]
[(2, 0); (2, 1); (2, 2); (2, 3); (2, 4); (2, 5); (2, 6); (2, 7)]
[(3, 0); (3, 1); (3, 2); (3, 3); (3, 4); (3, 5); (3, 6); (3, 7)]
[(4, 0); (4, 1); (4, 2); (4, 3); (4, 4); (4, 5); (4, 6); (4, 7)]
[(5, 0); (5, 1); (5, 2); (5, 3); (5, 4); (5, 5); (5, 6); (5, 7)]
[(6, 0); (6, 1); (6, 2); (6, 3); (6, 4); (6, 5); (6, 6); (6, 7)]
[(7, 0); (7, 1); (7, 2); (7, 3); (7, 4); (7, 5); (7, 6); (7, 7)]]
I'll leave this here in case anyone finds it useful, as I think this data shape makes sense in many cases.
Related
I came across the following problem in an online challenge.
Consider the following vectors:
x = [3, 4, ...]
y = [2, 3, ...]
Such that for i >= 2:
x[i] = x[i-1] + 3 * y[i-2]
y[i] = 2 * y[i-1] + 2 * x[i-2]
What is x[10^15] ?
While the problem has a very straightforward solution, the problem is the 10^15 value which cannot be calculated in a small time. Only thing I can think of is that we have to derive a polynomial from the recurrence relation - However this isn't easy to do. Am I missing something?
The problem statement can be express as matrix multiplication as follows:
A= [
[1, 0, 0, 3],
[1, 0, 0, 0],
[0, 2, 2, 0],
[0, 0, 1, 0]
]
[xn+1, xn, yn+1, yn] = A*[xn, xn-1, yn, yn-1]
=> [xn+1, xn, yn+1, yn] = A^(n-1) * [x1, x0, y1, y0]
[x1, x0, y1, y0] = [4, 3, 3, 2]
While not mentioned in the problem, since the matrix multiplication exceeds integer limits, the solution needs to be expressed in as remainder of some prime number. Let the prime number be 1000000007. But how can we not exceed the integer limits while multiplying? Consider the following:
(X * Y) mod p = ((X mod p) * (Y mod p)) mod p
Now, X = A^n
Let, A^n mod p = B
Now, B = B mod p
So,
(X * Y) mod p =
((X mod p) * (Y mod p)) mod p
=> ((A^n mod p) * (Y mod p)) mod p
=> ( B * (Y mod p)) mod p
=> ((B mod p) * (Y mod p)) mod p
=> (B * Y) mod p
So a simple python implementation would be:
import numpy as np
p = 1000000007
A= np.array([
[1, 0, 0, 3],
[1, 0, 0, 0],
[0, 2, 2, 0],
[0, 0, 1, 0]
])
Y = np.array([4, 3, 3, 2])
# We will use binary exponentiation for fast matrix multiplication
# See: https://cp-algorithms.com/algebra/binary-exp.html
# The `power` list is the array of A's powers needed for that
powers = []
powers.append(A % p)
for i in range(1, 50): # Till 50 since 10^15 ~= 2^50
Ap = powers[i - 1]
powers.append(Ap.dot(Ap) % p)
def solve(n):
pow_of_a = n - 3
index = 0
prod = np.identity(4)
while (pow_of_a > 0):
if (pow_of_a & 1) == 1:
prod = prod.dot(powers[index])
pow_of_a >>= 1
index += 1
B = prod % p
print(B.dot(Y) % p)
I was wondering if there is a way to use a list or an array of int as an index for slicing into a array to get a sub array in f#.
I know you can do the following
Arr2d.[*,1] or Arr2d.[1..5,1..2] etc...
But I was looking for something like in Matlab where you can write:
Arr2d([1;6;10],1) or Arr2d(1:10,[1;6;10])
Is it possible to do slicing like that in F#?
Thanks!
Here was my sample solution: (maybe not optimal but works)
let sampleMatrix = Array2D.init 10 5 (fun x y -> y)
val sampleMatrix : int [,] = [[0; 1; 2; 3; 4]
[0; 1; 2; 3; 4]
[0; 1; 2; 3; 4]
[0; 1; 2; 3; 4]
[0; 1; 2; 3; 4]
[0; 1; 2; 3; 4]
[0; 1; 2; 3; 4]
[0; 1; 2; 3; 4]
[0; 1; 2; 3; 4]
[0; 1; 2; 3; 4]]
let idxlist = [1;3;4]
let array2dColumnSlice (idxlist:list<int>) (data:'T[,]) =
let tmp = [|for i in idxlist -> data.[*,i]|]
Array2D.init tmp.[0].Length tmp.Length (fun x y -> tmp.[y].[x] )
let slice = array2dColumnSlice idxlist sampleMatrix
val slice : int [,] = [[1; 3; 4]
[1; 3; 4]
[1; 3; 4]
[1; 3; 4]
[1; 3; 4]
[1; 3; 4]
[1; 3; 4]
[1; 3; 4]
[1; 3; 4]
[1; 3; 4]]
As detailed here, there is no additional slicing notation beyond what you have already found.
For ranges only, it is possible, by wrapping Array2D with a sliceable type, or using the old PowerPack's Matrix type.
See the docs here:
http://msdn.microsoft.com/en-us/library/dd233214.aspx#sectionToggle6
You can use this slicing syntax for types that implement the element
access operators and overloaded GetSlice methods. For example, the
following code creates a Matrix type that wraps the F# 2D array,
implements an Item property to provide support for array indexing, and
implements three versions of GetSlice. If you can use this code as a
template for your matrix types, you can use all the slicing operations
that this section describes.
I'm having some issues transforming a list of lists again. I have a list of list of ints it looks like this.
val p5PrimeFactorization : int list list =
[[1]; [2]; [3]; [2; 2]; [5]; [3; 2]; [7]; [2; 2; 2]; [3; 3]; [5; 2]; [11];
[3; 2; 2]; [13]; [7; 2]; [5; 3]; [2; 2; 2; 2]; [17]; [3; 3; 2]; [19];
[5; 2; 2]]
Now I want to transform each list into the product of all entries. Now this works
[for n in 2..20 -> primeFactors n 2 []]
|> List.map (List.sum)
But this doesn't..
[for n in 2..20 -> primeFactors n 2 []]
|> List.map (List.fold (fun acc elem -> acc * elem))
It seems the problem is that it infers the type of acc and elem to be of type int list which isn't right. I don't understand why List.sum which basically does the same thing except it returns the sum of all numbers, works, but my folder will not.
In your second example, you haven't specified the initial value for the fold.
You probably meant something like
|> List.map (List.fold (fun acc elem -> acc * elem) 1)
#light
let a1 = [| (1, 1); (2, 1); (3, 1) |]
let a2 = [| (1, 1); (2, 3); (3, 1) |]
let aa = Array.zip a1 a2
|> Array.filter(fun (x, y) -> x <> y)
I want to write a function to do this: it will return the different tuple from two arrays, but I also want to return the index of the different tuple in the second array and the corresponding tuple in the second array. (My code did not work totally yet!)
For my above example, I want to return: 1 and (2, 3)
Another example:
let a1 = [| (1, 1); (2, 1); (3, 1); (4, 1) |]
let a2 = [| (1, 1); (2, 3); (3, 1); (4, 2) |]
I want to return: 1 and (2, 3); 3 and (4, 2)
If you have any idea, please show me your code.
Besides, I am not used to the new place for F#, the format makes me feel difficult to find a good place to post my questions, therefore, I still post my question here.
let a1 = [| (1, 1); (2, 1); (3, 1) |]
let a2 = [| (1, 1); (2, 3); (3, 1) |]
let diff =
(a1, a2)
||> Array.mapi2(fun i t1 t2 -> (i, t1, t2))
|> Array.choose(fun (i, a, b) -> if a <> b then Some (i, b) else None)
Here's one way to do it:
let diff a b =
let s = Set.ofSeq a
b
|> Seq.mapi (fun i x -> i, x)
|> Seq.filter (fun (_, x) -> not (Set.contains x s))
Example
let a1 = [| (1, 1); (2, 1); (3, 1) |]
let a2 = [| (1, 1); (2, 3); (3, 1) |]
diff a1 a2 //output: seq [(1, (2, 3))]
This works for any collection (list, array, seq<_>, set, etc) and the sequences may be of different lengths. If you know you'll always be using arrays of equal length, you can optimize accordingly (see desco's answer).
let diff (a:(int * int)[]) b =
b
|> Array.mapi (fun i tp -> if a.[i] <> tp then (i, tp) else (-1, tp))
|> Array.filter (fun (x, _) -> x >= 0)
DEMO
> diff a1 a2;;
val it : (int * (int * int)) [] = [|1, (2, 3)); (3, (4, 2))|]
I want to generate a sequence like a multiplication table. So for a start of 1 and a stop of 10 I am looking for a sequence like
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 1*1 - 1*10
2, 4, 6, 8, 10, 12, 14, 16, 18, 20, // 2*1 - 2*10
3, 6, 9, 12, ... // 3*1 - 3*10
Here is my lame start at it, however I can't seem to figure out how to cleanly increment j when the stop is reached, or how to reset i back to the start.
let multable (start,stop) =
(start,start)
|> Seq.unfold(
fun (i,j) ->
Some(i*j, (i+1, j)))
let its = multable(1, 1)
let first10 = Seq.take 10 its
printf "%A" (Seq.to_list first10)
Which of course gives me 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
I can't really think of many cases where I'd prefer Seq.unfold over an equivalent list comprehension:
> let multiplication n m = [for a in 1 .. n -> [for b in 1 .. m -> a * b ] ];;
val multiplication : int -> int -> int list list
> multiplication 5 5;;
val it : int list list =
[[1; 2; 3; 4; 5]; [2; 4; 6; 8; 10]; [3; 6; 9; 12; 15]; [4; 8; 12; 16; 20];
[5; 10; 15; 20; 25]]
Occasionally the Array.init methods are useful too:
> let multiplication n m = Array2D.init n m (fun n m -> n * m);;
val multiplication : int -> int -> int [,]
> multiplication 5 5;;
val it : int [,] = [[0; 0; 0; 0; 0]
[0; 1; 2; 3; 4]
[0; 2; 4; 6; 8]
[0; 3; 6; 9; 12]
[0; 4; 8; 12; 16]]
Use a sequence expression:
let multable start stop = seq{
for a = start to stop do
for b = start to stop do
yield a*b
}
Output:
> multable 1 3 |> Seq.to_list;;
val it : int list = [1; 2; 3; 2; 4; 6; 3; 6; 9]
It's weird to represent a fundamentally 2d structure in this fashion. Why not a sequence of sequences:
let multable2 start stop = seq {
for a = start to stop do yield seq {
for b = start to stop do
yield a*b
}
}
Output:
val multable2 : int -> int -> seq<seq<int>>
> multable2 1 3 |> Seq.to_list;;
val it : seq<int> list = [seq [1; 2; 3]; seq [2; 4; 6]; seq [3; 6; 9]]
If you want to be "clever" and avoid multiplication:
let multable4 start stop = seq {
for a = start to stop do yield seq {
let s = ref 0 in
for b = start to stop do
s:=!s+a
yield !s
}
}
I don't actually see any nice prepackaged "sequence from a to b" outside of comprehensions/sequence expressions, although there's obviously [a..b] (list) and [|a..b|] (array) which you can project through Seq.unfold, Seq.map, etc. to make a Seq.
let Table r c =
[for row in 1..r do
yield [for col in 1..c do
yield row * col]]
printfn "%A" (Table 5 4)
// [[1; 2; 3; 4]; [2; 4; 6; 8]; [3; 6; 9; 12]; [4; 8; 12; 16]; [5; 10; 15; 20]]
Here's another way to use sequences:
let rec fromXToY x y =
seq {
if x <= y
then yield x; yield! fromXToY (x + 1) y;
else ()
}
let scaledSequence factor items =
Seq.map (fun x -> factor * x) items
let mulTable x y =
let sequenceOfIntegersMultipliedByValue = (fun n -> scaledSequence n (fromXToY x y))
let seqOfSeqOfValues = Seq.map sequenceOfIntegersMultipliedByValue (fromXToY x y)
// Convert the sequence of sequences to a simple sequence of values
Seq.fold Seq.append Seq.empty seqOfSeqOfValues