SqlJuxt – Active patterns for the win

F# Active Patterns are awesome!! I wanted to start this blog post with that statement. I was not truly aware of F# active patterns until I read the article on F Sharp for Fun and Profit when I was looking at a better way to use the .Net Int32.Parse function.

Active patterns are a function that you can define that can match on an expression. For example:

let (|Integer|_|) (s:string) = 
    match Int32.TryParse(s) with
        | (true, i) -> Some i
        | _ -> None 

To explain what each line is doing the | characters are called banana clips (not sure why) and here we are defining a partial active pattern. This means the pattern has to return Option of some type. So be definition the pattern may return a value or it may not so it is a partial match. This pattern takes a string and then returns Some int if the pattern matches or None if it does not. Once this pattern is defined it can be used in a normal match expression as follows:

let printNumber (str:string) =
	match str with
		| Integer i -> printfn "Integer: %d" i
		| _ -> "%s is not a number" %s

Using this technique it allows us to define a really cool active pattern for matching regular expressions and parsing out the groups that are matched:

let (|ParseRegex|_|) regex str =
    let m = Regex(regex).Match(str)
    match m with 
        | m when m.Success -> Some (List.tail [ for x in m.Groups -> x.Value] )
        | _ -> None

This regex active pattern returns all of the matched groups if the regex is a match or None if it is not a match. Note the reason List.tail is used is to skip the first element as that is the fully matched string which we don’t want, we only want the groups.

The reason why all of this came up is that the getNextAvailableName function that I wrote about in my last blog post is very long winded. For those who haven’t read my last post this function generates a unique name by taking a candidate name and a list of names that have been taken. If the name passed in has been taken then the function will add a number on to the end of the name and keep incrementing it until it finds a name that is not taken. The getNextAvailableName function was defined as:

let rec getNextAvailableName (name:string) (names: string list) =

    let getNumber (chr:char) =
        match Int32.TryParse(chr.ToString()) with
            | (true, i) -> Some i
            | _ -> None

    let grabLastChar (str:string) =
        str.[str.Length-1]

    let pruneLastChar (str:string) =
        str.Substring(0, str.Length - 1)

    let pruneNumber (str:string) i =
        str.Substring(0, str.Length - i.ToString().Length)

    let getNumberFromEndOfString (s:string)  =

        let rec getNumberFromEndOfStringInner (s1:string) (n: int option) =
            match s1 |> String.IsNullOrWhiteSpace with
                | true -> n
                | false -> match s1 |> grabLastChar |> getNumber with
                            | None -> n
                            | Some m ->  let newS = s1 |> pruneLastChar
                                         match n with 
                                            | Some n1 -> let newN = m.ToString() + n1.ToString() |> Convert.ToInt32 |> Some
                                                         getNumberFromEndOfStringInner newS newN
                                            | None -> getNumberFromEndOfStringInner newS (Some m) 
        let num = getNumberFromEndOfStringInner s None
        match num with
            | Some num' -> (s |> pruneNumber <| num', num)
            | None -> (s, num)
        

    let result = names |> List.tryFind(fun x -> x = name)
    match result with
        | Some r -> let (n, r) = getNumberFromEndOfString name
                    match r with 
                        | Some r' -> getNextAvailableName (n + (r'+1).ToString()) names
                        | None -> getNextAvailableName (n + "2") names
                    
        | None -> name

With the Integer and Regex active patterns defined as explained above the new version of the getNextAvailableName function is:

let rec getNextAvailableName (name:string) (names: string list) =

    let result = names |> List.tryFind(fun x -> x = name)
    match result with
        | Some r -> let (n, r) = match name with
                                    | ParseRegex "(.*)(\d+)$" [s; Integer i] -> (s, Some i)
                                    | _ -> (name, None)
                    match r with 
                        | Some r' -> getNextAvailableName (n + (r'+1).ToString()) names
                        | None -> getNextAvailableName (n + "2") names
                    
        | None -> name

I think it is pretty incredible how much simpler this version of the function is. It does exactly the same job (all of my tests still pass:) ). It really shows the power of active patterns and how they simplify your code. I think they also make the code more readable as even if you didn’t know the definition of the ParseRegex active pattern you could guess from the code.

Check out the full source code at SqlJuxt GitHub repository.

SqlJuxt – Building primary keys on a table

There were a few interesting design decisions I had to make when designing the code to script a primary key on a table. Before I dive into them I think it is good to see the finished code, here is a test that uses the TableBuilder to create a clustered primary key on a table:

[<Fact>]
let ``should be able to build a table with a clustered primary key on a mulitple columns``() =
    CreateTable "RandomTableName"
        |> WithInt "MyKeyColumn"
        |> WithInt "SecondKeyColumn"
        |> WithVarchar "ThirdCol" 50
        |> WithVarchar "ForthCol" 10
        |> WithClusteredPrimaryKey [("MyKeyColumn", ASC); ("SecondKeyColumn", DESC); ("ThirdCol", DESC)]
        |> Build
        |> should equal @"CREATE TABLE [dbo].[RandomTableName]( [MyKeyColumn] [int] NOT NULL, [SecondKeyColumn] [int] NOT NULL, [ThirdCol] [varchar](50) NOT NULL, [ForthCol] [varchar](10) NOT NULL )
GO

ALTER TABLE [dbo].[RandomTableName] ADD CONSTRAINT [PK_RandomTableName] PRIMARY KEY CLUSTERED ([MyKeyColumn] ASC, [SecondKeyColumn] DESC, [ThirdCol] DESC)
GO"

What I like about this code is that just from reading it, it is obvious what the code will do. It will create a create table script with 4 columns with a clustered primary key on 3 of those cloumns.

I decided to go with the approach to take the minimal amount of arguments possible in order to define the primary key. Those being the list of column names and sort order of the columns that you want as a primary key. Originally I thought about allowing the user to specify the primary key name but actually this just adds noise to the code. One can be generated using the convention “PK_” + tableName. Also why make the user think about the name for the primary key when all we really care about is that there is a primary key there and that it has a unique name.

I love the way that in f# you can use discriminate unions to represent states to make the code easy to read and work with. In the above example I could have taken many approaches to specify the column sort order such as using a bool to say whether or not the column is ascending. However, if I had gone with that approach then when calling the code you would have ended up with “columnName true” or “columnName false”. This already feels horrible as just from reading the code you do not know what the true or false means. By defining a discriminate union of ASC/DESC you can immediately tell what the parameter is and what it is doing.

The primary key is defined as a constraint as the following type:

type Constraint = {name: string; columns: (Column * SortDirection)  list; isClustered: bool}

Then the table type has been extended to add a Constraint as a primary key using the option type. As a table may or may not have a primary key. It is nice that we can use Option to represent this rather than having to rely on null like we would in an imperative language.

The hardest part to making this work is taking the list of (String * SortDirection) that the WithClusteredPrimaryKey function takes and turning that in to a list of (Column * SortDirection). This is done using the following function:

let private getColumnsByNames (columnNames: (string * SortDirection) list) table =
            columnNames |> List.map(fun (c,d) -> let column = table.columns |> List.tryFind(fun col ->  match col with
                                                                                            | IntColumn i when i.name = c -> true
                                                                                            | VarColumn v when v.name = c -> true
                                                                                            | _ -> false)
                                                 match column with
                                                    | Some col -> (col, d)
                                                    | None -> failwithf "no column named %s exists on table %s" c table.name )

It is great in F# how we can let the types guide us. If you look at the signature of the function above then we can see that it is:

getColumnsByNames (columnNames: (string * SortDirection) list) -> (table:Table) -> (Column * SortDirection) list

When you look at the types you can see that there are not too many ways this function could be implemented. Using what is in the room as Erik Meijer would say we go through the columns on the table and match them up with the column names that were passed in (throwing an exception if a name is passed in that is not on the table) and then return the actual column along with the sort direction.

F# is proving to be an interesting choice in writing the database comparison library. It is a totally different way of thinking but I feel that I’m starting to come to terms with thinking functionally.

If you want to check out the full source code and delve deeper feel free to check out the SqlJuxt GitHub repository.

SqlJuxt – Implementing the builder pattern in F#

As an imperative programmer by trade a pattern that I often like to use is the builder pattern for building objects. This pattern is especially useful for test code.

The reasons the builder pattern is so useful is because:

  • It means you only have to “new” the object up in a single place meaning your test code effectively goes through an API (the builder API) to create the object
  • It makes you code really readable so you can understand exactly what it is doing without having to look into how the code works

In my SqlJuxt project I started by coding it in C#. I wanted a builder to make a table create script. This would mean that in my integration tests I could fluently create a script that would create a table and then I could run it in to a real database and then run the comparison. This makes the tests very readable and easy to write. In C# using the table builder looks like:

    var table = Sql.BuildScript()
                   .WithTableNamed("MyTable", t => t.WithColumns(c => c.NullableVarchar("First", 23)
                                                                       .NullableInt("Second")))

I think that is pretty nice code. You can easily read that code and tell that it will create a table named “MyTable” with a nullable varchar column and a nullable int column.

I wanted to achieve the same thing in F# but the catch is I did not just want to translate the C# in to F# (which is possible) I wanted to write proper functional code. Which means you should not really create classes or mutable types! The whole way the builder pattern works is you store state on the builder and then with each method call you change the state of the builder and then return yourself. When the build method is called at the end you use all of the state to build the object (note an implicit call to the Build method is not needed in the above code as I have overridden the implicit conversion operator).

I hunted around for inspiration and found it in the form of how the TopShelf guys had written their fluent API.

This is how using the table builder looks in F#:

    let table = CreateTable "TestTable"
                    |> WithNullableInt "Column1"
                    |> Build 

I think that is pretty sweet! The trick to making this work is to have a type that represents a database table. Obviously the type is immutable. The CreateTable function takes a name and then returns a new instance of the table type with the name set:

    let CreateTable name =
        {name = name; columns = []}

Then each of the functions to create a column take the table and a name in the case of a nullable int column and then return a new immutable table instance with the column appended to the list of columns. The trick is to take the table type as the last parameter to the function. This means you do not have to implicitly pass it around. As you can see from the CreateTable code above. The Build function then takes the table and translates it in to a sql script ready to be run in to the database.

Here is an example of a complete test to create a table:

    [<Fact>]
    let ``should be able to build a table with a mixture of columns``() =
       CreateTable "MultiColumnTable"
           |> WithVarchar "MyVarchar" 10
           |> WithInt "MyInt"
           |> WithNullableVarchar "NullVarchar" 55
           |> WithNullableInt "NullInt"
           |> Build 
           |> should equal @"CREATE TABLE [dbo].[MultiColumnTable]( [MyVarchar] [varchar](10) NOT NULL, [MyInt] [int] NOT NULL, [NullVarchar] [varchar](55) NULL, [NullInt] [int] NULL )
GO"

I think that test is really readable and explains exactly what it is doing. Which is exactly what a test should do.

If you want to follow along with the project then check out the SqlJuxt GitHub repository.

SqlJuxt – A database comparison tool written in F#

As part of a new project I have decided to write a Sql database comparison tool in F#. I wanted a project that I could learn F# with (having dabbled a bit in the past). I have just finished re-reading the excellent Thinking Functionally series on the F# for fun and profit site. Scott has done a fantastic job on there of explaining F# concepts from the perspective of an imperative programmer. Kudos to Scott for that.

So what is the database comparison tool going to be? Well it is initially going to be an API library written in F# that allows you to compare two Sql databases to find the differences. Then from there I might extend it to allow you to script the differences to make the databases the same and then possibly write a front end for it. The other idea I have in mind is to write a C# shim to allow you to use the library nicely from F#. Although the shim library is not strictly necessary using F# from C# or vice versa can be a bit cumbersome unless you put a bit of effort in to making it work well.

That’s it for now stay tuned as I blog about my foray into the world of functional programming. If you want to keep up with how the project is going then you can check out the Sql Juxt GitHub repository.

Partially applying functions in F#

A cool feature of a functional language like F# is the ability to partially apply a function. Take this add function:

let add x y = x + y

By partially applying this function we can create new functions like this:

let plus1 = add 1
let plus5 = add 5

The functions we have created plus1 and plus5 both have the signature int -> int. We have partially applied add to a single parameter leaving us with a function that takes one more int and returns us an int. This is a really neat idea.

Building on this if we want to do the same thing with subtract we find that it does not quite work:

let subtract x y = x - y
let minus1 = subtract 1
printfn "%i" (minus1 7)

The code above prints -6 when we wanted our minus1 function to subtract 1 from the argument given. This is because unlike with add it matters the order that you give the arguments to subtract. We have another cool trick up our sleeves to solve this:

let subtract x y = x - y
let swap f x y = f y x
let minus = swap subtract
let minus1 = minus 1
printfn "%i" (minus1 7)

The minus1 function above now does what we would expect. To make this work we defined a swap function that swaps the order of the arguments. We can then pass our subtract function to our swap function to produce a new subtract function that takes its arguments in the opposite order. We can now partially apply the new function minus with 1 to give us a new function minus1 that works how we would expect. Having functions as a first class citizen really does lead to some neat code.

Manses and the Stones Hacker Rank Problem in F#

The next problem from Hacker Rank that I’m tackling in F# is a problem called Mansasa and the stones (catchy name). The basics of the problem are that you are given 2 numbers and a length and you have to give all of the distinct sums of those numbers of the lists that can be made up of length l. An example is if stone 1 has the value 2 and stone 2 has the value 4 and the length is 3 we get:

0, 2, 2 = sum 4
0, 2, 4 = sum 6
0, 4, 2 = sum 6
0, 4, 4 = sum 8

Note the problem states that we should start with 0 for each entry. This means that the distinct sums in this example would be 4 6 8 (in order).

My idea to solve this problem was to write a function that takes a list and a length and then gives you all permutations for that list of that length. In the example above if you passed this function 2 and 4 and a length of 2 it would give the 4 possible ways of arranging 2 and 4 shown above. Once I have this function I can simply sum the numbers, do a distinct and then format the result. Simples, or so I thought more on that later.

Now that I’ve got a great way to write tests for my code I started with the unit tests for the function:

module combinations =

 
module combinations =
    []
    let ``combinations for [2;3] of length 2 should be [[2;2];[2;3];[3;2];[3;3]]``() =
        combinations [2;3] 2 |> should equal [[2;2];[2;3];[3;2];[3;3]]

    []
    let ``combinations for [2;3] of length 3 should be [[2;2;2];[2;2;3];[2;3;2];[2;3;3];[3;2;2];[3;2;3];[3;3;2];[3;3;3]]``() =
        combinations [2;3] 3 |> should equal [[2;2;2];[2;2;3];[2;3;2];[2;3;3];[3;2;2];[3;2;3];[3;3;2];[3;3;3]]

    []
    let ``combinations for [1;4] of length 1 should be [[1];[4]]``() =
        combinations [1;4] 1 |> should equal [[1];[4]]

I think it is so neat that the tests describe themselves. I was stuck on writing this function in a recursive way for a little while. I’m still finding it hard to think functionally. I put this problem to my friend Sam Owens who came up with a great solution:

 
let combination list length =
    let rec solve letters len =     
        seq {
            if len = 1 then 
                for l in letters do yield [l]
            else
                let theRest = solve letters (len-1) 
                for l in letters do
                    for r in theRest do 
                        yield l::r
        }
    solve list length

I thought this solution was ingenious. Before I talk through how it works let me show you the more functional version. I created this by translating Sam’s function above to use pattern matching:

let combinations list length =
    let rec solve lst len =
        match len with
        | 1 -> lst |> Seq.map(fun x -> [x])
        | i -> lst |> Seq.map(fun l -> solve lst (len-1) |> Seq.map(fun r -> l::r)) 
                            |> Seq.collect(fun x -> x) 
    solve list length

Both of these functions are exactly the same (kudos to Sam for coming up with this way of doing it). I think the 2nd function is much more elegantly written and more readable. It’s much terser and really shows the power of F#’s pattern matching.

This function works by the fact that it knows how to print out every combination of a list of length 1. Which is shown on the first line of the match statement. To do this it simply maps out all of the elements as a list of one item. If the function is called with a length greater than one then it calls itself with length – 1 and appends the results from that on to each element in the list passed in.

With this function written composing the function to solve the whole problem was pretty straight forward:

let findMansaNumbers steps (stone1:int) (stone2:int) =
    combinations [stone1; stone2] (steps-1) |> Seq.map(fun l -> Seq.sum(l)) 
                                            |> Seq.distinct 
                                            |> Seq.sort
                                            |> fun x -> String.Join(" ", x)

All we have to do is run the combinations function passing it a list of the two stone numbers and a length. We then sum the numbers from each combination, get a distinct list of the sums, sort them in to order and then print them out in a string where each number is separted by a space. The way that F# lends itself well to composing small building blocks together makes it a fun language to program in.

Here comes the kicker. Although this solution works, it passes the first three test cases on the hacker rank problem page it then times out. The reason for this is that the number of combinations the combinations function will return is given by the formula 2^length. This is exponential growth so for big lengths the time to compute all combinations is too long. As a short aside the fact that hackerrank run the code on their server and then time out if your solution takes too long is a good thing. It stops you from being able to brute force the problems which is one of the things that plagues project Euler in my opinion.

So it’s back to the drawing board with this problem. The code is on the repository under slow solution in the MansasaAndStones.fs file in the Hacker Rank in F# repository on github.

To solve this problem it is actually very straight forward. I was just taking completely the wrong approach. If you think of the case where you have 2 stones of values 2 and 4 and are asked to find 3 steps then you can think of this as:

0, 4, 4 = sum 8 = (0*2) + (2*4)
0, 2, 4 = sum 6 = (1*2) + (1*4)
0, 2, 2 = sum 4 = (2*2) + (0*4)

So the distinct sums are 4, 6 and 8. This is calculated by having two loops, one starting and 0 and incrementing, one starting at the number of steps – 1 (as we the first step is always 0 in the problem) and then multiplying one of the loops by the first stone and one by the second.

let findNumbers steps (stone1:int) (stone2:int) =
    let list1 = [0..steps-1]
    let list2 = [0..steps-1] |> List.rev
    List.zip list1 list2 |> Seq.map(fun (x, y) -> (x*stone1)+(y*stone2))
                         |> Seq.distinct
                         |> Seq.sort
                         |> fun x -> String.Join(" ", x)

The code above is the full solution to the problem. Instead of looping twice we use the zip function to produce tuples of the loop values we can then feed this into the map function which makes the code neater. After that we just have to make sure the list is distinct (as the problem states no duplicates) and then sort it (as the problem states that the values should be in order) then we have to produce a space separated string for each answer.

I really went around the houses with this problem but I did learn some cool things in F#. Solving the combinations problem was fun and helped me practice my skills of turning C# into functional F#. Once I realised I only needed two loops I was quite happy with how nice the solution is. One thing I’m learning more and more about functional programming is that you can write really expressive beautiful code. Erik Meijer would be proud!

To look at the final solution check out the ManasaAndStones module and the solution function from the github repository. As always I would be keen to hear your feedback.

Grid Search Problem Solved Using F#

As mentioned in my last post I’ve recently got into solving HackerRank problems in F#. I’m trying to use F# with a functional programming style not writing in an imperative style as I would in C# and use the F# syntax (which is possible).

I want to go through how I solved the Grid Search Problem so if you don’t want to know a solution look away now!

The problem is that you are given two grids of numbers and you have to write “YES” if the second grid is contained anywhere in the first grid and “NO” if it isn’t.

I’m quite new to functional programming but the way I approached this was to break the problem up into smaller functions and then the answer would be a composition of those smaller functions.

If you clone my HackerRankInFSharp repository from github it contains all of the code that you can follow along to. To view the code for this problem open the file GridSearch.fs in the HackerRank project.

At the bottom of the GridSearch.fs file you will see a solution function defined. This function runs the test case from the input file and is where you should start reading the file from.

When you run your code on hackerrank your program needs to interact with the console. To save typing the inputs in each time I wanted to test my program I copied the test cases into a text file and then simply mapped a read function to reading a line from a file like so:

let reader = new StreamReader("TextFile1.txt")
let read = reader.ReadLine

This is one of the neat things about F#. As it’s a functional language and functions are first class citizens you can assign them into variables and then just pass them around. By writing my code in this way I could simply copy all of my solution into HackerRank when it is complete and just change the read function to map to console readline (let read = Console.ReadLine) and leave the rest of my code the same.

The next three functions that I wrote are to help read the input data:

let t = read() |> Convert.ToInt32

let num = fun() -> read().Split(' ') 
                |> Seq.head
                |> Convert.ToInt32

let fetch = fun() -> [for _ in 1..num() do yield read()]  

The first two simply read the values for t (the amount of test cases) and num I use to be the amount of rows in the grid. The input data also gives you the length of each row but as the rows are separated by new lines you don’t need this. The last function fetch returns a sequence of strings of length num (the amount of rows in the grid). The function fetch will be used to read a grid into a variable and is generic so can be used both for the reference and search grids. The terminology I’m going to use is reference grid to refer to the bigger grid and search grid will be what we are looking for inside the reference grid.

Now I’ve got the input my idea was to write a function get all indexes of a smaller string in a bigger string. The reason for this is that I thought to search for the search grid inside the reference grid we would first start with just the first line of the search grid. We want to look at each line of the reference grid and know if the first line of the search grid is contained within it. If it is we want to a list of the indexes of where it is.

let allIndexOf (str:string) (c:string) =
    let rec inner (s:string) l offset =
        match (s.IndexOf(c), (s.IndexOf(c)+1) = s.Length) with
        | (-1, _) -> l
        | (x, true) -> (x+offset)::l
        | (x, false) -> inner(s.Substring(x+1)) ((x+offset)::l) (x+1)
    inner str [] 0

In my last post I talked about the awesome help I got off the community with this function. This function works recursively which is one of the mantras of functional programming. allIndexOf takes 2 strings. The first string is the reference string (str) and the second string is the one you are looking for (c). The first line of the function declares a recursive function that takes a string (s) a list of int (l) and an int (offset). There are a few interesting points on this line. Firstly the keyword “rec” is not optional, it means it is a recursive function. The next interesting part is that the parameters l and offset do not have any type annotations. This is one of the things that makes F# very clean. The reason for this is that the compiler can figure out the types of the functions nearly all of the time for you so the type annotations are completely optional. This removes a lot of the excess clutter. The next line (match) is another very cool feature of F# The pattern matching. What it is saying is create a tuple that as the values (s.IndexOf(c), (s.IndexOf(c) +1 = s.Length)) which is of type (int, bool). Once that tuple is created it is then matched on one of the next three lines. If s.IndexOf(c) returns -1 then it doesn’t matter what the second part of the tuple is as we match with the wildcard _. In that case we return l the list that was passed in. If the s.IndexOf(c) evaluates to anything other than -1 then we match the 2nd line if the bool part is true. If the bool part is false then we match the last line. The last line of the function then calls the recursive function with the string you have passed in, an empty list and an offset of 0.

To see how this function works lets look at a simple example if we pass in “hello hell” and “hell” we would expect the indexes returned to be 0, 6. When we call the function inner with “hello hell” [] 0. The match clause will then produce the tuple (0, false) which will match to the third line. This will then call inner again with “ello hell” [0] 1. This time the match clause will evaluate to (2, false) which will then call inner with “ell” [0, 6] 6. This time the match clause will return the tuple (-1, false) so it will match with the first line of the match clause and return the list [0, 6] which is the correct answer.

The way you can combine functions together to perform the tasks you need will become clear as I go through the rest of the solution. The next function uses the allIndexOf function to return the co-ordinates of every occurrence of a string in a list of strings (aka a grid).

let find g str start = g  |> Seq.skip start
                          |> Seq.mapi (fun i x -> (allIndexOf x str) |> Seq.map (fun u -> (u, i+start))) 
                          |> Seq.collect (fun x -> x)

You can read the |> operator as pipes data from left to right. What we are doing here is for each row in the grid skipping as many rows as are passed in via the start parameter (note this is an optimisation as further on we can reuse this function to search the remainder of the grid). We then pipe the result from that into a map function that returns a tuple where the first element is the index of the string (x co-ordinate) and the indexer is the y co-ordinate of the string. The y co-ordinate of the string is known as we are looping through each string in the grid using the mapi function. The mapi function gives you each element (x) and the index of the element (i). The index of the element will be the y co-ordinate as that corresponds to the row in the grid. We then have to use the Seq.collect function to unwind a double sequence. This is the equivalent to a select many.

let findExact g str x y = find g str y
                              |> Seq.exists(fun (a, b) -> x = a && y = b)

The findExact function then extends the find function to return a bool if and only if that string is found in the grid at the co-ordinates specified. The reason for this function is my idea to solve the problem is to call the find function for the first row of the search in the reference grid giving you all of the co-ordinates of where that appears. Then all you need to do to tell if the whole search grid is there is loop through subsequent rows and add one on to the y co-ordinate each time. For example if we called find and we got back (2, 3) and (5, 6) and the search grid was 3 strings deep. Then to tell if the search grid is in the reference grid we would simply need to know if the second string was at (2, 4) and the third at (2, 5) or if the second string was at (5, 7) and the third at (5, 8). In either case the answer is yes, if any of those return false the answer is no.

let gridContains g (s: string list) = 
    let matches = find g s.[0] 0 
    let numStrs = s |> Seq.skip 1
        |> Seq.mapi(fun i line -> (i, line))
    matches |> Seq.map(fun (a, b) -> numStrs |> Seq.map(fun (i, line) -> findExact g line a (b+i+1)))
        |> Seq.exists(fun b -> b |> Seq.forall(fun x -> x))

The function above does exactly that. The first row assigns all of the co-ordinates of the first row of the search grid that are found in the reference grid into the variable matches. The next line essentially numbers each string in the search grid but not the first row making it easier to write the last part of the function. The last part of that function then pipes matches into a function that for each co-ordinate in matches adds on i (the current loop value) to the y value and 1 (due to 0 starting value) and returns a bool as to whether that string is contained in that position. That will then return a sequence of sequence of bool. The last part is then to see if any of those sequences of bool contain a set of all true. It even reads how I’ve just described it “does a sequence exist where there is a sequence for all of which are true”.

To run the solution clone theHackerRank repo on github. Then in the program.fs file uncomment the line //GridSearch.solution.

I’m still new to functional programming so if there is anything you would improve or do different please feel free to leave a comment below.