Samsung Semiconductor Institute of Research(SSIR Software) intern/FTE | Set-3

We are given m*n matrix which can have a number between 0 and 7. Each number represents a pipe with a shape as follows:
Pipes

Two pipes are considered connected if their end points connect.

Example:
If matrix is as follows:
0040
1360
5000

Pipe 1 and 3{1 opens to right. 3 opens to left} are connected. Other connected pipes are 3 and 6(3 opens to right. 6 opens to left).

4 and 6 are not connected as 6 does not open to top, and 4 does not open to bottom.



1 and 5 are also not connected as even though 1 opens to bottom, 5 is not open to top.

Given this matrix, start point (X, Y) and length of probe tool “L”, find out how many pipes{matrix elements} can be reached.
Note: Probe tool: is a measuring tool, if 6 pipes can be reached but length of probe tool is 4. Answer will be 4 if 3 pipes can be reached but length of probe tool is 4. Answer will be 3.

Example:
Starting index: (1, 0)
Length of probe: 4
Matrix:
0040
1360
5000
connected pipes via probe- (1, 0)->(1, 1)->(1, 2)
Ans- 3

Starting index: (0, 0)
Length of probe: 4
Matrix:
0040
1360
5000
connected pipes via probe- 0
Ans- 0

Starting index: (1, 0)
Length of probe: 2
Matrix:
0040
1360
5000
connected pipes via probe- (1, 0)->(1, 1)
Ans- 2

Key Steps to solve:
Find which of the neighboring pipe elements can be accessed from one starting point {Maintaining exhaustive list of checks to ascertain neighboring criteria as defined above}.

Find a method to process through the elements to find the next set of elements which can be accessed. {Traversing through the graph}. It should be noted that we wish to reach all nodes which are accessible from start node with distance less than “L”. The focus is not on reaching lot of nodes, but on reaching them with lesser moves from start point (X, Y).

Recursion:

We mark all the nodes as unvisited and visited node count as 0. If a node marked as unvisited is processed during recursion, increment visited node count by 1 and mark it as visited.
We start by visiting Start node (X, Y) and then recursively visiting all its connected neighbors (based on checks for connected criteria as defined above) till the recursion depth of “L”.
Drawback:
In case of highly connected matrix (almost all pipes are connected together and multiple ways to reach a pipe exists), we reach a node multiple times and process it multiple times which may lead to high running time. We can optimize it by checking that we process a node again only if we have reached it with a lower recursion level.

This is not a DFS solution because we reprocess a node, even if already visited, as it is possible that the new visit may update the visiting depth of the node to lower level and greater depth be reached after this node.



Breadth-First Search:
We mark all the nodes as unvisited and visited node count as 0. If a node marked as unvisited is processed during processing, increment visited node count by 1.
We start by pushing the start node (X, Y) into a queue with depth 1 and then start processing the queue till it is empty.

In each iteration a member of queue is taken out and its connected neighbors are analyzed. If neighbors are unvisited and depth of current element is not greater than L, connected elements are put into queue, marked visited and visited node count increased by 1.

As BFS performs level order traversal of nodes, it is not possible that a visited node be reached in a smaller distance. So, drawback of previous method cannot exist. This is the optimal solution for this problem.

Simplification possible in the solutions for easy coding:

Since there are 7 types of pipes, we will have to put multiple if conditions leading to nested if statements which are difficult to debug. It can be simplified by converting the 7 values into direction based data. For e.g. each value can be transformed into a structure with 4 Boolean variables, one for each direction. Alternatively, each number can be mapped to a 4 bit number where each bit represents a direction. After this input reduction, checks will become simpler and with less complexity.

filter_none

edit
close

play_arrow

link
brightness_4
code

#include <bits/stdc++.h>
using namespace std;
#define Max 1000
#define row_size 3
#define col_size 4
  
int x = 1, y = 0; // starting index(x, y),
int l = 4; // length of probe tool
  
// input matrix containing the pipes
int mt[row_size][col_size] = { { 0, 0, 4, 0 },
                               { 1, 3, 6, 0 },
                               { 5, 0, 0, 0 } };
  
// visited matrix checks for cells already visited
int vi[row_size][col_size]; 
  
// calculates the depth of connection for each cell
int depth[row_size][col_size]; 
  
int f = 0;
int r = 0;
  
// queue for BFS
struct node {
    int x;
    int y;
    int d;
};
node q[Max];
void push(int a, int b, int d) // push function
{
    node temp;
    temp.x = a;
    temp.y = b;
    temp.d = d;
    q[r++] = temp;
    vi[a][b] = 1;
}
node pop() // pop function
{
    node temp;
    temp.x = q[f].x;
    temp.y = q[f].y;
    temp.d = q[f].d;
    f++;
    return temp;
}
  
// It can be simplified by converting the 7
// values into direction based data. For e.g. 
// each value can be transformed into a structure
// with 4 Boolean variables, one for each direction. 
// Alternatively, each number can be mapped to a 4
// bit number where each bit represents a direction.
bool s1(int i, int j) // conversion to final direction
{
    if (i >= 0 && i < row_size && j >= 0 &&
        j < col_size && vi[i][j] == 0 && (mt[i][j] == 1 || 
        mt[i][j] == 3 || mt[i][j] == 6 || mt[i][j] == 7))
        return true;
    else
        return false;
}
  
bool s2(int i, int j) // conversion to final direction
{
    if (i >= 0 && i < row_size && j >= 0 && j < col_size && 
        vi[i][j] == 0 && (mt[i][j] == 1 || mt[i][j] == 2 ||
        mt[i][j] == 4 || mt[i][j] == 7))
        return true;
    else
        return false;
}
bool s3(int i, int j) // conversion to final direction
{
    if (i >= 0 && i < row_size && j >= 0 && j < col_size &&
        vi[i][j] == 0 && (mt[i][j] == 1 || mt[i][j] == 3 ||
        mt[i][j] == 4 || mt[i][j] == 5))
        return true;
    else
        return false;
}
bool s4(int i, int j) // conversion to final direction
{
    if (i >= 0 && i < row_size && j >= 0 && j < col_size && 
       vi[i][j] == 0 && (mt[i][j] == 1 || mt[i][j] == 2 || 
       mt[i][j] == 6 || mt[i][j] == 5))
        return true;
    else
        return false;
}
  
// search for connection
// We start by pushing the start node (X, Y) into a queue
// with depth 1  and then start processing the queue till 
// it is empty.
void bfs(int x, int y, int d) 
{
    push(x, y, d);
    while (r > f) {
        node temp = pop();
        int i = temp.x;
        int j = temp.y;
        int c = temp.d;
        depth[i][j] = c;
  
        if (mt[i][j] == 1 || mt[i][j] == 3 ||
            mt[i][j] == 4 || mt[i][j] == 5) {
            if (s1(i, j + 1))
                push(i, j + 1, c + 1);
        }
        if (mt[i][j] == 1 || mt[i][j] == 2 ||
            mt[i][j] == 6 || mt[i][j] == 5) {
            if (s2(i + 1, j))
                push(i + 1, j, c + 1);
        }
        if (mt[i][j] == 1 || mt[i][j] == 3 ||
            mt[i][j] == 7 || mt[i][j] == 6) {
            if (s3(i, j - 1))
                push(i, j - 1, c + 1);
        }
        if (mt[i][j] == 1 || mt[i][j] == 2 ||
            mt[i][j] == 4 || mt[i][j] == 7) {
            if (s4(i - 1, j))
                push(i - 1, j, c + 1);
        }
    }
}
int main() // main function
{
  
    f = 0;
    r = 0;
    // matrix
    for (int i = 0; i < row_size; i++) {
        for (int j = 0; j < col_size; j++) {
  
            // visited matrix for BFS set to 
            // unvisited for every cell
            vi[i][j] = 0; 
  
            // depth set to max intial value
            depth[i][j] = Max;
        }
    }
  
    if (mt[x][y] != 0) // condition for BFS
        bfs(x, y, 1);
  
    int nc = 0;
    for (int i = 0; i < row_size; i++) {
        for (int j = 0; j < col_size; j++) {
            if (depth[i][j] <= l) {
                cout << "(" << i << ", " << j << ")";
                nc++;
            }
        }
    }
    cout << " " << nc << "\n";
}

chevron_right


Output:

(1, 0)(1, 1)(1, 2) 3


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.