1
\$\begingroup\$

Story:

I build a kind of labyrinth. This labyrinth is divided in seven steps. You start with the first, then second, and so on to the seventh. You cannot go back to a previous step. Each step contains 3 to 5 rooms. Every room of a step is connected to at least one room of the next step. As well, every room of a step is connected to at least one room of the previous one. No hallway (connection between rooms) can cross another hallway. No room can have more than 3 source-rooms, neither more than 3 destination-rooms.

Implementation:

My point is to create a matrix (two-dim array) which depict the connection of a step to its successor. Rows represent the rooms of the source step, and columns the destination step. As I want to practice it, F# is required.

Decisions:

The matrix will only contains 3 values:
- M[i,j] = 1 means that source-room #i is connected to destination-room #j
- M[i,j] = 0 means that source-room can not be connected to destination-room
- M[i,j] = -1 means that source-room can be connected (but is not) to destination-room

Constraints:

  1. Because hallways cannot be crossed, first source-room is imperatively connected to the first destination-room ; same for last rooms.
  2. Because rooms can not have more than three destination-room, the first source-room can only be connected to the three first destination-rooms, and the last destination-room can only be connected to the three last source-rooms.

Code:

module MapConnections =
    let IsUncertain array row col =
        Array2D.get array row col = -1

    let IsDisconnected array row col =
        Array2D.get array row col = 0

    let IsConnected array row col =
        Array2D.get array row col = 1

    let ListUncertain array =
        let mutable list : (int*int) list = list.Empty
        for i  in 0 .. Array2D.length1 array - 1 do
            for j in 0 .. Array2D.length2 array - 1 do
                if IsUncertain array i j then
                    list <- list @ [(i,j)]
        list

    let ListDisconnected array =
        let mutable list : (int*int) list = list.Empty
        for i  in 0 .. Array2D.length1 array - 1 do
            for j in 0 .. Array2D.length2 array - 1 do
                if IsDisconnected array i j then
                    list <- list @ [(i,j)]
        list

    let ListConnected array =
        let mutable list : (int*int) list = list.Empty
        for i  in 0 .. Array2D.length1 array - 1 do
            for j in 0 .. Array2D.length2 array - 1 do
                if IsConnected array i j then
                    list <- list @ [(i,j)]
        list

    let CountUncertain array =
        ListUncertain array |> Seq.length<int*int>

    let CountDisconnection array =
        ListDisconnected array |> Seq.length<int*int>

    let CountConnection array =
        ListConnected array |> Seq.length<int*int>

    let Disconnect array row col =
        if IsUncertain array row col then
            Array2D.set array row col 0
        IsDisconnected array row col

    // Check no-cross rule
    let Connect array row col =
        if IsUncertain array row col then
            Array2D.set array row col 1
            // Disconnect all 'top-right' connections
            for i in 0 .. row - 1 do
                for j in col + 1 .. Array2D.length2 array - 1 do
                    Disconnect array i j |> ignore
            // Disconnect all 'bottom-left' connections
            for i in row + 1 .. Array2D.length1 array - 1 do
                for j in 0 .. col - 1 do
                    Disconnect array i j |> ignore
        IsConnected array row col

    // Check no-more-than-three rule
    let Create rows cols =
        let matrix = Array2D.create rows cols -1
        Connect matrix 0 0 |> ignore
        Connect matrix (rows - 1) (cols - 1) |> ignore
        for i in 3 .. rows - 1 do
            Disconnect matrix i 0 |> ignore
        for i in 0 .. rows - 4 do
            Disconnect matrix i (cols - 1) |> ignore
        for j in 3 .. cols - 1 do
            Disconnect matrix 0 j |> ignore
        for j in 0 .. cols - 4 do
            Disconnect matrix (rows - 1) j |> ignore
        matrix

What I want to be sure:

I want to follow the F# conventions. For example, if lists are non-mutable, I presume that a mutable list is something to avoid?

\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.