I want to check if the sum of each row in any matrix is equal. How should I rewrite this to avoid NPE?
I can make it work for "normal" matrices like int[][] a = {{1,2,3}, {4,5,6}}, but I want it to work even when testing with null and empty matrices.
public static boolean allRowSumsEqual(int[][] m) {
boolean a = false;
int x = 0;
int total = rowSum(m[0]);
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
x += m[i][j];
}
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v) {
int vSum = 0;
for (int i = 0; i < v.length; i++) {
vSum += v[i];
}
return vSum;
}
As you said, this does work for most matrices. There are a few places I might check for null, see modified code below:
public static boolean allRowSumsEqual(int[][] m){
if(m == null) return true;
if(m.length == 0) return true;
boolean a = false;
int x = 0;
int total = rowSum(m[0]);
for (int i = 1; i < m.length; i++){
// You can use your own function instead of the inner for loop
x = rowSum(m[i]);
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v){
int vSum = 0;
// Assume a null row has sum 0
if(v == null) return 0;
for (int i = 0 ; i < v.length ; i++){
vSum += v[i];
}
return vSum;
}
You need to define a result or an exception if you want to check for "null" parameter. You can return true if null is valid or false otherwise.
if(m == null) return true;
Empty or one lined matrices can return true all the time and does not require any calculation:
if(m.length < 2) return true;
The line test is more simple, I think:
// expect a positiv result
boolean result = true;
// calculate first line
int firstLine = rowSum(m[0]);
// loop remaining lines
for (int i = 1 ; i < m.length ; i++){
// compare first line with current line
if (firstLine != rowSum(m[i]))
{
// not equal -> change result
result = false;
// break loop
break;
}
}
return result;
public class Snippet {
public static boolean allRowSumsEqual(int[][] m) {
if (null == m || 0 == m.length)
return true;
boolean a = false;
int x = 0;
int total = 0;
if (null != m[0])
total = rowSum(m[0]);
for (int i = 1; i < m.length; i++) {
if (null != m[i]) {
for (int j = 0; j < m[i].length; j++) {
x += m[i][j];
}
} else
x = 0;
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v) {
int vSum = 0;
for (int i = 0; i < v.length; i++) {
vSum += v[i];
}
return vSum;
}
public static void main(String[] args) {
int[][] a = { { 1, 2, 3 }, { 3, 2, 1 }, null };
System.out.println(allRowSumsEqual(a));
int[][] b = { null, null, null };
System.out.println(allRowSumsEqual(b));
}
}
What do you think of this solution:
public static boolean allRowSumsEqual(int[][] m) {
if(m == null) { return false; }
int sum = 0;
for(int i = 0; i < m.length; i++) {
int temp = 0;
if(m[i] == null) { continue; }
for(int j = 0; j < m[i].length; j++) {
temp += m[i][j];
}
if(i == 0) { //is the first row
sum = temp;
}
else if(sum != temp) {
return false;
}
}
return true;
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 9 days ago.
Improve this question
I'm trying to implement the A* algorithm in Java in order to solve the 15-Puzzle, but I get an infinite loop and I don't understand why.
I tried with the removal of the openList.clear(); statement, but in this way I get another problem: the tiles begin to do some erroneous movements.
Here is the code of the Board:
public class BoardPrototype implements Prototype, Cloneable {
public Box[][] board;
public int manhattanDistance = 0;
public int g_n = 0;
public final List<Integer> finalList = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0);
#Override
public Object clone() {
try {
BoardPrototype cloned = (BoardPrototype) super.clone();
cloned.board = new Box[board.length][board[0].length];
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
cloned.board[i][j] = new BoxBuilder()
.setX(board[i][j].getX())
.setY(board[i][j].getY())
.setValue(board[i][j].getValue())
.setG_n(board[i][j].getG_n())
.setInitialX(board[i][j].getInitialX())
.setInitialY(board[i][j].getInitialY())
.setManhattanDistance(board[i][j].getManhattanDistance())
.build();
}
}
return cloned;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
#Override
public boolean equals(Object o) {
if (o instanceof BoardPrototype that) {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
if (board[i][j].getValue() != that.board[i][j].getValue())
return false;
}
}
return true;
} else {
return false;
}
}
#Override
public int hashCode() {
int result = Arrays.hashCode(board[0]);
for (int i = 1; i < board.length; i++) {
result = 31 * result + Arrays.hashCode(board[i]);
}
return result;
}
public void setBoard(Box[][] board) {
this.board = board;
}
public void setManhattanDistance(int manhattanDistance) {
this.manhattanDistance = manhattanDistance;
}
public int getManhattanDistance() {
manhattanDistance = 0;
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
manhattanDistance += board[i][j].getManhattanDistance();
}
}
return manhattanDistance;
}
public void setG_n(int g_n) {
this.g_n = g_n;
}
public int getG_n() {
return this.g_n;
}
public BoardPrototype swap(int index1, int index2) {
BoardPrototype copy = (BoardPrototype) this.clone();
int row1 = index1 / 4;
int col1 = index1 % 4;
int row2 = index2 / 4;
int col2 = index2 % 4;
copy.board[row1][col1].setManhattanDistance(copy.board[row1][col1].getManhattan(index2, copy.board[row1][col1].getValue()));
copy.board[row2][col2].setManhattanDistance(copy.board[row2][col2].getManhattan(index1, copy.board[row2][col2].getValue()));
copy.board[row1][col1].setValue(copy.board[row2][col2].getValue());
copy.board[row2][col2].setValue(0);
copy.board[row1][col1].setInitialX(copy.board[row2][col2].getInitialX());
copy.board[row2][col2].setInitialX(copy.board[row1][col1].getInitialX());
copy.board[row1][col1].setInitialY(copy.board[row2][col2].getInitialY());
copy.board[row2][col2].setInitialY(copy.board[row1][col1].getInitialY());
copy.board[row1][col1].setG_n(copy.board[row2][col2].getG_n() + 1);
copy.board[row2][col2].setG_n(copy.board[row1][col1].getG_n() + 1);
copy.board[row1][col1].update();
copy.board[row2][col2].update();
return copy;
}
public List<BoardPrototype> neighbors(BoardPrototype board) {
ArrayList<BoardPrototype> neighbors = new ArrayList<>();
int blankIndex = board.getBlankIndex();
int row = blankIndex / 4;
int col = blankIndex % 4;
if (row > 0) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex - 4);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
if (col > 0) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex - 1);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
if (row < 3) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex + 4);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
if (col < 3) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex + 1);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
return neighbors;
}
public int getBlankIndex() {
int index = 0;
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if(this.board[i][j].getValue() == 0) {
index = i * 4 + j;
}
}
}
return index;
}
public boolean isSolved() {
int count = 0;
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if(board[i][j].getValue() == finalList.get(count)) {
count++;
if (count == 16) {
return true;
}
} else {
return false;
}
}
}
return false;
}
}
And this one is the code of the class that implements the A* algorithm:
public class Game15Solver {
private static Game15Solver game15Solver;
ManhattanComparator manhattanComparator = new ManhattanComparator();
private Game15Solver() {}
public static Game15Solver getInstance() {
if(game15Solver == null) {
game15Solver = new Game15Solver();
}
return game15Solver;
}
public List<BoardPrototype> AStar(BoardPrototype board) {
PriorityQueue<BoardPrototype> openList = new PriorityQueue<>(manhattanComparator);
List<BoardPrototype> closeList = new ArrayList<>();
openList.add(board);
while (!openList.isEmpty()) {
BoardPrototype current = openList.poll();
closeList.add(current);
openList.clear();
if (current.isSolved()) {
System.out.println("Solved");
} else {
for (BoardPrototype neighbor : current.neighbors(current)) {
if (!closeList.contains(neighbor)) {
if(!openList.contains(neighbor)) {
neighbor.setG_n(current.getG_n() + 1);
openList.add(neighbor);
} else {
var tmpList = (Arrays.asList(openList.toArray()));
int ind = tmpList.indexOf(neighbor);
BoardPrototype boardPrototype = (BoardPrototype) tmpList.get(ind);
if(neighbor.getG_n() + 1 < boardPrototype.getG_n()) {
openList.remove(neighbor);
neighbor.setG_n(current.getG_n() + 1);
openList.add(neighbor);
}
}
}
}
}
}
return closeList;
}
}
Do you know how can I solve this problem? Thank you.
public static int maxIceCream(int[][] costs, int coins) {
Arrays.sort(costs);
boolean found = false;
for (int i = 0; i < costs.length; ++i) {
if (coins != costs[i]) {
coins -= costs[i];
found = true;
break;
} else {
return i;
}
}
return costs.length;
}
compare to integer and integer array
You are getting the error message because "costs" is a 2D matrix and "coins" is an integer.
So, you can't compare an integer(int) to array of integer(int[]).
Try looping two times over the "costs" to compare to all the values
public static int maxIceCream(int[][] costs, int coins) {
Arrays.sort(costs);
boolean found = false;
for (int i = 0; i < costs.length; ++i) {
for (int j = 0; j < costs[i].length; ++j) {
if (coins != costs[i][j]) {
coins -= costs[i][j];
found = true;
break;
} else {
return i;
}
}
}
return costs.length;
}
I have just written up this code an have been trying for ages to try and find out why it is not printing the sorted list. It is running and there are no bugs, except it just does not print out the sorted list. Can you please help me find whats wrong?
public class Merging {
public static void main(String[] args) {
int[] a = new int[10];
populate(a);
printA(a);
a = merge_sort(a);
printA(a);
}
public static int[] merge_sort(int[] B) {
if (B.length <= 1) {
return B;
}
int midpoint = B.length / 2;
int[] left = new int[midpoint];
int[] right= new int[B.length-midpoint];
int[] result;
for (int i = 0; i < midpoint; i++) {
left[i] = B[i];
}
int x = 0;
for (int j = midpoint; j < B.length; j++) {
if (x < right.length) {
right[x] = B[j];
x++;
}
}
left = merge_sort(left);
right = merge_sort(right);
result = merge(left, right);
return result;
}
public static int[] merge(int[] left, int[] right) {
int lengthResult = left.length + right.length;
int[] result = new int[lengthResult];
int indexL = 0;
int indexR = 0;
int indexRes = 0;
while (indexL < left.length || indexR < right.length) {
if (indexL < left.length && indexR < right.length) {
if (left[indexL] <= right[indexR]) {
result[indexRes] = left[indexL];
indexL++;
indexRes++;
} else {
result[indexRes] = right[indexR];
indexR++;
indexRes++;
}
} else if (indexL < left.length) {
result[indexRes] = left[indexL];
indexL++;
indexRes++;
}
}
return result;
}
public static void printA(int[] B) {
for (int i = 0; i < B.length; i++) {
System.out.print(B[i] + " ");
}
}
public static int[] populate(int[] B) {
for (int i = 0; i < B.length; i++) {
B[i] = (int) (Math.random() * 100);
}
return B;
}
}
imagine the case in your loop, where indexL < left.length == false but indexR < right.length == true, you never increase indexR and the loop will never terminate
Well I have a program which handles a set of circles represented by an array. It's by default is of size of 10, but if more than 10 items are added, it extends the array by 10 more spaces. I looked for a solution to reduce the length of the set in case the number of items in it drops blow 10. I keep getting a
Exception in thread "main" java.lang.ArrayStoreException: oop.Circle
at oop.ObjectSet.reduce(ObjectSet.java:94)
at oop.ObjectSet.removeObject(ObjectSet.java:39)
at oop.CircleSet.removeObject(CircleSet.java:17)
at oop.Test.main(Test.java:60)
This is the source:
package oop;
public class ObjectSet {
protected Object[] objectSet;
protected int size;
public ObjectSet() {
objectSet = new Object[10];
size = 0;
}
public int numberOfItems() {
return size;
}
public boolean addObject(Object object) {
if (object != null) {
if (size == 0)
objectSet[size] = object;
if (size == objectSet.length)
extend();
if (contains(object) == -1) {
objectSet[size] = object;
size++;
return true;
}
}
return false;
}
public boolean removeObject(Object object) {
if (object != null && size > 0) {
int index = contains(object);
if(size == this.objectSet.length - 10)
reduce();
for (int i = index; i < size; i++) {
objectSet[i] = objectSet[i + 1];
}
objectSet[size - 1] = null;
size--;
return true;
}
return false;
}
public int contains(Object object) {
if (object != null && size > 0) {
for (int i = 0; i < size; i++) {
if (objectSet[i].equals(object))
return i;
}
}
return -1;
}
public void printSet(){
if(size > 0){
for (int i = 0; i < size; i++) {
System.out.println();
}
}
}
private void extend() {
Object[] temp = new Object[size];
for (int i = 0; i < size; i++) {
temp[i] = this.objectSet[i];
}
this.objectSet = new Object[size + 10];
for (int i = 0; i < size; i++) {
this.objectSet[i] = temp[i];
}
}
private void reduce(){
int newSize = this.objectSet.length - 10;
Object[] temp = new Object[newSize];
for (int i = 0; i < size; i++) {
temp[i] = this.objectSet[i];
}
this.objectSet = new ObjectSet[newSize];
for (int i = 0; i < size; i++) {
this.objectSet[i] = temp[i];
}
}
}
Sometimes you initialize the array as
this.objectSet = new Object[size + 10];
while other times you initialize it as
this.objectSet = new ObjectSet[newSize];
This is probably the cause of the exception.
I'm assuming you meant the latter to be :
this.objectSet = new Object[newSize];
You are trying to store Object instances in an array of ObjectSet. This line:
this.objectSet = new ObjectSet[newSize];
Should be
this.objectSet = new Object[newSize];
As it is in the extend method.
Note that you also need to change the subsequent loop termination condition to i < newSize.
public class Sudoku {
public static void main(String[] args) {
// Row and column Latin but with invalid subsquares
String config1 = "1234567892345678913456789124567891235678912346" + "78912345789123456891234567912345678";
String[][] puzzle1 = makeSudoku(config1);
if (isValidSudoku(puzzle1)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle1));
System.out.println("--------------------------------------------------");
// Row Latin but column not Latin and with invalid subsquares
String config2 = "12345678912345678912345678912345678912345678" + "9123456789123456789123456789123456789";
String[][] puzzle2 = makeSudoku(config2);
if (isValidSudoku(puzzle2)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle2));
System.out.println("--------------------------------------------------");
// A valid sudoku
String config3 = "25813764914698532779324685147286319558149273663" + "9571482315728964824619573967354218";
String[][] puzzle3 = makeSudoku(config3);
if (isValidSudoku(puzzle3)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle3));
System.out.println("--------------------------------------------------");
}
public static String[][] makeSudoku(String s) {
int SIZE = 9;
int k = 0;
String[][] x = new String[SIZE][SIZE];
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
x[i][j] = s.substring(k, k + 1);
k++;
}
}
return x;
}
public static String getPrintableSudoku(String[][] x) {
int SIZE = 9;
String temp = "";
for (int i = 0; i < SIZE; i++) {
if ((i == 3) || (i == 6)) {
temp = temp + "=================\n";
}
for (int j = 0; j < SIZE; j++) {
if ((j == 3) || (j == 6)) {
temp = temp + " || ";
}
temp = temp + x[i][j];
}
temp = temp + "\n";
}
return temp;
}
//sudoku validation
public static boolean isValidSudoku(String[][] x) {
return rowsAreLatin(x) && colsAreLatin(x) && goodSubsquares(x);
}
public static boolean rowsAreLatin(String[][] x) {
// fill in your code here
boolean result = true; // Assume rows are latin
for (int i = 0; i < 9; i++) {
result = result && rowIsLatin(x, i); // Make sure each row is latin
}
return result;
}
public static boolean rowIsLatin(String[][] x, int i) {
boolean[] found = new boolean[9];
for (int j = 0; j < 9; j++) {
found[Integer.parseInt(x[i][j])] = true;
}
for (int j = 0; j < 9; j++) {
if (!found[j]) {
return false;
}
}
return true;
}
public static boolean colsAreLatin(String[][] x) {
// fill in your code here
boolean result = true; // Assume cols are latin
for (int j = 0; j < 9; j++) {
result = result && colIsLatin(x, j); // Make sure each row is latin
}
return result;
}
public static boolean colIsLatin(String[][] x, int j) {
// fill in your code here
boolean[] found = new boolean[9];
for (int i = 0; i < 9; i++) {
found[Integer.parseInt(x[i][j])] = true;
}
for (int i = 0; i < 9; i++) {
if (!found[i]) {
return false;
}
}
return true;
}
public static boolean goodSubsquares(String[][] x) {
return true;
}
public static boolean goodSubsquare(String[][] x, int i, int j) {
boolean[] found = new boolean[9];
// We have a 3 x 3 arrangement of subsquares
// Multiplying each subscript by 3 converts to the original array subscripts
for (int p = i * 3, rowEnd = p + 3; p < rowEnd; p++) {
for (int q = j * 3, colEnd = q + 3; q < colEnd; q++) {
found[Integer.parseInt(x[p][q])] = true;
}
}
for (int p = 0; p < 9; p++) {
if (!found[p]) {
return false;
}
}
return true;
}
}
This the error I am getting. Help!
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
at Sudoku.rowIsLatin(Sudoku.java:104)
at Sudoku.rowsAreLatin(Sudoku.java:93)
at Sudoku.isValidSudoku(Sudoku.java:85)
at Sudoku.main(Sudoku.java:8)
Java Result: 1
The problem is with the line:
Integer.parseInt(x[i][j])
Sudoku numbers range from [1, 9], but indices for an array (of length 9) range from [0, 8]. So, when the (i, j) element is a 9, the index is 9 and therefore the IndexOutOfBoundsException is being thrown.
You'll have to change it to
found[Integer.parseInt(x[i][j]) - 1] = true;
Note that you also make the same mistake in the column's respective method.