I am trying to create a program that returns the maximum square submatrix of 1's from a square matrix of 0's and 1's. Right now I have figured out how to break the square up into a square submatrix starting at each number that equals 1. The problem is, as the program starts to get farther from the starting point of the matrix, it suddenly goes out of bounds, which I am suspecting has to do with how it calculates what part of the matrix to start from for each submatrix.
Here is my code:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter the number of rows and columns in the matrix (only one input, this is a square matrix): ");
int dimensions = input.nextInt();
int[][] matrix = new int[dimensions][dimensions];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
int n = input.nextInt();
if (n == 0 || n == 1)
matrix[i][j] = n;
else
System.out.print("Input only 0 or 1");
}
}
int[] largestBlock = findLargestBlock(matrix);
}
public static int[] findLargestBlock(int[][] m) {
int[] solution = new int[3];
//find rows with most consecutive 1's, then find columns with the same # of consecutive 1's
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
//"origin" for each iteration is (i, j)
if (m[i][j] == 1)
if (isSquare(m, i, j) == true) {
solution[0] = i; solution[1] = j; solution[2] = getSize(m, i, j);
}
}
}
return solution;
}
public static boolean isSquare(int[][] m, int i, int j) {
int k = m.length - i;
if (m[0].length - j < k)
k = m.length - j;
if (k < 2)
return false;
int[][] testSquare = new int[k][k];
for (int y = i; y < m.length - i; y++) {
for (int x = j; x < m[i].length - j; x++) {
testSquare[y - i][x - j] = m[y][x];
}
}
for (int y = 0; y < testSquare.length; y++) {
for (int x = 1; x < testSquare[y].length; x++) {
if (testSquare[y][x] != testSquare[y][x - 1])
return false;
}
}
for (int x = 0; x < testSquare[0].length; x++) {
for (int y = 1; y < testSquare.length; y++) {
if (testSquare[y][x] != testSquare[y - 1][x])
return false;
}
}
return true;
}
public static int getSize(int[][] m, int i, int j) {
int k = m.length - i;
if (m[0].length - j < k)
k = m.length - j;
return k;
}
I determined that this part of the program was causing the issue, apparently there is some flaw in it that sends the array x- or y- value out of bounds:
public static boolean isSquare(int[][] m, int i, int j) {
int k = m.length - i;
if (m[0].length - j < k)
k = m.length - j;
if (k < 2)
return false;
int[][] testSquare = new int[k][k];
for (int y = i; y < m.length - i; y++) {
for (int x = j; x < m[i].length - j; x++) {
**testSquare[y - i][x - j] = m[y][x];**
}
}
I'm very confused regarding the line in stars/in bold font, as I think this is the line causing the issue. However, I'm not sure how its causing the issue.
I think the loop you are looking for is this - since testSquare is square just start from it make sure its enumerated from 0 to k then find the other matrix indexes - m will never go more than k since k is the minimum so it starts from i and j and goes to i+k and j+k max.
if (m[i].length - j < k)
k = m[i].length - j;
for (int y = 0; y < k; y++) {
for (int x = 0; x < k; x++) {
testSquare[y][x] = m[i+y][j+x];
}
}
Related
Firsly, I have a Matrix which I need to sort in such way (shown on the picture) using Selection Sort:
the way to sort the Matrix
Thus, the array should be sorted in increasing way from up to down. What's more, we have to sort elements of the right diagonal of Matrix.
Here's my code, but it doesn't work properly because I take diagonal into account.
public class PAS {
public static void main(String[] args) {
int n = 5; int max = 25; int minimL = 0; int MinRow, Temp;
int[][] array = new int [n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
array[i][j] = (int) (Math.random() * (max - minimL + 1) + minimL);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
System.out.print(" " + array[i][j]);
System.out.println();
}
System.out.println();
for (int NumCol = n - 1; NumCol >= 0; NumCol --) {
for (int NumRow = 0; NumRow < n; NumRow++) {
if (NumCol >= n - NumRow - 1) // Getting the right diagonal of Matrix changing position of columns to rows in order to sort them
{
MinRow = NumRow;
for (int j = NumRow + 1; j < n; j++)
if (array[(n - 1) - NumCol][NumCol] > array[MinRow][(n - 1) - NumCol])
MinRow = j;
Temp = array[NumRow][(n - 1) - NumCol];
array[(n - 1) - NumCol][NumCol] = array[MinRow][(n - 1) - NumCol];
array[MinRow][(n - 1) - NumCol] = Temp;
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.print(" " + array[i][j]);
}
System.out.println();
}
}
}
Is it possible to sort it properly in the way shown on the picture taking O(n^3) notation?
I'm trying to make a Sudoku game for my project but if i increase the number of empty spaces in the Sudoku Grid the code just throws an exception arrayoutofbounds but can't figure out where it's coming from. k is the number of empty spaces in the grid.
I haven't tried anything because can't figure out what can be done at this kind of problem
Here is the code:
package sudoku.puzzle;
import java.util.*;
public class SudokuPuzzle {
int[] mat[];
int N; // number of columns/rows.
int SRN; // square root of N
int K; // No. Of missing digits
// Constructor
SudokuPuzzle(int N, int K) {
this.N = N;
this.K = K;
// Compute square root of N
Double SRNd = Math.sqrt(N);
SRN = SRNd.intValue();
mat = new int[N][N];
}
// Driver code
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Select Level Of Difficulty \n 1.Easy\n 2.Medium\n 3.Hard");
String Choice = in .next(); in .close();
if ("1".equals(Choice) || "Easy".equals(Choice) || "easy".equals(Choice) || "e".equals(Choice) || "E".equals(Choice)) {
int N = 9, K = 40;
SudokuPuzzle sudoku = new SudokuPuzzle(N, K);
sudoku.fillValues();
sudoku.printSudoku();
}
if ("2".equals(Choice) || "Medium".equals(Choice) || "medium".equals(Choice) || "m".equals(Choice) || "M".equals(Choice)) {
int N = 9, K = 60;
SudokuPuzzle sudoku = new SudokuPuzzle(N, K);
sudoku.fillValues();
sudoku.printSudoku();
}
if ("3".equals(Choice) || "Hard".equals(Choice) || "hard".equals(Choice) || "h".equals(Choice) || "H".equals(Choice)) {
int N = 9, K = 72;
SudokuPuzzle sudoku = new SudokuPuzzle(N, K);
sudoku.fillValues();
sudoku.printSudoku();
}
}
// Sudoku Generator
public void fillValues() {
// Fill the diagonal of SRN x SRN matrices
fillDiagonal();
// Fill remaining blocks
fillRemaining(0, SRN);
// Remove Randomly K digits to make game
removeKDigits();
}
// Fill the diagonal SRN number of SRN x SRN matrices
void fillDiagonal() {
for (int i = 0; i < N; i = i + SRN)
// for diagonal box, start coordinates->i==j
fillBox(i, i);
}
// Returns false if given 3 x 3 block contains num.
boolean unUsedInBox(int rowStart, int colStart, int num) {
for (int i = 0; i < SRN; i++)
for (int j = 0; j < SRN; j++)
if (mat[rowStart + i][colStart + j] == num)
return false;
return true;
}
// Fill a 3 x 3 matrix.
void fillBox(int row, int col) {
int num;
for (int i = 0; i < SRN; i++) {
for (int j = 0; j < SRN; j++) {
do {
num = randomGenerator(N);
}
while (!unUsedInBox(row, col, num));
mat[row + i][col + j] = num;
}
}
}
// Random generator
int randomGenerator(int num) {
return (int) Math.floor((Math.random() * num + 1));
}
// Check if safe to put in cell
boolean CheckIfSafe(int i, int j, int num) {
return (unUsedInRow(i, num) &&
unUsedInCol(j, num) &&
unUsedInBox(i - i % SRN, j - j % SRN, num));
}
// check in the row for existence
boolean unUsedInRow(int i, int num) {
for (int j = 0; j < N; j++)
if (mat[i][j] == num)
return false;
return true;
}
// check in the row for existence
boolean unUsedInCol(int j, int num) {
for (int i = 0; i < N; i++)
if (mat[i][j] == num)
return false;
return true;
}
// A recursive function to fill remaining
// matrix
boolean fillRemaining(int i, int j) {
// System.out.println(i+" "+j);
if (j >= N && i < N - 1) {
i = i + 1;
j = 0;
}
if (i >= N && j >= N)
return true;
if (i < SRN) {
if (j < SRN)
j = SRN;
} else if (i < N - SRN) {
if (j == (int)(i / SRN) * SRN)
j = j + SRN;
} else {
if (j == N - SRN) {
i = i + 1;
j = 0;
if (i >= N)
return true;
}
}
for (int num = 1; num <= N; num++) {
if (CheckIfSafe(i, j, num)) {
mat[i][j] = num;
if (fillRemaining(i, j + 1))
return true;
mat[i][j] = 0;
}
}
return false;
}
// Remove the K no. of digits to
// complete game
public void removeKDigits() {
int count = K;
while (count != 0) {
int cellId = randomGenerator(N * N);
// System.out.println(cellId);
// extract coordinates i and j
int i = (cellId / N);
int j = cellId % 9;
if (j != 0)
j = j - 1;
// System.out.println(i+" "+j);
if (mat[i][j] != 0) {
count--;
mat[i][j] = 0;
}
}
}
// Print sudoku
public void printSudoku() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
System.out.print(mat[i][j] + " ");
System.out.println();
}
System.out.println();
}
}
What you got is probably a ArrayIndexOutOfBoundsException. That means at some point you try to access a field of an array outside its boundaries.
But I canĀ“t see where K could be responsible for that. Can you provide more information about the error? E.g. at which value you get it or in which line.
EDIT: The variable i int the removeKDigits() function exceeds the boundaries of the array if the random generator spits out the value 81.
I wrote the following code to print a pyramid, but only one side is being printed.
int k = 7;
int m = 13;
int x = 6;
int y = x;
for (int i = 0; i < k; i++) {
for (int j = 0; j < m; j++) {
if (j < x) System.out.print(" ");
if ((j >= x) && (j <= y)) System.out.print("*");
}
System.out.println();
x++;
y++;
}
This code should print a pyramid starting with 1 asterisk at the top (first row containing the most spaces) and then increment by 2 each time until a pyramid with 7 rows is formed.
In your code x++; should be x--;
I'll summarize it for you:
int k = 7;
int m = 13;
int x = 6;
int y = x;
for (int i = 0; i < k; i++) {
for (int j = 0; j < m; j++) {
if (j<x)
System.out.print(" ");
if (j>=x && j<=y)
System.out.print("*");
}
System.out.println();
x--;
y++;
}
x needs to reduced each loop until the base of the triangle to maintain
the spaces amount.
your x and y are always the same, so this
if ((j >= x) && (j <= y))
will only be true once, when j is exactly = x = y.
im stuck building a function that takes a given 2d-char array and a Point inside of it, that takes the given point coordinate and builds a new 2d-char array that surrounds the point.
for example if the original grid is:
a b c d e
z h a f c
g y z q x
r z x s a
k j h z z
the answer of point (0,0) should be:
? ? ?
? a b
? z h
the answer of point(2,2) should be:
h a f
y z q
z x s
public int numOfColors(Point p) {
char [][] neighbors = new char[3][3];
for(int i = 0; i < neighbors.length; i++){
for(int j = 0; j < neighbors.length; j++){
neighbors[i][j]='?';
}
}
int pX = p.getX(), pY = p.getY();
for(int i = pX - 1; (i < map.length) && (i < pX + 1) ; i++){ //runs on the original map and copy to neighbors
for (int j = pY - 1; (j < map.length) && (j < pY + 1); j++){
neighbors[i-pX+1][j-pY+1]=map[i][j];
}
}
for(int k = 0; k < neighbors.length; k++){ //runs on the neighbors array. if a point is an edge point.copy the given point color to the '?' cell
for(int l = 0; l < neighbors.length; l++){
if(neighbors[k][l]=='?')
neighbors[k][l]= map[pX][pY];
}
}
I've been sitting on this all day, the correct answer will be rewarded with a beer
I would like to begin from a helper method
private char getValue(int x, int y) {
if (x < 0 || x >= xSize || y < 0 || y >= ySize) {
return '?';
}
return neighbors[x][y];
}
public static void extract(char [][] arr, int row, int col){
char [][] ex = new char [3][3];
int rc = 0;
int cc = 0;
for(int i=row-1; i<row+2; i++){
for(int j=col-1; j<col+2; j++){
if(i < 0 || j < 0 || i >= arr.length || j >= arr[i].length){
ex[rc][cc] = '?';
} else {
ex[rc][cc] = arr[i][j];
}
cc++;
}
rc++;
cc = 0;
}
for(int i=0; i<3;i++){
for(int j=0; j<3; j++){
System.out.print (ex[i][j] +" ");
}
System.out.println();
}
}
Row, Col is Point(x,y).
I'm assuming the out of bounds exception is happened when using this bit of code, since you aren't checking if px - 1 is -1 and the same for py:
for(int i = px - 1; (i < map.length) && (i < px + 1) ; i++){ //runs on the original map and copy to neighbors
for (int j = py - 1; (j < map.length) && (j < py + 1); j++){
neighbors[i-pX+1][j-pY+1]=map[i][j];
}
}
You could change it to something like this:
int x1 = Math.max(p.getX() - 1, 0);
int x2 = Math.min(p.getX() + 1, map.length);
int y1 = Math.max(p.getY() - 1, 0);
int y2 = Math.min(p.getY() + 1, map[0].length);
int xCount = 0;
int yCount = 0;
and then:
for(int i = x1; i < x2; i++) { //runs on the original map and copy to neighbors
for (int j = y1; j < y2; j++) {
neighbors[xCount][yCount++]=map[i][j];
}
yCount = 0;
xCount++;
}
I am trying to iterate throughout 2D Array to find a row that its sum equals the sum of two other rows in the same 2D array.
I am having hard time figuring out how to compare before I can reset sum2 and sum3 to zero;
* for sum2: its sum will be just the sum at row (n-1), same as for sum3
* Just need to find a way to compare before resetting sum2 and sum3 to zero
boolean compare(int n, int [][] A)
{
int i, j, k, x, y, p, sum, sum2, sum3, total;
//row
for ( i = 0; i < n; i++)
{
sum = 0;
//col
for ( j = 0; j < n; j++)
sum+= A[i][j];
//row
for ( k = 0; k < n; k++)
{
sum2 = 0;
//col
if (k != i)
for ( x = 0; x < n; x++)
sum2 += A[k][x];
}
for ( y = 0; y < n; y++)
{
sum3 = 0;
if ( (y != k) && (y != i) )
for ( p = 0; p < n; p++)
sum3 += A[y][p];
}
total = sum2 + sum3;
if ( sum == (total) )
return true;
}//for ( i = 0; i < n; i++)
return false;
}
Any input is greatly appreciated
**** Here we go, I updated my code as below:
boolean compare(int n, int [][] A)
{
int i, j, k, x, y;
int [] sumArray = new int[n];
for (i = 0; i < n; i++)
{
sum = 0;
for(j = 0; j < n; j++)
sum += A[i][j];
sumArray[i] = sum;
}
for ( k = 0; k < n; k++)
{
for(x = 0; x < n; x++)
{
if( x != k)
{
for(y = 0; y < n; y++)
{
if( (y != x) && (y != k) )
{
if( sumArray[k] == (sumArray[x] + sumArray[y]) )
return true;
}
}
}
}
}
return false;
}
Seems like it would be easier to calculate the sum of each row and put them in a 1D array. Then you can compare sums of each row in a more concise way and you also avoid computing the sum of each row more than once.
Also, the parameter int n is not needed for the compare() method, since you can just check the length property of the array that gets passed in.
public boolean compare(int[][] arr) {
final int rowLen = arr.length;
int[] sums = new int[rowLen];
// Compute sum of each row
for (int row = 0; row < rowLen; row++) {
int rowSum = 0;
int[] rowArr = arr[row];
for (int col = 0; col < rowArr.length; col++)
rowSum += rowArr[col];
sums[row] = rowSum;
}
// Check if row n equals the sum of any other 2 rows
for (int n = 0; n < sums.length; n++) {
for (int i = 0; i < sums.length; i++) {
for (int j = i + 1; j < sums.length; j++)
if (n != i && n != j && sums[n] == sums[i] + sums[j]) {
// sum of row n equals sums of rows i+j
System.out.println("Sum of row " + n + " is equal to the sums of rows " + i + " and " + j);
return true;
}
}
}
return false;
}
Disclaimer: untested code, but it gets my point accross