For loop producing java.lang.ArrayIndexOutOfBoundsException: 3 - java

I'm writing a program that reads a file and sees if the information make up a magic square, but I am getting this error: "java.lang.ArrayIndexOutOfBoundsException: 3" in my sumCol method. Specifically the line below: for (int row = 0; row < square[row].length; row++) {
public int sumCol(int col) {
int sum = 0;
for (int row = 0; row < square[row].length; row++) {
sum += square[row][col];
}
return sum;
}
I'm not sure if it is necessary, but here is the rest of my class as well:
// ****************************************************************
// Square.java
//
// Define a Square class with methods to create and read in
// info for a square matrix and to compute the sum of a row,
// a col, either diagonal, and whether it is magic.
//
// ****************************************************************
import java.util.Scanner;
public class Square {
int[][] square;
//--------------------------------------
//create new square of given size
//--------------------------------------
public Square(int size) {
square = new int[size][size];
for (int row = 0; row < square.length; row++) {
for (int col = 0; col < square.length; col++) {
square[row][col] = row * 10 + col;
}
}
}
//--------------------------------------
//return the sum of the values in the given row
//--------------------------------------
public int sumRow(int row) {
int sum = 0;
for (int col = 0; col < square.length; col++) {
sum += square[row][col];
}
return sum;
}
//--------------------------------------
//return the sum of the values in the given column
//--------------------------------------
public int sumCol(int col) {
int sum = 0;
for (int row = 0; row < square[row].length; row++) {
sum += square[row][col];
}
return sum;
}
//--------------------------------------
//return the sum of the values in the main diagonal
//--------------------------------------
public int sumMainDiag() {
int sum = 0;
for (int j = 0; j < square.length; j++) {
sum += square[j][j]; //you can do this because a square's diagonals have the same coordinate points
}
return sum;
}
//--------------------------------------
//return the sum of the values in the other ("reverse") diagonal
//--------------------------------------
public int sumOtherDiag() {
int sum = 0;
for (int j = 0; j < square.length; j++) {
sum += square[j][square.length - 1 - j];
}
return sum;
}
//--------------------------------------
//return true if the square is magic (all rows, cols, and diags have
//same sum), false otherwise
//--------------------------------------
public boolean magic() {
boolean answer = true;
int sum = sumMainDiag();
if (sumOtherDiag() != sum) {
answer = false;
} else {
for (int col = 0; col < square.length; col++) {
if (sum != sumCol(col)) {
answer = false;
}
}
for (int row = 0; row < square.length; row++) {
if (sum != sumRow(row)) {
answer = false;
}
}
}
return answer;
}
//--------------------------------------
//read info into the square from the input stream associated with the
//Scanner parameter
//--------------------------------------
public void readSquare(Scanner scan) {
for (int[] square1 : square) {
for (int col = 0; col < square.length; col++) {
square1[col] = scan.nextInt();
}
}
}
//--------------------------------------
//print the contents of the square, neatly formatted
//--------------------------------------
public void printSquare() {
for (int[] square1 : square) {
for (int col = 0; col < square1.length; col++) {
System.out.print(square1[col] + "\t");
}
System.out.println();
}
}
}

change
row < square[row].length
to:
row < square.length

Perhaps you meant this?
public int sumCol(int col) {
int sum = 0;
for (int row = 0; row < square.length; row++) {
sum += square[row][col];
}
return sum;
}
Notice that the number of rows is given by square.length, whereas the number of columns in a given row is given by square[row].length.

You're doing the check wrong. Use:
public int sumCol(int col) {
int sum = 0;
for (int row = 0; row < square.length; row++) {
sum += square[row][col];
}
return sum;
}
You're checking the length of the row, not of the overall array.

I think you want
// square.length not square[row].length
for (int row = 0; row < square.length; row++) {
// Here's where we might check square[row].length to be safe.
if (col < square[row].length) {
sum += square[row][col];
}
}

Related

Issues with calculating the determinant of a matrix (in Java). It is alwys 0

I want to calculoate the determinant of a given NxN Matrix using the Laplace-Method. I already tried differnt approaches which always return a 0.
The class I used:
package Matrix;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Scanner;
public class Matrix
{
double[][] array;
public static void init(Matrix a,int row , int column)
{
a.array = new double [row] [column];
for (int i = 0; i < row; i++)
{
for(int k = 0; k < column; k++)
{
a.array[i][k] = 0;
}
}
}
public static int getNRows(Matrix a)
{
return a.array.length;
}
public static int getNColumns(Matrix a)
{
return a.array[0].length;
}
public static void print(Matrix a)
{
for(int i = 0; i < getNRows(a);i++ )
{
for (int k = 0; k < getNColumns(a); k++)
{
System.out.print(a.array[i][k] + "\t");
}
System.out.println();
}
}
public static double det(Matrix a)
{
double det = 0;
det = a.array[0][0] * a.array[1][1] * a.array[2][2] + a.array[1][0] * a.array[2][1] * a.array[0][2] + a.array[2][0] * a.array[0][1] * a.array[1][2] - a.array[2][0] * a.array[1][1] * a.array[0][2] - a.array[1][0] * a.array[0][1] * a.array[2][2] - a.array[0][0] * a.array[2][1] * a.array[1][2];
return det;
public static Matrix transpose(Matrix a)
{
Matrix transposed = new Matrix();
Matrix.init(transposed, getNRows(a), getNColumns(a));
for(int i = 0; i < getNRows(a); i++)
{
for(int j = 0; j < getNColumns(a); j++)
{
transposed.array[j][i] = a.array[i][j];
}
}
return transposed;
}
public static Matrix subMatrix(Matrix a, int exclRow, int exclCol)
{
Matrix subMatrix = new Matrix();
Matrix.init(subMatrix, getNRows(a) - 1, getNColumns(a) - 1);
for(int i = 0; i < getNRows(a) - 1; i++)
{
for(int j = 0; j < getNColumns(a) - 1; j++)
{
if(i != exclRow && j != exclCol)
{
subMatrix.array[i][j] = a.array[i][j];
}
}
}
return subMatrix;
}
public static Matrix loadMatrix(String filename) throws Exception
{
Scanner sc = new Scanner(new BufferedReader(new FileReader(filename)));
Matrix result = new Matrix();
int row = 0;
int col = 0;
String[] line = sc.nextLine().trim().split("\t");
row = Integer.parseInt(line[0]);
col = Integer.parseInt(line[1]);
init(result, row, col);
int currentRow = 0;
while(sc.hasNextLine())
{
String[] line2 =sc.nextLine().trim().split("\t");
for(int i = 0; i < col; i++)
{
result.array[currentRow][i] = Double.parseDouble(line2[i]);
}
currentRow++;
}
return result;
}
/*public static double detN(Matrix a)
{
int colOfA = getNColumns(a);
int rowOfA = getNRows(a);
double value = 1;
if(colOfA != rowOfA)
{
return 0;
}
if(colOfA == 1 && rowOfA == 1)
{
return a.array[0][0];
}
else
{
for(int row = 0; row < rowOfA; row++)
{
value += Math.pow(-1, row) * a.array[row][0] * detN(subMatrix(a, row, 0));
}
}
return value;
}*/
public static double detN(Matrix a)
{
int colOfA = getNColumns(a);
int rowOfA = getNRows(a);
if(colOfA != rowOfA)
{
return 0;
}
if(rowOfA <= 3)
{
return det(a);
}
double value = 0;
for(int row = 0; row < rowOfA; row++)
{
if(row % 2 == 0)
{
value += a.array[row][0] * detN(subMatrix(a, row, 0));
}
else
{
value -= a.array[row][0] * detN(subMatrix(a, row, 0));
}
}
return value;
}
public static Matrix adjointN(Matrix a)
{
int rowOfA = getNRows(a);
int colOfA = getNColumns(a);
Matrix ret = new Matrix();
Matrix.init(ret, rowOfA, colOfA);
for(int row = 0; row < rowOfA; row++)
{
for(int col = 0; col < colOfA; col++)
{
ret.array[row][col] = detN(subMatrix(a, row, col));
}
ret = transpose(ret);
return ret;
}
return ret;
}
public static Matrix inverseN(Matrix a)
{
Matrix inverse = new Matrix();
Matrix.init(inverse, getNRows(a), getNColumns(a));
double pre = 1/detN(a);
inverse = adjointN(a);
for(int i = 0; i < getNRows(a); i++)
{
for(int j = 0; j < getNColumns(a); j++)
{
inverse.array[j][i] = inverse.array[i][j] * pre;
}
}
return inverse;
}
}
I have two versions for detN, which both yield the same result.
This isn't the entire class, because there are some functions that don't belong to this particular question
Here is an approach you could consider(the code is not fully debugged so take with a grain of salt). Finding the determinant is a recursive concept since you are always finding the determinant of a smaller matrix to get the final answer.
//Recursive base function
public static double det(int[][] matrix) {
if(matrix.length == 2)
return ((matrix[0][0] * matrix[1][1]) - (matrix[0][1] * matrix[1][0]));
double determinant = 0;
int mlength = matrix.length - 1;
int[][] newM = new int[mlength][mlength];
for(int i = 0; i < mlength + 1; i++) {
newM = newMatrix(matrix, i);
determinant = determinant + (Math.pow(-1, i) * matrix[0][i]) * det(newM);
}
return determinant;
}
//Format smaller matrix to use in further iteration of above det(int[][]) function
public static int[][] newMatrix(int[][] m, int column) {
int length = m.length - 1;
int[][] newMat = new int[length][length];
for(int i = 1; i < m.length; i++) {
for(int j = 0; j < column; j++)
newMat[i - 1][j] = m[i][j];
for(int k = column + 1; k < m.length; k++)
newMat[i - 1][k - 1] = m[i][k];
}
return newMat;
}
You can adapt to however your Matrix class works.
subMatrix is not really excluding the given row and column - it is just making them zero (not copying) and removing the last row and column...
Printing the matrix will help debug that.
one way: use additional indices for the destination matrix (the sub matrix). Only increment this if a value is really copied. Example: sub.array[k++][l++] = a.array[i][j] inside the if
loop over original matrix
Alternative: if one index is greater than or equal to the index that must be skipped, add 1 to the reading index:
var k = (i>=exclRow) ? i+1 : i;
var l = (j>=exclCol) ? j+1 : j;
sub.array[i][j = a.array[k][l];
code not intended to be complete, just ideas how to solve the problem

Generating an unique Sudoku

I am making a Sudoku game in Java and I need some help.
I've got two classes for generating the Sudoku puzzle: SudokuSolver, SudokuGenerator`.
The SudokuSolver creates a full valid Sudoku puzzle for an empty table and the SudokuGenerator removes a random value from the table and then checks (using SudokuSolver) if the Sudoku puzzle is unique.
I found out that the Sudoku puzzle isn't unique, so I think my algorithm for checking the uniqueness of the Sudoku puzzle is bad.
For example, I have this Sudoku puzzle
497816532
132000000
000000000
910600080
086009000
000084963
021063059
743050020
600278304
And this solution:
497816532
132**745**698
568392471
914**637**285
386529147
275184963
821463759
743951826
659278314
I went to https://www.sudoku-solutions.com/ and I added the pattern of my Sudoku and they gave me another solution:
497816532
132**547**698
568392471
914**635**287
386729145
275184963
821463759
743951826
659278314
The funny think is that they're saying that This puzzle is valid and has a unique solution.
Some opinions?
SudokuSolver
public class SudokuSolver {
public static final int GRID_SIZE = 9;
public static final int SUBGRID_SIZE = 3;
private static int validRow = 0;
private static int validCol = 0;
private int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 9};
public boolean solveSudoku(int[][] values, int forbiddenNum) {
if(!findUnassignedLocation(values)) return true;
//suffle the nums array - for having a different valid sudoku
shuffleNums();
for (int i = 0; i < GRID_SIZE; i++) {
int num = nums[i];
if(num == forbiddenNum) continue; //
if(isSafe(values,validRow, validCol, num)) {
values[validRow][validCol] = num;
if(solveSudoku(values, forbiddenNum)) return true;
if(validCol == 0) {
validRow--;
validCol = 8;
}else{
validCol--;
}
values[validRow][validCol] = 0;
}
}
return false;
}
public boolean createValidSudoku(int[][] values) {
if(!findUnassignedLocation(values)) return true;
shuffleNums();
for (int i = 0; i < GRID_SIZE; i++) {
int num = nums[i];
if(isSafe(values,validRow, validCol, num)) {
values[validRow][validCol] = num;
if(createValidSudoku(values)) return true;
if(validCol == 0) {
validRow--;
validCol = 8;
}else{
validCol--;
}
values[validRow][validCol] = 0;
}
}
return false;
}
private void shuffleNums() {
Random random = new Random();
for(int i = nums.length - 1; i > 0; i--) {
int index = random.nextInt(i + 1);
int a = nums[index];
nums[index] = nums[i];
nums[i] = a;
}
}
private boolean findUnassignedLocation(int[][] values) {
for(int row = 0; row < GRID_SIZE; row++) {
for(int col = 0; col < GRID_SIZE; col++) {
if (values[row][col] == 0) {
validRow = row;
validCol = col;
return true;
}
}
}
return false;
}
private boolean usedInRow(int[][] values, int row, int num) {
for (int col = 0; col < GRID_SIZE; col++) {
if(values[row][col] == num) return true;
}
return false;
}
private boolean usedInCol(int[][] values, int col, int num) {
for (int row = 0; row < GRID_SIZE; row++) {
if(values[row][col] == num) return true;
}
return false;
}
private boolean usedInBox(int[][] values, int boxStartRow, int boxStartCol, int num) {
for(int row = 0; row < SUBGRID_SIZE; row++) {
for (int col = 0; col < SUBGRID_SIZE; col++) {
if (values[row + boxStartRow][col + boxStartCol] == num) return true;
}
}
return false;
}
private boolean isSafe(int[][] values,int row, int col, int num) {
return !usedInRow(values, row, num) &&
!usedInCol(values, col, num) &&
!usedInBox(values, row - row % 3, col - col % 3, num);
}
public void printGrid(int[][] values) {
for (int row = 0; row < GRID_SIZE; row++) {
for (int col = 0; col < GRID_SIZE; col++) {
System.out.print(values[row][col]);
}
System.out.println();
}
}
}
SudokuGenerator
public class SudokuGenerator {
private int[][] generatorValues = new int[9][9];
public void generateSudoku() {
SudokuSolver sudokuSolver = new SudokuSolver();
//generate a random valid sudoku for an empty table
sudokuSolver.createValidSudoku(generatorValues);
int count = 0;
printNums(generatorValues);
while(count < 40){
Random random = new Random();
int row = 0;
int col = 0;
if(count < 15){
row = random.nextInt(3);
col = random.nextInt(9);
} else if (count >= 15 && count < 30) {
row = random.nextInt(3) + 3;
col = random.nextInt(9);
}else {
row = random.nextInt(3) + 6;
col = random.nextInt(9);
}
int num = generatorValues[row][col];
int tempValues[][] = Arrays.copyOf(generatorValues, generatorValues.length);
//System.out.println("Row:" + row + "Col: " + col + "Num: " + num);
//Set the cell to 0;
if(generatorValues[row][col] != 0){
generatorValues[row][col] = 0;
} else{
continue;
}
//If found a solution, set cell back to original num
if(sudokuSolver.solveSudoku(tempValues, num)) {
generatorValues[row][col] = num;
continue;
}
count++;
}
System.out.println("------------------");
printNums(generatorValues);
}
private void printNums(int[][] values) {
for (int row = 0; row < 9; row++) {
for(int col = 0; col < 9; col++) {
System.out.print(values[row][col]);
}
System.out.println();
}
}
public int[][] getGeneratorValues () {
return generatorValues;
}
}

Finding the location of a number in a 2d array

I am trying to create a program that lets you find how many times a curtain number occurs in a 2d array. One of the things that I am required to do is to create a method called countInstence which counts the amount of times a number occurs but also where they are located in the array. the problem i'm having is how do I output the location of the the number
public int[][] createArray(int rSize, int cSize) {
Random rnd = new Random();
int[][] array = new int[rSize][cSize];
for (int row = 0; row < array.length; row++) {
for (int col = 0; col < array[0].length; col++) {
array[row][col] = rnd.nextInt(26);
}
}
return array;
}
public void print2dArray(int[][] array) {
for (int row = 0; row < array.length; row++) {
for (int col = 0; col < array[0].length; col++) {
System.out.print(array[row][col] + "\t");
}
System.out.println("\n");
}
}
public int countInstence(int[][] array, int search) {
int count = 0;
for (int row = 0; row < array.length; row++) {
for (int col = 0; col < array[0].length; col++) {
if (array[row][col] == search)
count++;
}
}
return count;
}
public static void main(String[] args) {
Journal5b call = new Journal5b();
Scanner in = new Scanner(System.in);
int[][] myArray;
int value;
myArray = call.createArray(10, 10);
call.print2dArray(myArray);
System.out.println("Enter a number to search for: ");
value = in.nextInt();
System.out.println("Your number occurred "
+ call.countInstence(myArray, value) + " Times");
}
Just insert a one line print statement inside of the if-statement and format to print the row and column of the current index, as below...
public int countInstance(int[][] array, int search) {
int count = 0;
for (int row = 0; row < array.length; row++) {
for (int col = 0; col < array[0].length; col++) {
if (array[row][col] == search) {
System.out.printf("Instance found at [%d, %d]\n", row, col);
count++;
}
}
}
return count;
}
If you aren't familiar with the System.out.printf call or the %d symbols, you can read more about it here.
Just add this line to the for loop
for (int row = 0; row < array.length; row++) {
for (int col = 0; col < array[0].length; col++) {
if (array[row][col] == search) {
System.out.printf("Instance found at [%d, %d]\n", row, col);// add this line
count++;
}
}
}
If you want to also use location at other place then just declare a List and add location to that list while searching for element.
public static List<String> location=new ArrayList<String>();
public int countInstence(int[][] array, int search) {
int count = 0;
for (int row = 0; row < array.length; row++) {
for (int col = 0; col < array[0].length; col++) {
if (array[row][col] == search)
{
count++;
String loc=row+","+col;
location.add(loc);
}
}
}
return count;
}
public static void main(String[] args) {
Test call = new Test();
Scanner in = new Scanner(System.in);
int[][] myArray;
int value;
myArray = call.createArray(10, 10);
call.print2dArray(myArray);
System.out.println("Enter a number to search for: ");
value = in.nextInt();
System.out.println("Your number occurred "
+ call.countInstence(myArray, value) + " Times");
System.out.println("locations :");
for(int i = 0; i < location.size(); i++) {
System.out.println(location.get(i));
}
}
I suggest using Points:
List<Point> locations=new ArrayList<Point>();
....
if (array[row][col] == search)
{
count++;
locations.add(new Point(row,col));
}

How to return a column id that contains minimum value in a 2-D array (Java)

I am trying to return the index of the column which contains the minimum value in a matrix, but so far i can only return the minimum value of the matrix, and can't figure out how to return that column's id. If I try to return "col" it doesn't change anything.
public static int minColIndex (int[][] m) {
int row = m.length, col = m[0].length;
int min = m[0][0];
for (col = 0; col < m.length; col++) {
for (row = 0; row < m[col].length; row++) {
if (min > m[col][row]) {
min = m[col][row];
}
}
}
return min;
}
In your code, the value of col will always be m.length - 1 after the outer loop completes. You need to store the minimum column somewhere, e.g.,
public static int minColIndex (int[][] m) {
int row = m.length, col = m[0].length;
int min = m[0][0];
int minCol = 0; // extra variable to store minimumm column
for (col = 0; col < m.length; col++) {
for (row = 0; row < m[col].length; row++) {
if (min > m[col][row]) {
min = m[col][row];
minCol = col; // remember the minimum column as well as minimum
}
}
}
return minCol; // return minimum column, not col
}
There's also no need for row and col to have initial values set before the loop, so you can change the first few lines of the method to be the following, for slightly greater clarity:
public static int minColIndex (int[][] m) {
int min = m[0][0];
int minCol = 0; // extra variable to store minimumm column
for (int col = 0; col < m.length; col++) {
for (int row = 0; row < m[col].length; row++) {
... etc.
public static int minColIndex (int[][] m) {
int row = m.length, col = m[0].length , int index = 0;
int min = m[0][0];
for (col = 0; col < m.length; col++) {
for (row = 0; row < m[col].length; row++) {
if (min > m[col][row]) {
min = m[col][row];
index= col;
}
}
}
return index;
}
If(min< m[c][r]){
min=[c][r];
save=c;
} '
Define these variables.
int rowOfMinValue = 0;
int colOfMinValue = 0;
And then,
Change:
if (min > m[col][row]) {
min = m[col][row];
}
To:
if (min > m[col][row]) {
min = m[col][row];
rowOfMinValue = row;
colOfMinValue = col;
}
now, you have min values row and column in hand.
Suggestion:
You have wrongly pointing row and col in a matrix. On an m x n matrix, m and n represent rows and columns respectively. And hence, in a m[][] matrix, each of [] represent row and col respectively in sequence.
If value 6 is in 2nd row, 4th col, then we write as
row=1;
col=3;
value = 6;
m[ row ][ col ] = value;

Draw a line in JAVA with Pattern - Beginner

I want to draw a line in java. I will use these draws with making Triangles. I can do this :
1***
11**
111*
1111
and i need to do this:
1***
*1**
**1*
***1
Ive done a lot of work today and my mind got really confused.
Can you help me ? Thanks A lot.
EDIT: also my perfect answer should be Implement Bresenham’s line drawing algorithm but i dont understand in wikipedia.
EDIT 2: my grid code :
String [][] matrix = new String [50][50];
for (int row = 0; row < 50; row++){
for (int column = 0; column < 50; column++){
matrix [row][column] = "*";
}
}
public class Test
{
public static void main(String [] args)
{
int size=50;
String[][] matrix= new String [size][size];
for (int i=0; i < size; i++)
{
for (int j=0; j < size; j++)
{
if (i != j)
matrix[i][j]="*";
else
matrix[i][j]="1";
}
}
for (int i=0; i < size; i++)
{
for (int j=0; j < size; j++)
{
System.out.print(matrix[i][j]);
}
System.out.println();
}
}
}
Edit: if it's already filled with * simply make matrix[i][j]="1"; when i equals j, ie if (i==j).
public class MulArray {
public static void main(String[] args) {
/*
* 1*** 1** 1* 1
*/
String[][] grid = new String[5][5];
for (int row = 0; row < grid.length-1; row++) {
for (int column = 0; column < grid[row].length; column++) {
if (row == column) {
grid[row][column] = "1";
} else {
grid[row][column] = "*";
}
}
}
for (int row = 0; row < grid.length-1; row++)
for (int column = 0; column < grid[row].length; column++) {
if (column != 4) {
System.out.print(grid[row][column]);
}
else{
System.out.print("\n");
}
}
}
}

Categories

Resources