What is the immutable version to de/reference array? - arrays

How to de/reference the 3 array variables in this code instead of using mutable values?
The code below computes the Longest common subsequence (LCS) by diagonal traversing the m*n array.
The arguments are 2 char arrays like so:
So LCS method should result to length 4 as the longest common sub-sequence chars are "acbb" & "bcbb".
let private s1 = "ABCDBB".ToCharArray()
let private s2 = "CBACBAABA".ToCharArray()
let public lcs_seq_1d_diags (x:char[]) (y:char[]) =
let m = x.Length
let n = y.Length
let mutable dk2 = Array.create (1+m) 0
//printfn "\r\n0: %A" dk2
let mutable dk1 = Array.create (1+m) 0
//printfn "1: %A" dk1
let mutable dk = Array.create (1+m) 0
for k = 2 to m+n do
let low = max 1 (k-m)
let high = min (k-1) n
for j = low to high do
let i = k - j
if x.[i-1] = y.[j-1] then
dk.[i] <- dk2.[i-1] + 1
else
dk.[i] <- max dk1.[i] dk1.[i-1]
let mutable temp = dk2
dk2 <- dk1
dk1 <- dk
dk <- temp
dk1.[m]
let private res_seq_1d_rows = duration (fun () -> lcs_seq_1d_rows s1 s2)
//res_seq_1d_rows = 4

Take a look at the reference cells http://msdn.microsoft.com/en-us/library/dd233186.aspx
The syntax looks like this:
let a = ref 1 // declaring a reference
a := 2 // changing the reference value
printfn "%i" !a // dereferencing
This might also be interesting: F#: let mutable vs. ref

Arrays are mutable by default. Try using a list instead if you want immutability.
Try starting with this instead:
let s1 = List.ofSeq "ABCDBB"
let s2 = List.ofSeq "CBACBAABA"
The rest I leave as an exercise for the reader :-)

Related

Assign variable to array element where variable and array can be modified independently in ocaml

Here is the problem I can't get around, I'm working in ocaml to copy the elements of an array to a new array. I want to be able to modify these arrays independently from each other, but no matter what I try, a change to one array is reflected in the other array as well.
Here is a simplified example:
type sampleType = { a : int; b : int array };;
let x = {a = 5; b = [|1, 2, 3|] };;
let y = x.b;;
Array.set y 1 6;;
After running these commands I want:
y - : int array = [|1; 6; 3|]
x - : sampleType = {a = 5; b = [|1; 2; 3|]}
Instead x is being changed along with y, and
x - : sampleType = {a = 5; b = [|1; 6; 3|]}
Any solutions to this problem?
As you see from your experiments, this code:
let y = x.b
makes y refer to the very same array as x.b. It doesn't create an independent array. To create an independent array, you need to copy:
let y = Array.copy x.b
I was specifically using 3d arrays, realized I had to apply Array.copy at the lowest level of the 3d array, rather than at the top level.
let arr = Array.init 3 (fun _ -> Array.init 3 (fun _ -> (Array.init 3 (fun _ -> {faces = [|0;1;2;3;4|]}))));;
let drr = Array.init 3 (fun i -> Array.init 3 (fun j -> Array.copy arr.(i).(j)));;
This gave me the result I needed.

F# Finding the Missing element between 2 arrays/lists

`So, I am very new to F#. I hope the issue is simple. I have been doing research and looking around. I have an "Incomplete structured construct at or before this point in expression" error. I feel like it might be something simple or I am way off.
The objective is:
There is an array of non negative integers. A second array is
formed by shuffling the elements of the first
array and deleting a random element. Given these two arrays, find which element is missing in the second
array. Linear searching is not allowed.
let FindMiss list =
match list with
| [] ->
[]
|firstElem::otherElements ->
let rand = new Random
let shuffle (arr : 'a array) =
let array = Array.copy arr
let n = array.Length
for x in 1..n do
let i = n-x
let j = rand.Next(i+1)
let tmp = array.[i]
array.[i] <- array.[j]
array.[j] <- tmp
array
return array
array.[rand].delete
|array::list ->
let d=collections.defaultdict(int)
for num in list do
d[num] +=1
for num in array1 do
if d[num]==0 then return num
else d[num]-=1
printfn "The missing Number is: %A" (FindMiss[4;2;1;7;5;6;3;2])
The task is to reimplement List.except?
If not, just use that 'except' then:
[1;2;3] |> List.except [1;2]
Or was the task "random removal of element in list"? Then this is "the answer": https://stackoverflow.com/a/2889972/5514938
For a start, for more readability, you can take the shuffling and deleting a random element in a separate function. For arrays, they may look like this:
let Shuffle arr =
let rand = System.Random()
arr |> Array.sortBy(fun _ -> rand.Next())
let RemoveRandom arr =
let rand = System.Random()
let lng = arr |> Array.length
let index = rand.Next lng
[|0..lng - 1 |]
|> Array.choose(fun x -> if x = index then None else Some(arr.[x]))
|> Shuffle
Further define the search function:
let FindMiss arr1 arr2 =
let sum1 = arr1 |> Array.sum
let sum2 = arr2 |> Array.sum
sum1 - sum2
Example:
let first = [| 4;2;1;7;5;6;3;2 |]
first |> printfn "%A"
let second = first |> RemoveRandom
second |> printfn "%A"
FindMiss first second |> printfn "Missing value is %i"
Print:
[|4; 2; 1; 7; 5; 6; 3; 2|]
[|2; 2; 3; 7; 1; 5; 6|]
Missing value is 4
Link:
https://dotnetfiddle.net/g6wKUX

How to Generate A Specific Number of Random Indices for Array Element Removal F#

So sCount is the number of elements in the source array, iCount is the number of elements I want to remove.
let indices = Array.init iCount (fun _ -> rng.Next sCount) |> Seq.distinct |> Seq.toArray |> Array.sort
The problem with the method above is that I need to specifically remove iCount indices, and this doesn't guarantee that.
I've tried stuff like
while indices.Count < iCount do
let x = rng.Next sCount
if not (indices.Contains x) then
indices <- indices.Add x
And a few other similar things...
Every way I've tried has been extremely slow though - I'm dealing with source arrays of sizes up to 20 million elements.
What you're doing should be fine if you need a set of indices of negligible size compared to the array. Otherwise, consider doing a variation of a Knuth-Fisher-Yates shuffle to get the first i elements in a random permutation of 1 .. n:
let rndSubset i n =
let arr = Array.zeroCreate i
arr.[0] <- 0
for j in 1 .. n-1 do
let ind = rnd.Next(j+1)
if j < i then arr.[j] <- arr.[ind]
if ind < i then arr.[ind] <- j
arr
I won't give you F# code for this (because I don't know F#...), but I'll describe the approach/algorithm that you should use.
Basically, what you want to do is pick n random elements of a given list list. This can be done in pseudocode:
chosen = []
n times:
index = rng.upto(list.length)
elem = list.at(index)
list.remove-at(index)
chosen.add(elem)
Your list variable should be populated with all possible indices in the source list, and then when you pick n random values from that list of indices, you have random, distinct indices that you can do whatever you want with, including printing values, removing values, knocking yourself out with values, etc...
is iCount closer to the size of the array or closer to 0? That will change the algorithm which you will use.
If closer to 0, then keep track of the previously generated numbers and check if additional numbers have already been generated.
If closer to the size of the array then use the method as described by #feralin
let getRandomNumbers =
let rand = Random()
fun max count ->
Seq.initInfinite (fun _ -> rand.Next(max))
|> Seq.distinct
|> Seq.take count
let indices = Array.init 100 id
let numToRemove = 10
let indicesToRemove = getRandomNumbers (indices.Length - 1) numToRemove |> Seq.toList
> val indicesToRemove : int list = [32; 38; 26; 51; 91; 43; 92; 94; 18; 35]

Why is my recursion faster than Array.exists?

I am pretty new to F#. I'm trying to understand how I can get a fast code in F#. For this, I tried to write two methods (IsPrime1 and IsPrime2) for benchmarking. My code is:
// Learn more about F# at http://fsharp.net
open System
open System.Diagnostics
#light
let isDivisible n d = n % d = 0
let IsPrime1 n =
Array.init (n-2) ((+) 2) |> Array.exists (isDivisible n) |> not
let rec hasDivisor n d =
match d with
| x when x < n -> (n % x = 0) || (hasDivisor n (d+1))
| _ -> false
let IsPrime2 n =
hasDivisor n 2 |> not
let SumOfPrimes max =
[|2..max|] |> Array.filter IsPrime1 |> Array.sum
let maxVal = 20000
let s = new Stopwatch()
s.Start()
let valOfSum = SumOfPrimes maxVal
s.Stop()
Console.WriteLine valOfSum
Console.WriteLine("IsPrime1: {0}", s.ElapsedMilliseconds)
//////////////////////////////////
s.Reset()
s.Start()
let SumOfPrimes2 max =
[|2..max|] |> Array.filter IsPrime2 |> Array.sum
let valOfSum2 = SumOfPrimes2 maxVal
s.Stop()
Console.WriteLine valOfSum2
Console.WriteLine("IsPrime2: {0}", s.ElapsedMilliseconds)
Console.ReadKey()
IsPrime1 takes 760 ms while IsPrime2 takes 260ms for the same result.
What's going on here and how I can make my code even faster?
In IsPrime2, you don't construct a huge array so you could avoid allocating, explicitly traversing and garbage collecting this array. Remember that you call IsPrime1/IsPrime2 function max-1 times in SumOfPrimes so there are many instances of such array. Avoiding creating explicit data structures could be used as an optimization technique.
Here are some small optimizations which could be done on your code.
1) To check for divisors in hasDivisors, you only have to check up to sqrt(n) and skip all even numbers. If no divisor found, the checked number is prime.
let rec hasDivisor2 n d =
match d with
| x when x <= int(sqrt(float n)) -> (n % x = 0) || (hasDivisor2 n (d+2))
| _ -> false
let IsPrime3 n =
n = 2 || (n%2 <> 0 && not (hasDivisor2 n 3))
2) For SumOfPrimes, you could eliminate the intermediate array and also skip all even numbers (they couldn't be prime anyway).
let sumOfPrimes isPrime max =
[|2..max|] |> Array.filter isPrime|> Array.sum
let sumOfPrimes2 isPrime max =
let mutable sum = 2L
for i in 3..2..max do
if isPrime i then
sum <- sum + int64 i
sum
3) I did a small change so that isPrime is passed as an argument. In this way, you can measure your code more easily:
let time fn =
let sw = new System.Diagnostics.Stopwatch()
sw.Start()
let f = fn()
sw.Stop()
printfn "Time taken: %.2f s" <| (float sw.ElapsedMilliseconds)/1000.0
f
let maxVal = 200000
let p2 = time (fun () -> sumOfPrimes IsPrime2 maxVal)
let p3 = time (fun () -> sumOfPrimes2 IsPrime3 maxVal)
The new sumOfPrimes2 function with IsPrime3 is blazingly fast. It took 0.05 seconds on my machine for maxVal = 200000 while the original version took 7.45 seconds.
The reason for the speed difference is that the slow code does something like this:
if n%a.[1] = 0 || n%a.[2]=0 ...
wheras the fast code does:
if n%2=0 || n%(2+1)=0 ...
In the fast case we don't need to go to memory to get the next factor. We also avoid having to build the array in the fast case
Here is my generic very fast F# code to build up a table of primes (from this answer: https://stackoverflow.com/a/12014908/124259):
#time "on"
let limit = 1000000
//returns an array of all the primes up to limit
let table =
let table = Array.create limit true //use bools in the table to save on memory
let tlimit = int (sqrt (float limit)) //max test no for table, ints should be fine
let mutable curfactor = 1;
while curfactor < tlimit-2 do
curfactor <- curfactor+2
if table.[curfactor] then //simple optimisation
let mutable v = curfactor*2
while v < limit do
table.[v] <- false
v <- v + curfactor
let out = Array.create (100000) 0 //this needs to be greater than pi(limit)
let mutable idx = 1
out.[0]<-2
let mutable curx=1
while curx < limit-2 do
curx <- curx + 2
if table.[curx] then
out.[idx]<-curx
idx <- idx+1
out

Array initialization in F#

How do I create and initialize an array in F# based on a given record type?
Suppose I want to create an Array of 100 record1 records.
e.g.
type record1 = {
value1:string;
value2:string
}
let myArray = Array.init 100 ?
But it appears the Array.init does not allow for this, is there a way to do this?
Edited to add:
Of course I could do something like this:
let myArray = [|for i in 0..99 -> { value1="x"; value2="y" }|]
You can use also Array.create, which creates an array of a given size, with all its elements initialized to a defined value:
let myArray = Array.create 100 {value1="x"; value2="y"}
Give a look to this list of array operations.
This should do what you need. Hope it helps.
type record1 = {
value1:string;
value2:string
}
let myArray = Array.init 100 (fun x -> {value1 = "x"; value2 = "y"})
or using Generics
let myArray = Array.init<record1> 100 (fun x -> {value1 = "x"; value2 = "y"})
Or you can create a sequence, instead of creating an array, like this:
// nItems, given n and an item, returns a sequence of item repeated n times
let rec nItems n item =
seq {
match n with
| n when n > 0 -> yield item; yield! nItems (n - 1) item
| _ -> ()
}
type Fnord =
{ foo: int }
printfn "%A" (nItems 99999999 {foo = 3})
// seq [{foo = 3;}; {foo = 3;}; {foo = 3;}; {foo = 3;}; ...]
printfn "%A" (nItems 3 3 |> Seq.toArray)
[|3; 3; 3|]
The nice thing about the sequence, instead of an array, is that it creates items as you need them, rather than all at once. And it's simple to go back and forth between sequences and arrays if you need to.

Resources