Magic Square Java program - java

//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.

Related

How to add an element in a null array in java?

I have created a function that takes an array and outputs another array. So I have declared the result array (which will be the output) as null cause the size varies and depends on the inputted array. (for eg. if I enter an array of integers and then I want to output the array containing even numbers from that array). So I will be using for or while loops and I want to know that how I can add the integer to that null array. I tried but I get a null pointer exception that says cannot store to int array cause "array" is null.
sorry but I can't use more advanced techniques cause I am new to java (I need to make this without using arraylist library as I am learning coding I found those type of questions which tries to make you perfect in i specific topic and then they take you to next step so u can be more prepared)
I am using this code and I want to know that add an element to my result array or should I initialized it as null or something else cause the size depends on inputted array in this code I am getting null pointer exception
public static int[] even(int[] numbers) {
int[] result = null;
int even = 0;
int i = 0;
int a = 0;
while (i < numbers.length) {
if (numbers[i] % 2 == 0) {
even = numbers[i];
result[a] = even;
a++;
}
i++;
}
return result;
}
The array's size needs to be initialized. If you want dynamic storage , read about List and Collection.
Here, if you still want to use array, you need the count.
int a = 0;
while (i < numbers.length) {
if (numbers[i] % 2 == 0) {
a++;
}
i++;
}
Then after this, you can initialize it as int[] result = new int[a];
public static int[] even(int[] numbers) {
int[] result = null;
int j = 0;
int a = 0;
while (i < numbers.length) {
if (numbers[j] % 2 == 0) {
a++;
}
j++;
}
result = new int[a];
int even = 0;
int i = 0;
int b = 0;
while (i < numbers.length) {
if (numbers[i] % 2 == 0) {
even = numbers[i];
result[b] = even;
b++;
}
i++;
}
return result;
}

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.

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.

Confused about java assignment method

Hi guys so right now I'm taking data structures in school and I'm having trouble understanding the code our homework is based on which was created by the teacher.
Basically its a program designed to store integers and assign them sets depending on if their positive, negative, and a set that keeps track of weather or not the last entry of an integer was either. We have a class that creates a new array with the storage of whatever int is passed to it. We also have a insert method that inserts an int into a collection only if its not already there. heres the code:
public IntColl1(int i){
c = new int[i+1];
c[0] = 0;
}
public void insert(int i){
if (i > 0){
int j = 0;
while ((c[j] != 0) && (c[j] != i)) j++;
if (c[j] == 0){
if (j == c.length - 1){
int newLength = (c.length * 2);
int[] d = new int[newLength];
for(int l = 0; l < c.length; l++){
d[l] = c[l];
}
c = d;
}
c[j] = i;
c[j + 1] = 0;
}
}
}
Its supposed to insert the Int into the array and if the array is too small, it creates a new one with double the length. For test we set Intcoll1(1), Can anyone help by explaining the while loop that is inside the first if statement? I always thought that when an empty array is created that the slots were all set to 0, and if thats the case then wouldn't that while loop always be false?
It appears that the while loop is trying to find the next "available" space in the array. Initially (as you correctly stated) the while condition will immediately be false. After a couple of inserts, it will be more useful.
Assuming an initial array size of 5, c would start out looking like
[0,0,0,0,0]
If I call insert(4), the condition
(c[j] != 0) && (c[j] != i)
Fails, so j is never incremented and 4 is inserted as position 0. Now c looks like
[4,0,0,0,0]
Now if I call insert(7), the condition will be initially satisfied when j is 0, but will fail when j is incremented to one, so 7 will be inserted as position 1:
[4,7,0,0,0]
Can anyone help by explaining the while loop that is inside the first if statement?
Well I feel that there is a problem in understanding your program above. So I am re-writing the code to make it clear to your:
public void insert(int i){
if (i > 0){
int j = 0;
while ((c[j] != 0) && (c[j] != i)){ //Introduced this bracket to show the start of while
j++;
} //Introduced this bracket to show the end of while
if (c[j] == 0){
if (j == c.length - 1){
int newLength = (c.length * 2);
int[] d = new int[newLength];
for(int l = 0; l < c.length; l++){
d[l] = c[l];
}
c = d;
}
c[j] = i;
c[j + 1] = 0;
}
}
}
The next if statement if (c[j] == 0) is not inside the while loop. Hope that now your understand it.

counting number of unique elements

Hi so I am supposed to count the number of unique elements after an array sort excluding duplicates but i'm getting the wrong output.
In in = new In(args[0]);
int[] whitelist = in.readAllInts();
Arrays.sort(whitelist);
int count = 0;
for (int i = 0; i < whitelist.length; i++) {
if (whitelist[i] == whitelist[count]) {
count++;
}
}
while (!StdIn.isEmpty()) {
int key = StdIn.readInt();
rank(key, whitelist);
}
System.out.println(count);
}
}
expected output: java InstrumentedBinarySearch tinyW.txt < tinyT.txt
65
got: 16
Did i count the number of duplicates or something?
int flag = 0;
int count = 0;
for (int i = 0; i < whitelist.length; i++) //Element to be checked for
{
for (int j=0; j< whitelist.length ; j++) //Loop that goes through the whole array
{
if (whitelist[i] == whitelist[j]) //checks if there are duplicates
{
flag++; // count
}
}
if( flag==1) //There should be only 1 instance of the element in the array and that is the element itself
{
System.out.println(whitelist[i]); //displays unique element
count++; // Keeps count
}
}
This algorithm counts how many different unique numbers there are in the array. A number appearing more than once will only count for 1. I am assuming this is what you mean, as opposed to "numbers which appear exactly once".
There is a more trivial way to do it, as proposed in another answer, but it requires a nested for-loop and therefore executes in quadratic complexity. My algorithm below attempts to solve the problem in linear time proportional to the array size.
int uniquesFound = 0;
// Assume that array is sorted, so duplicates would be next to another.
// If we find duplicates, such as 12223, we will only count its last instance (i.e. the last '2')
for (int i = 0; i < whitelist.length; i++) {
// If we are at the last element, we know we can count it
if (i != whitelist.length - 1) {
if (whitelist[i] != whitelist[i+1]) {
uniquesFound++;
}
else {
// Nothing! If they are the same, move to the next step element
}
} else {
uniquesFound++;
}
}
For instance, given the array:
{1,2,3} this will yield 3 because there are 3 unique numbers
{1,2,3,3,3,4,4,4,5} this will yield 5 because there are still 5 unique numbers
First let's take a look at your loop:
for (int i = 0; i < whitelist.length; i++) {
if (whitelist[i] == whitelist[count]) {
count++;
}
}
You should be comparing consecutive elements in the list, like whitelist[0] == whitelist[1]?, whitelist[1] == whitelist[2]?, whitelist[3] == whitelist[4]?, etc. Doing whitelist[i] == whitelist[count] makes no sense in this context.
Now you have two options:
a. Increment your counter when you find two consecutive elements that are equal and subtract the result from the total size of the array:
for (int i = 0; i < whitelist.length - 1; i++) {
if (whitelist[i] == whitelist[i + 1]) {
count++;
}
}
int result = whitelist.length - count;
b. Change the condition to count the transitions between consecutive elements that are not equal. Since you are counting the number of transitions, you need to add 1 to count in the end to get the number of unique elements in the array:
for (int i = 0; i < whitelist.length - 1; i++) {
if (whitelist[i] != whitelist[i + 1]) {
count++;
}
}
int result = count + 1;
Note that, in both cases, we loop only until whitelist.length - 1, so that whitelist[i + 1] does not go out of bounds.

Categories

Resources