// Counts the neighbors of alive or dead cells in boolean grid.
public static int countNeighbors ( final boolean[][] grid, final int row, final int col ) {
// Finds neighbors in top row.
int count = 0;
for (int i = 1; i > -1; --i) {
if (grid[row - 1][col + i] == true)
count += 1;
else if (grid[row - 1][col + i] == false)
count += 0;
}
// Finds neighbors in same row.
for (int i = 1; i > -1; --i) {
if (grid[row][col + i] == true)
count += 1;
else if (grid[row][col + i] == false)
count += 0;
}
// Finds neighbors in bottom row.
for (int i = 1; i > -1; --i) {
if (grid[row + 1][col + i] == true)
count += 1;
else if (grid[row + 1][col + i] == false)
count += 0;
}
return count;
}
Getting an array out of bounds exception when I attempt to find all true neighbor values in all 8 blocks around the specified square.
I figured the code would already handle if it was out of bounds as I assume those values would be false anyways.
Create a separate function to get the grid cell, including a bounds check:
public static boolean getGridCell ( final boolean[][] grid, final int row, final int col )
{
// bounds check:
if((row < 0) || (row >= grid.length))
return false;
if((col < 0) || (col >= grid[row].length))
return false;
return grid[row][col];
}
Then call this function instead of accessing the grid directly:
public static int countNeighbors ( final boolean[][] grid, final int row, final int col ) {
// Finds neighbors in top row.
int count = 0;
for (int i = 1; i >= -1; --i) {
if (getGridCell(grid, row - 1,col + i))
count += 1;
}
// Finds neighbors in same row.
for (int i = 1; i >= -1; --i) {
if (getGridCell(grid, row, col + i))
count += 1;
}
// Finds neighbors in bottom row.
for (int i = 1; i >= -1; --i) {
if (getGridCell(grid, row + 1, col + i))
count += 1;
}
return count;
}
Also:
There's no need to check if the grid cell is empty and add zero to count if it is, because that isn't going to make any difference to the count.
You don't need to test if(some_boolean == true), you can just write if(some_boolean)
Your loop termination condition should be >= -1 not > -1, if you intend include -1.
Related
Given a NxN matrix (which contains Boolean values - true / false).
We will define:
true region in an array as a maximum collection of adjacent cells that all have a true value.
Cells located diagonally to each other are not considered adjacent.
In this example, there are 3 true areas:
True Regions
My Solution attemp in Java:
public static int (boolean[][] mat) {
return GetTrueRegions(mat, 0, 0);
}
public static int GetTrueRegions(boolean[][] m, int i , int j) {
final boolean VISITED = false;
if (i == m.length - 1 && j == m[0].length - 1)
return 0;
// avoid repeat a cell
boolean temp = m[i][j];
m[i][j] = VISITED;
// recursion for all neighbors
int up = -1, down = -1, left = -1, right = -1;
if (i - 1 >= 0 && m[i-1][j] )
up = GetTrueRegions(m, i - 1, j);
if (i + 1 < m.length && m[i+1][j])
down = GetTrueRegions(m, i + 1, j);
if (j - 1 >= 0 && m[i][j-1])
left = GetTrueRegions(m, i, j - 1);
if (j + 1 < m[0].length && m[i][j+1] )
right = GetTrueRegions(m, i, j + 1);
// couldn't find a path
if (temp) {
return 1 + GetTrueRegions(m, i, j + 1);
}
if (up == -1 && down == -1 && left == -1 && right == -1 )
return GetTrueRegions(m, i, j +1);
return up + down + left + right;
}
this obviously not working.
I was thinking about going through each cell, and if the cell has true value, adding 1 to the total regions(somehow), and put the value false to him and to each adjacent cell(mark the region as "visited").
though I find it hard for me to get the base cases, and how to get every region value.
try to look at something like that:
public static int GetTrueRegions(boolean[][] mat)
{
return GetTrueRegions(mat, 0, 0);
}
private static int GetTrueRegions(boolean[][] m, int i, int j)
{
if (j == m[0].length)
return 0;
if (i == m.length)
return GetTrueRegions(m, 0, j + 1);
// found a region
if (m[i][j])
{
// mark the entire region, to avoid duplications
markRegionAsFalse(m, i, j);
// count 1 region and proceed
return 1 + GetTrueRegions(m, i + 1, j);
}
// proceed...
return GetTrueRegions(m, i + 1, j);
}
private static void markRegionAsFalse(boolean[][] matrix, int row, int col)
{
// just visited...
matrix[row][col] = false;
if(row - 1 >= 0 && matrix[row - 1][col]) // move up and mark cell if true
markRegionAsFalse(matrix, row - 1, col);
if (row < matrix.length - 1 && matrix[row + 1][col]) // move down and mark cell if true
markRegionAsFalse(matrix, row + 1, col);
if (col < matrix.length - 1 && matrix[row][col + 1]) // move right and mark cell if true
markRegionAsFalse(matrix, row, col + 1);
if(col - 1 >= 0 && matrix[row][col - 1]) // move left and mark cell if true
markRegionAsFalse(matrix, row, col - 1);
}
I got a homework assignment, I have to find a recursive function that gets a 2D matrix and the number of rows in a matrix and returns true / false If the diagonal of the matrix has a sequence of letters a b c,
Can not think of a solution
public static void main(String[] args) {
char[][] mat = new char[5][5];
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat[i].length; j++)
mat[i][j] = (char) (int) ((Math.random() * 26) + 'a');
}
for (int i=0 ; i <mat.length ; i++)
mat[i][i] = (char)('a' + i);
//mat[2][2] = 'b';
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat[i].length; j++)
System.out.print(mat[i][j] + " ");
System.out.println();
}
System.out.println(isDiagonalLettersSequence(mat, mat.length));
}[Here are two examples that I hope will help me explain myself][1]
https://i.stack.imgur.com/Z6qmn.png
This is pretty simple. Just check on each iteration if the current value is equals to previous +1:
public static boolean isDiagonalHasSequence(char[][] matrix) {
return isDiagonalHasSequence(matrix, 0);
}
private static boolean isDiagonalHasSequence(char[][] matrix, int row) {
if (row > 0 && row < matrix.length) {
// check diagonal \
if (matrix[row][row] != matrix[row - 1][row - 1] + 1)
return false;
// check diagonal /
if (matrix[row][matrix.length - row - 1] != matrix[row - 1][matrix.length - row - 2] + 1)
return false;
}
return row == matrix.length || isDiagonalHasSequence(matrix, row + 1);
}
In the main function:
String[][] arr = { {"a","e","d"},
{"h","b","c"},
{"f","f","c"}};
if(diagonal(arr, 0).equals("abc"))
System.out.print("true");
And the global recursive function should be:
public static String diagonal(String[][] arr, int i) {
if(i == arr.length - 1)
return arr[i][i];
return arr[i][i] + diagonal(arr, i + 1);
}
I am trying to find the expected output to the below program..But I am getting the error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at programbasics.CountingConnections.count(CountingConnections.java:7)
at programbasics.CountingConnections.main(CountingConnections.java:26)
My question is about a matrix m*n. The elements in matrix are populated with values 1 and 0.
1 indicates in establishing connection and 0 indicates Not establishing connection.
we need to connect the available adjacent positions vertically, horizontally and diagonally and count the number of distinct connections established
My piece of code is
package programbasics;
class CountingConnections
{
static int count(int a[][], int i, int j) {
int rows = a.length;
int cols = a[0].length;
if(a[i][j] == 0) return 0;
if (i == rows - 1 && j == cols - 1)
return a[i][j];
else if (i == rows - 1)
return a[i][j + 1];
else if (j == cols - 1)
return a[i + 1][j];
else if (a[i][j] == 1)
return count(a, i + 1, j) + count(a, i, j + 1);
else
return 0;
}
public static void main(String[]args)
{
int a[][] = {{1,0,0,1},
{0,1,1,1},
{1,0,0,1}};
int i = 3;
int j = 4;
System.out.println(count(a, i, j));;
}
}
The expected output is 8. Like the positions are connected as follows
1)(0,0) -> (1,1)
2)(2,0) -> (1,1)
.
.
.
.
8) (0,3) -> (1,3)
It fails to get the expected output 8.
public static int count(int[][] a) {
int[][] paths = new int[a.length][a[0].length];
if ((paths[0][0] = a[0][0]) == 0) {
return 0;
}
for (int c = 1; c < a[0].length; c++) {
paths[0][c] = a[0][c] * paths[0][c - 1];
}
for (int r = 1; r < a.length; r++)
{
paths[r][0] = a[r][0] * paths[r - 1][0];
for (int c = 1; c < a[r].length; c++)
{
paths[r][c] = a[r][c] * (paths[r - 1][c] + paths[r][c - 1]);
}
}
return paths[a.length - 1][a[0].length - 1];
}
public static int count(int[][] a, int m, int n) {
int count = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (a[i][j] == 1) {
if (i - 1 >= 0 && j - 1 >= 0 && a[i - 1][j - 1] == 1) {
count = count + 1;
}
if (i - 1 >= 0 && a[i - 1][j] == 1) {
count = count + 1;
}
if (i - 1 >= 0 && j + 1 < n && a[i - 1][j + 1] == 1) {
count = count + 1;
}
if (j + 1 < n && a[i][j + 1] == 1) {
count = count + 1;
}
}
}
}
return count;
}
You call if(a[i][j] == 0) in your code where you pass 3 as i and 4 as j. However Array's are zero indexed, so when you try to call a[3][4] you are trying to call
0 1 2 3 4
0 {1, 0, 0, 1}
1 {0, 1, 1, 1}
2 {1, 0, 0, 1}
3 X
4
The index where the X is. Clearly this is not a valid index in your Array.
Also your method at different points calls a[i + 1][j] and a[i][j + 1] which means that you will have to take this in account when making sure the code stays in bounds.
As to your actual method your logic seems a bit off. if(a[i][j] == 0) return 0; will return 0 and stop the recursion and return 0 without checking to see if there are any more connections. Your logic should be something more like this:
Start at 0,1.
If the index is a 1
Look one index to the right, one down and to the right (The diagonal) down one, and down one and to the left (The second diagonal).
If any of the numbers at those index's are 1's then up the counter.
Continue to iterate through the matrix, but keep in mind that you are checking one row down and over, so you will only loop until less than length -1 for for both the row and column. Also make sure that you are starting at index a[i][1] as you will be needing to check a[a+1][j-1] and if j == 0 you will be trying to call a[a+1][-1] which will cause another index out of bounds
private int countConnections(int[][] a, int rows, int columns) {
//cartesian plane coordinates around a point
final int[] x = {1, 1, 1, -1, -1, -1, 0, 0};
final int[] y = {1, -1, 0, 1, -1, 0, 1, -1};
int count = 0;
boolean[][] visited = new boolean[rows][columns];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
for (int k = 0; k < 8; k++) {
int l = i + x[k];
int m = j + y[k];
//check for connections only if the given cell has value 1
if (a[i][j] == 1 && canVisit(l, m, rows, columns, visited) && a[l][m] == 1) {
count++;
}
}
visited[i][j] = true;
}
}
return count;
}
private boolean canVisit(int i, int j, int rows, int columns, boolean [][] visited) {
return i < rows && j < columns && i >= 0 && j >= 0 && !visited[i][j];
}
Check all the 8 cells around a cell whose cell value is 1 and when traversed mark it as visited.
I need to find the maximum number of consecutive points in a straight line(row,column or diagonal) in a matrix .
For eg:- if it is a 4*4 matrix
input is (1#1,2#2,3#3,2#1) the answer should be 3 as the max consecutive points in diagonal is 3.
My code is successfully getting executed with expected results.But the code complexity is very high.
Can someone please suggest the best approach complexity wise.
Below is my code:
// Get the max number of Continuous points in a matrix row
private static int getMaxContinuousPointsInRow(boolean[][] matrix, int row){
int maxCount = 0;
int currCount = 0;
int pos = 0;
while(pos < matrix[row].length){
currCount = 0;
while(pos < matrix[row].length && !matrix[row][pos])
pos++;
if(pos >= matrix[row].length)
break;
while(pos < matrix[row].length && matrix[row][pos]){
currCount++;
pos++;
}
if(currCount > maxCount)
maxCount = currCount;
}
return maxCount;
}
// Get the max number of Continuous points in a matrix row
private static int getMaxContinuousPointsInCol(boolean[][] matrix, int col) {
int maxCount = 0;
int currCount = 0;
int pos = 0;
while (pos < matrix.length) {
currCount = 0;
while (pos < matrix.length && !matrix[pos][col])
pos++;
if(pos >= matrix.length)
break;
while (pos < matrix.length && matrix[pos][col]) {
currCount++;
pos++;
}
if (currCount > maxCount)
maxCount = currCount;
}
return maxCount;
}
// Get the max number of Continuous points in a matrix diagonal right starting from position (row,col)
private static int getMaxContinuousPointsInDiagonalRight(boolean[][] matrix, int row, int col) {
int maxCount = 0;
int currCount = 0;
int i = row, j = col;
while (i < matrix.length && j < matrix[row].length) {
currCount = 0;
while (i < matrix.length && j < matrix[row].length && !matrix[i][j]){
i++;
j++;
}
if(i >= matrix.length || j >= matrix[row].length)
break;
while (i < matrix.length && j < matrix[row].length && matrix[i][j]) {
currCount++;
i++;
j++;
}
if (currCount > maxCount)
maxCount = currCount;
}
return maxCount;
}
public static int function_called_by_main_method(int input1, int input2, String[] input3) {
// create a boolean matrix of size input1 x input2
// M[i][j] = true if input3 contains a point i#j, else M[i][j] = false
boolean M[][] = new boolean[input1 + 1][input2 + 1];
// initialize the matrix with all false values
for(int i=0; i <= input1; i++){
for(int j=0; j <= input2; j++){
M[i][j] = false;
}
}
// process each value in input3 and populate the matrix
for (String s : input3) {
// extract row, column value
String[] data = s.split("#");
int i = Integer.parseInt(data[0]);
int j = Integer.parseInt(data[1]);
M[i][j] = true;
}
// get max number of Continuous points among all matrix rows
int max = 0;
for(int row = 0; row <= input1; row++){
int rowMax = getMaxContinuousPointsInRow(M, row);
if(rowMax > max)
max = rowMax;
}
// get max number of Continuous points among all matrix rows and columns
for (int col = 0; col <= input2; col++) {
int colMax = getMaxContinuousPointsInCol(M, col);
if (colMax > max)
max = colMax;
}
// get max number of Continuous points among all matrix rows, columns and right diagonals
for(int col = input2 ; col >= 0; col--){
int diagMax = getMaxContinuousPointsInDiagonalRight(M, 0, col);
if(diagMax > max)
max = diagMax;
}
for(int row = 1 ; row <= input1; row++){
int diagMax = getMaxContinuousPointsInDiagonalRight(M, row, 0);
if(diagMax > max)
max = diagMax;
}
return max;
}
You could try parallelism with the java 8 streams, on a dumb brute force approach.
class Coord {
int i;
int j;
}
List<Coord[]> allLineCoords = calculateLinesForMatrix(rows, columns);
Comparator<Coord[]> comparator = (coords1, coords2) ->
length(matrix, coords1) - length(matrix, coords2);
Coord[] maxCoords = allLineCoords.parallelStream()
.max(comparator);
// or for just the max length:
int maxLength = (int) allLineCoords.parallelStream()
.mapToInt(coords -> length(matrix, coords))
.max();
Very unsatisfying is the missing intelligence. And the parallelism only scales to the number of cores of your computer.
I want to find the Complexity of my function and i am not sure if it's O(n) or maybe something else
public static boolean find(int [][] mat, int x)
{
int i = 1;
int j = 0;
int k = 0;
int row = 0;
int col = 0;
int n = mat.length;
while(i < n)//(see method discription)stage 1. loops over maxuim of n/2 times = O(n)
{
i = i * 2;
if(x == mat[i-1][i-1])
return true;
else if (x < mat[i-1][i-1])
{
k = i / 2;
row = col = i-1;
break; //bigger value then x found, x is within the max and min values of the matrix. moving on to find a match.
}
}
if (i > n)//x is bigger then max value of mat
return false;
for (j = k; j > 1; j = j / 2)//stage 2. locking on the right 2x2 matrix. runs k times. k<n O(n)
{
if(x == mat[row-j][col] || x == mat[row][col-j])
return true;
else if(x < mat[row-j][col])
row = row - j;
else if (x < mat[row][col-j])
col = col - j;
}
//checking if x is within this 2x2 matrix
if(x == mat[row][col-1])
return true;
else if(x == mat[row-1][col])
return true;
else if(x == mat[row-1][col-1])
return true;
else
return false;
}
I would say O(log2(n)):
first loop does log2(n) max iterations
second loop depends on k < log2(n) and does max log2(k) operations