Neighbours does not yield true - java

I am writing a small program of how to calculate sum of neighbours of a given position in a grid.
for some reason the program does not recognize the right value as correct. I was wondering if that may be because i am using try catch to restrict out of bounds or if it something else i have missed?
i am using a simple 3x3 grid numbered 1 - 9. i have used the same matrix for many other tests so assume there is nothing wrong with the grid. This even though i get 11 when debugging and checking step by step. i dont quite understand, does anyone have an idea?
the -1 in sum was simply to force it to 11 (2+4+5) but the program still yields false when running the input positions. either there is something ive missed or something i have not understood
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
out.println(sumNeighbours(matrix, 0, 0) == 11);
int sumNeighbours(int[][] matrix, int row, int col) {
int sum = -1;
try {
for (int i = row - 1; i <= row; i++) {
for (int j = col - 1; j <= col; j++) {
sum = sum + matrix[i][j];
}
}
} catch (ArrayIndexOutOfBoundsException e) {
} return sum;

Simple printouts (or better: using a debugger
) show you what is happening:
int sumNeighbours(int[][] matrix, int row, int col) {
int sum = 1;
try {
for (int i = row - 1; i <= row; i++) {
for (int j = col - 1; j <= col; j++) {
System.out.println("Step 1 invalid indecies: i " + i +" j "+j);
sum = sum + matrix[i][j];
}
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Step 2 exiting loop, muted exception");
}
System.out.println("Step 3 returning sum "+sum);
return sum;
}
Side note: exceptions are just that. They are meant to handle exceptional situations. Avoid using exceptions to control your program.

I'm going to post this here as a community wiki, so as not to detract from cOder's answer (1+ to it, by the way), but the key is to write your code to avoid running into AIOOBE, to create loop start and end values that prevent this from happening, something like:
int sumNeighbours(int[][] matrix, int row, int col) {
int sum = 0;
int iStart = Math.max(0, row - 1);
int iEnd = Math.min(matrix.length, row + 2);
for (int i = iStart; i < iEnd; i++) {
int jStart = Math.max(0, col -1);
int jEnd = Math.min(matrix[i].length, col + 2);
for (int j = jStart; j < jEnd; j++) {
sum += (i == row && j == col) ? 0 : matrix[i][j];
}
}
return sum;
}

In the first iteration i and j is equal to -1 and you are trying to get value from matrix[-1][-1] and then exception is thrown. Catch block is empty so no operation is done and finally your program returns sum (it is -1).
If you want to continue iteration after exception you should do something like this:
for (int i = row - 1; i <= row; i++) {
for (int j = col - 1; j <= col; j++) {
try {
sum = sum + matrix[i][j];
}
catch (Exception e) {
// do nothing
}
}
} return sum;
In this case only adding is in the loop, so error doesn't stop it.
PS: try to avoid handling situations like this with try catches

Related

Summing up the outer elements in a 2D array of integers in Java?

One of the questions from my exam asked to write some code to compute the sum of the outer int elements of a 2D array. Length of rows and length of columns aren't necessarily equal.
[EDIT] Corner values cannot be added more than once.
I came up with this code and it works, but I'd like to know if there are more efficient ways to achieve the same results. Thanks.
for(int i = 0; i < in.length; i ++) {
for(int j = 0; j < in[i].length; j++) {
if(i == 0 || i == in.length - 1) {
sum += in[i][j];
}
else {
sum += in[i][in[i].length - 1 ] + in[i][0];
break;
}
}
}
If I understand your question, then you could first extract a method to add the elements of one array like
public static int sumArray(int[] in) {
int sum = 0;
for (int val : in) {
sum += val;
}
return sum;
}
Then you can add the elements on the first and last rows like
int sum = sumArray(in[0]) + sumArray(in[in.length - 1]);
And then the outer elements from the other rows with an additional (non-nested) loop like
for (int i = 1; i < in.length - 1; i++) {
sum += in[i][0] + in[i][in[i].length - 1];
}
Or, in Java 8+, you might eliminate the extra method and the explicit loop and do it with one statement like
int sum = IntStream.of(in[0]).sum() //
+ IntStream.of(in[in.length - 1]).sum() //
+ IntStream.range(1, in.length - 1).map(i -> {
return in[i][0] + in[i][in[i].length - 1];
}).sum();
Yes you can do it more efficiently.
int row = in.length;
int column = in[0].length;//not sure of this syntax but trying to get the column size
int sum = 0;
for(int j=0;j<column;j++)
{
sum+=in[0][j]+in[row-1][j];
}
for(int j=1;j<row-1;j++)
{
sum+=in[j][0]+in[j][column-1];
}
Your solution is O(mn) and the loop iterates through unnecessary indexes.

Jagged array; check for column-wise value increase

This method is simple, there is 2D array, not a rectangle, the purpose is to check the values in each column whether they are increasing or not, if they are in an increasing order, return true, else return false.
The shape of the array is like the following, it is a Young Tableaux
{
[1,4,5,10,11],
[2,6,8],
[3,9,12],
[7]
}
The main properties of a young tableaux:
it consists of cells which are filled with integers, and arranged in
left-justified rows,
no row is longer than a preceding row,
from left to right in any row, and down any column the integers are increasing,
the set of integers used is {1, 2, . . . , n} where n is the number
of cells
How I solve it?
My approach is simple, first convert this 2D array into a rectangle matrix, if some position is empty, then filled it with 0.
Then check the column one by one, if found a error, then break, and return the result.
It works, I just wonder if there is a better apporach for this.
public static boolean columnValuesIncrease(int[][] t) {
//How many columns are there?
int columnCounts = t[0].length;
int rowCounts = t.length;
//create a rectangle matrix, fill 0 when outIndex
int[][] addZero = new int[rowCounts][columnCounts];
for (int row = 0; row < rowCounts; row++) {
for (int col = 0; col < t[0].length; col++) {
try {
addZero[row][col] = t[row][col];
} catch (IndexOutOfBoundsException e) {
addZero[row][col] = 0;
}
}
}
//Let's check the damn column!
boolean mark = true;
myLoop:
for (int col = 0; col < columnCounts; col++) {
for (int row = 0; row < rowCounts; row++) {
if (row + 1 < rowCounts && col + 1 < columnCounts) {
if (addZero[row + 1][col] != 0) {
mark = addZero[row][col] <
addZero[row + 1][col] ? true : false;
}
}
if (!mark) {
break myLoop;
}
}
}
return mark;
}
This approach takes a row. It considers 'this' row and the one after it. It considers N number of columns, where N is the minimum of the number of columns in this row and the row after. In math, if R is the number of rows in this 2D matrix, take some r1: r1 ∈ [0, R) and r2 = r1 + 1. Then, N = min{num_cols(r1), num_cols(r2)}.
In column n, where n ∈ [0, N], if the value at the column in the next row happens to be smaller than the value in the preceding row, it returns false. If everything else worked, it returns true.
public static boolean columnValuesIncrease(int[][] t) {
for(int i = 0 ; i < t.length - 1 ; i++)
for(int j = 0 ; j < Math.min(t[i].length, t[i+1].length) ; j++)
if(t[i][j] > t[i+1][j])
return false;
return true;
}

Solve sudoku by backtracking (java)

public static int[][] solve(int[][] input){
for (int i = 0; i < 9*9; i++){
if(input[i / 9][i % 9] != 0){
continue;
}
for (int j = 1; j <= 9; j++){
if(validNumber(input, i / 9, i % 9, j)){
input[i / 9][i % 9] = j;
solve(input);
}
}
}
return input;
}
This method should solve a (solvable) sudoku puzzle via backtracking regardless of the initial situation. It works like this:
Given a sudoku puzzle it iterates from the upper left corner over each row to the lower right corner of the 2D array. When there is already a number, it gets skipped. When there is a zero (empty field) it calculates possible values via the validNumber method. The first valid number (from 1 to 9) is put in the field and the method goes to the next field.
In this algorithm the method does not now whether or not a valid number will eventually render the puzzle unsolvable.
I want to alter it like this:
At the end, when the method finishes iterating through the whole 2d array, every entry of the array gets tested if it is a zero or not.
If there is even one zero the whole algorithm must go to the place where the very first "valid" number was put in. Now, the next "valid" number is put in and so on until there are no zeroes at the end of the algorithm.
I have some troubles implementing this thought. It seems to me there must be an other for loop somewhere, or something like a goto statement, but I don't know where to put it.
Any advice?
I implemented a Sudoku solver once before. It was a bit more complicated than what you had, but solved the game in a blink. :)
What you are attempting to do is solve Sudoku by "Brute Force" and using (tail) recursion. That means you are attempting to solve the board by iterating over all 981 possible combinations. 9 to the power of 81 is... well it's a big number. And so your approach will take eternity, but you'll run out of stack space from the tail recursion much sooner.
When I implemented Sudoko, it was more straight up. It kept a 9x9 array of "items", where each item was the value in the square, and an array of 9 booleans representing candidates (true == viable, false == eliminated). And then it just did a non-recursive loop of solving the board.
The main loop would start with the simple process of finding squares with only 1 remaining candidate. Then the next step would do simple candidate elimination based on values already assigned. Then it would work its way into more complicated elimination techniques such as X-Wing.
Your algorithm does not actually backtrack. It moves forward if it can, but it never moves backwards when it realizes it's stuck in a corner. This is because it never returns any knowledge up the stack, and it never resets squares. Unless you get really lucky, your code will get the game board into a cornered state, and then print out that cornered state. To backtrack, you need to reset the last square you set (the one that got you cornered) to zero, so your algorithm will know to keep trying other things.
For understanding backtracking, I highly recommend a book called The Algorithm Design Manual by Steven Skiena. I read it when I was preparing for SWE interviews, and it really improved my knowledge of backtracking, complexity, and graph search. The second half of the book is a catalog of 75 classic algorithmic problems, and Sudoku is one of them! He has an interesting analysis of optimizations you can make to prune the search tree and solve very hard puzzle boards. Below is some code I wrote a long time ago after reading this chapter (probably not that high quality by my current standards, but it works). I just read through it really quickly and added the solveSmart boolean in the solve method which allows you to turn one of those optimizations on or off, which results in a pretty big time savings when solving a "hard" class Sudoku board (one with only 17 squares filled in to start with).
public class Sudoku {
static class RowCol {
int row;
int col;
RowCol(int r, int c) {
row = r;
col = c;
}
}
static int numSquaresFilled;
static int[][] board = new int[9][9];
static void printBoard() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(" " + (board[i][j] == 0 ? " " : board[i][j]) + " ");
if (j % 3 == 2 && j < 8)
System.out.print("|");
}
System.out.println();
if (i % 3 == 2 && i < 8)
System.out.println("---------|---------|---------");
}
System.out.println();
}
static boolean isEntireBoardValid() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (!isBoardValid(i, j)) {
return false;
}
}
}
return true;
}
static boolean isRowValid(int row) {
int[] count = new int[9];
for (int col = 0; col < 9; col++) {
int n = board[row][col] - 1;
if (n == -1)
continue;
count[n]++;
if (count[n] > 1)
return false;
}
return true;
}
static boolean isColValid(int col) {
int[] count = new int[9];
for (int row = 0; row < 9; row++) {
int n = board[row][col] - 1;
if (n == -1)
continue;
count[n]++;
if (count[n] > 1)
return false;
}
return true;
}
static boolean isSquareValid(int row, int col) {
int r = (row / 3) * 3;
int c = (col / 3) * 3;
int[] count = new int[9];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int n = board[r + i][c + j] - 1;
if (n == -1)
continue;
count[n]++;
if (count[n] > 1)
return false;
}
}
return true;
}
static boolean isBoardValid(int row, int col) {
return (isRowValid(row) && isColValid(col) && isSquareValid(row, col));
}
static RowCol getOpenSpaceFirstFound() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] == 0) {
return new RowCol(i, j);
}
}
}
return new RowCol(0, 0);
}
static RowCol getOpenSpaceMostConstrained() {
int r = 0, c = 0, max = 0;
int[] rowCounts = new int[9];
int[] colCounts = new int[9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != 0)
rowCounts[i]++;
if (board[j][i] != 0)
colCounts[i]++;
}
}
int[][] squareCounts = new int[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int count = 0;
for (int m = 0; m < 3; m++) {
for (int n = 0; n < 3; n++) {
if (board[(i * 3) + m][(j * 3) + n] != 0)
count++;
}
}
squareCounts[i][j] = count;
}
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] == 0) {
if (rowCounts[i] > max) {
max = rowCounts[i];
r = i;
c = j;
}
if (colCounts[j] > max) {
max = rowCounts[j];
r = i;
c = j;
}
}
}
}
return new RowCol(r, c);
}
static boolean solve() {
if (81 == numSquaresFilled) {
return true;
}
boolean solveSmart = true;
RowCol rc = solveSmart ? getOpenSpaceMostConstrained() : getOpenSpaceFirstFound();
int r = rc.row;
int c = rc.col;
for (int i = 1; i <= 9; i++) {
numSquaresFilled++;
board[r][c] = i;
if (isBoardValid(r, c)) {
if (solve()) {
return true;
}
}
board[r][c] = 0;
numSquaresFilled--;
}
return false;
}
public static void main(String[] args) {
// initialize board to a HARD puzzle
board[0][7] = 1;
board[0][8] = 2;
board[1][4] = 3;
board[1][5] = 5;
board[2][3] = 6;
board[2][7] = 7;
board[3][0] = 7;
board[3][6] = 3;
board[4][3] = 4;
board[4][6] = 8;
board[5][0] = 1;
board[6][3] = 1;
board[6][4] = 2;
board[7][1] = 8;
board[7][7] = 4;
board[8][1] = 5;
board[8][6] = 6;
numSquaresFilled = 17;
printBoard();
long start = System.currentTimeMillis();
solve();
long end = System.currentTimeMillis();
System.out.println("Solving took " + (end - start) + "ms.\n");
printBoard();
}
}
Eventually validNumber() method will not return any number because there is no possibilities left that means one of the previous choices was incorrect. Just imagine that the algorithm is started with the empty grid (obviously this puzzle is solvable1).
The solution is to keep tree of possible choices and if some choices are incorrect, then just remove them from the tree and use the next available choice (or step back on a higher level of the tree, if there is no choice left in this branch). This method should find a solution if any. (Actually this is how I implemented my sudoku solver some time ago.)
1 IMHO there are 3 different kinds of sudoku:
"true" correct sudoku that has a single unique complete solution;
ambiguous sudoku that has multiple distinct complete solutions, e.g. a puzzle with only 7 different numbers, so it has at least two distinct solutions that differ by swapping 8th and 9th numbers;
incorrect sudoku that has no complete solution, e.g. with a row with two or more occurrences of the same number.
With this definition, a solver algorithm should either:
prove that there is no solution;
return complete solution that satisfies the initial grid.
In the case of a "true" sudoku the result is a "true" solution by definition. In the case of an ambiguous sudoku the result can be different depending on the algorithm. An empty grid is the ultimate example of ambiguous sudoku.

JAVA : How to create a snake shape matrix

Hi I am trying to create a matrix on the console using 2D array. The idea is that the output should look like this one :
1|8|9 |16
2|7|10|15
3|6|11|14
4|5|12|13
Is there any one who has an idea how it can be done?
Few things you can guess from the matrix: -
First, you have to traverse all rows of a columns first before moving to the next column
Second, you need to alternate between downwards and upwards direction on each iteration
So, you would need two nested for loop, for iterating through rows for a particular column. One will go from row 0 to max - 1, and the next will go from row = max - 1 to 0.
Now, to alternate the iteration direction, you can use a boolean variable, and toggle it after each iteration of inner loop finishes.
Each loop needs to be enclosed inside an if-else. Both of them will be executed on a certain condition. If boolean downwards = false;, then loop moving upwards will be executed and vice-versa.
On each iteration, fill the current cell with an integer counter, that you would have to initialize with 1, and increment it after each fill.
Pseudo code : -
// Initialize variables row, col, and count = 1
boolean goDown = true;
int[][] matrix = new int[row][col]; // declare matrix
for i = 0 to col:
if (goDown)
for j = 0 to row: // Move in downwards direction
assign count++ to matrix[j][i]
// assign to `[j][i]` because, we have to assign to rows first
goDown = false; // Toggle goDown
else
for j = row - 1 to 0: // Move in upwards direction
assign count++ to matrix[j][i]
goDown = true; // toggle goDown
}
Just some psuedo-code, hope it helps and gives you something to start with.
boolean goUp = false;
boolean goDown = true;
size = 4;
matrix[size][size];
k = 0;
l =0;
loop i->0 i < size*size i++
matrix[l][k] = i;
if(l==size and goDown)
goDown = false;
goUp = true;
k++;
else if(l==0 and goUp)
goDown = true;
goUp = false;
k++;
else
l = l+ (1*goDown?1:-1);
end loop;
finally with your help and after looking carefully at how multidimensional arrays work I solved the problem which now is looking quite simple to me.
int a = 4;
int b = 4;
int c = 1;
boolean direction = true;
int[][] arrey = new int[a][b];
for (int y = 0; y <= b - 1; y++) {
if (direction) {
for (int x = 0; x <= a - 1; x++) {
arrey[x][y] = c;
c++;
}
direction = false;
} else {
for (int x = a - 1; x >= 0; x--) {
arrey[x][y] = c;
c++;
}
direction = true;
}
}
for (int x = 0; x <= a - 1; x++) {
for (int y = 0; y <= b - 1; y++) {
System.out.print("["+arrey[x][y]+"]");
}
System.out.println("");
}
const matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
];
let i = 1;
for (let col = 0; col < matrix[0].length; col++) {
if (col % 2 === 1) {
for (let row = matrix.length - 1; row >= 0; row--) {
matrix[row][col] = i++;
}
} else {
for (let row = 0; row < matrix.length; row++) {
matrix[row][col] = i++;
}
}
}
console.table(matrix);

Magic Square Java program

//Kevin Clement
//Week3A Magic Squares
Hey all, doing an introductory assignment to 2dimensional arrays. Below is the code I have done which is pretty much done.
My problem I get is I'm not entirely sure how to print out the array, as well as getting everything to run right with a test method. I get an error out of bounds at the line msq[order][order] = 1;
I apologize if my formatting of question is wrong, still not used to this site. Any help would be great. Thanks!
import java.util.*;
class Magic
{
private int order;
int msq[ ][ ];
public Magic(int size)
{
if(size < 1 || size % 2 == 0)
{
System.out.print("Order out of range");
order = 3;
}
msq = new int[order][order];
Build();
Display();
}
public void Build()
{
int row = 0;
int col =0;
msq[order][order] = 1;
for(int k = 1; k <= order * order; k++)
{
msq[row][col] = k;
if(row == 0 && col == order -1)
row++;
else if(row == 0)
{
row = order - 1;
col++;
}
else if(msq[row - 1][col + 1] != 0)
row++;
else if(msq[row -1][col + 1] == 0)
{
row--;
col++;
}
if(col == order - 1)
{
col = 0;
row--;
}
}
}
public void Display()
{
for(int i = 0; i < order; i++)
{
for(int k = 0; k < order; k++)
{
System.out.println(msq[i][k] + " ");
}
}
}
}
I get an error out of bounds at the line msq[order][order] = 1;
msq = new int[order][order];
// ..
msq[order][order] = 1;
If array size is n, then you need to access the elements from 0 to n-1. There is no nth index. In your case there is no order, order index. It is only from 0 to order-1 and is the reason for array index out of bounds exception.
What is the reason for this condition in the constructor?:
if(size < 1 || size % 2 == 0)
{
System.out.print("Order out of range");
order = 3;
}
Note that whenever you use a size input that doesn't satisfy the if clause, the variable order is not initialized and defaults to 0. As a result the 2d array has size zero and throws the out of bounds error. If you are trying to use 3 as a default value, then u want to move the line:
order = 3;
before the if block.
Other things to consider:
1. make the order variable final since u don't plan on changing it. Eclipse IDE would warn you about the situation described above if you do so.
or
2. If you are going to default to 3 for the value of order initialize it as such.
private int order = 3
Also you might consider printing a message saying order defaults to three when the condition is not satisfied.
To print a matrix of integers in Java
for (int i = 0; i < order; i++) {
for (int k = 0; k < order; k++) {
System.out.printf("%6d", msq[i][k]);
}
System.out.println();
}
The second part of your question is answered by Mahesh.
msq[order][(order] = 1;
--> here is a syntax error. You have an '('.
You get end of bound error because array start from 0 not 1 (which is a mistake every beginner makes) therefore change it to msq[order-1][order-1] = 1;
The answer above is the correct way to print out the array.

Categories

Resources