I'm having some problems with my Sudoku Solver that I need to make, what I am supposed to do is to create a program which checks to see if the inputted Sudoku puzzle is correct or not. I have the code which checks to see if each row, column, and "minibox" working. My only problem now is to print out the puzzle. This is what I have so far:
public String printGrid(int size, int[][] puzzle){
double temp = Math.sqrt(size);
for(int row = 0; row < size; row++){
for(int column = 0; column < size; column++){
System.out.print(puzzle[row][column]);
if(column == temp - 1) {
System.out.print("|");
}
if(row == temp - 1){
for(int i = 0; i < size; i++){
System.out.print("-\t");
}
}
if(column == size - 1) {
column = 0;
row++;
}
}
}
return "Correct!";
}
As an example size will be 4 and the inputted sudoku will be:
1 2 3 4
4 3 2 1
3 4 1 2
2 1 4 3
My output is to look like this:
1 2 | 3 4
4 3 | 2 1
----+----
3 4 | 1 2
2 1 | 4 3
My current code however gives an ArrayOutOfBounds error and outputs this:
- 2- - - - 1- - - - 4|121|43
I'm completely lost in how to write this method to output, can anyone shed some light on this for me? (Also ignore the fact that all sudokus return "Correct!" I should be able to figure that out myself.)
if(column == size - 1) {
column = 0;
row++;
}
Using the above if-statement, you are not letting the inner loop to get terminated, because everytime the column value reaches the dead-end, you are resetting it to 0, and hence the terminating condition of inner loop (column < size) will always be true, and also you are increasing the row value continuously, which will gradually result ArrayIndexOutOfBounds.
Just remove that if condition. It is not needed.
You have at least 4 problems that I see right away:
You don't print a newline at the end of your outer (row) loop
The if(row == temp - 1) loop should be in the outer loop only (you want to do it on it's own row, not each time in the column
column == temp-1 etc. will only work for the 2x2 case, it should be column > 0 && column % temp == 0
Don't ever ever modify a for loop variable inside the loop, that will confuse everything and usually cause ArrayIndexOutOfBoundsException, as happens here.
Related
I have a question about the following code snippet. This is from a sudoku solver I found on youtube. It uses a recursive backtracking algorithm to solve. I'm just trying to learn from this, but I'm stuck on some parts.
The following snippet is a boolean to check if a number is in a 3x3 box, this is used later in the solve() method.
// we check if a possible number is in its 3x3 box
private boolean isInBox(int row, int col, int number) {
int r = row - row % 3;
int c = col - col % 3;
for (int i = r; i < r + 3; i++)
for (int j = c; j < c + 3; j++)
if (board[i][j] == number)
return true;
return false;
}
I just don't understand how this works. What does row - row % 3 do? And then in the for loop i < r + 3 confuses me too. I understand the rows and column checkers, those are easy, but the logic here is escaping me.
row and col can be any value from 0 to 8. They define a location within the 9x9 sudoku game.
The loops need to check the specific 3x3 box that the location row,col is contained within.
int r = row - row % 3; finds the index of the first row in that same 3x3 box.
int c = col - col % 3; finds the index of the first column in that same 3x3 box.
Both convert the input value to output as:
0 -> 0
1 -> 0
2 -> 0
3 -> 3
4 -> 3
5 -> 3
6 -> 6
7 -> 6
8 -> 6
The loop then checks every location from r,c up to r+2,c+2 (inclusive), looking for the specified value number.
So the goal was to use a nested for loop to output 6 rows and 10 columns. The thing was though that the inner for loop was supposed to check to see whether the number was even or odd as, if it was even, we would add 2 to it and then print out that number 10 times before moving onto the next output. So this is what were were supposed to get
1 1 1 1 1 1 1 1 1 1
4 4 4 4 4 4 4 4 4 4
3 3 3 3 3 3 3 3 3 3
6 6 6 6 6 6 6 6 6 6
5 5 5 5 5 5 5 5 5 5
8 8 8 8 8 8 8 8 8 8
I thought I was on the right track but my output is a complete mess, here's what I have. Thank you to anyone willing to help.
for (int numberE = 1; numberE <= 6; numberE++)
{
for (int nestedE = 1; nestedE < 10; nestedE++)
{
if (numberE%2 == 0)
{
numberE += 2;
System.out.printf("%2d", numberE);
} else {
System.out.printf("%2d", numberE);
}
}
System.out.printf("%2d\n", numberE);
}
well to start with your inner loop will only iterate nine times. second you don't need a nested loop, you need one loop and a guard determining when to print.
Don't modify numberE inside the loops. Instead just print numberE + 2.
Also, if your inner loop runs from 0 to <10 you will get 10 iterations and you don't need to print the number again - just a newline.
for (int numberE = 1; numberE <= 6; numberE++)
{
for (int nestedE = 0; nestedE < 10; nestedE++) // <-- start at 0 and end <10 for 10 iterations
{
if (numberE%2 == 0)
{
System.out.printf("%2d", numberE + 2); // <-- print the number + 2
} else {
System.out.printf("%2d", numberE);
}
}
System.out.println(); // <-- don't print the value again here
}
I would do it this way. Gives the required result.
public class NestedForLoop {
public static void main(String[] args) {
for (int i = 1; i <= 6; i++)
{
int temp = i;
if(temp%2 == 0) {
temp +=2;
}
for(int j=1;j<=10;j++) {
System.out.print(temp+" ");
}
System.out.println();
}
}
}
A brief description of what is happening here:
So, since we need 6 rows, we use the value of 6 as a row counter. The variable i takes care of keeping a count of the rows. Here since the target is 6, we start from row number 1 and go until row no 6. Inside each value of the loop, we save the value of i to temp because we don't want the value of i to change before incrementing in the main for loop. We then check if this temp value is even by doing a modulo division by 2. If it is even, we increment the temp value by 2.
Then, we run a loop from 1 to 10 since we need 10 columns to print the value temp(either the original i or incremented because it was even). After exiting the loop, finally to move to the next row, we do a System.out.println().
I would suggest using a temporary variable to store the current intended value.
The issue with your solution was that you were modifying the value of numberE by using numberE += 2; inside the second for loop, this changes the value globally.
Moving the final column in to the nested for loops also makes it easier as you wouldn't need to define the temporary variable outside of the loop. Using this also meant changing the <10 to <=10.
for (int numberE = 1; numberE <= 6; numberE++) {
for (int nestedE = 1; nestedE <= 10; nestedE++) {
int current = (numberE % 2 == 0) ? numberE + 2 : numberE;
System.out.printf("%2d", current);
}
System.out.printf("\n");
}
You were pretty close though, with practise you'll get better.
I'm a beginner programmer and taking an intro to Java class. We were assigned to write a program that outputs the letter E made of asterisks with 5 down and 3 across as below:
***
*
***
*
***
The only requirement was to use nested-loops and if statements to get to our result. Below is my code. It works as intended, but I'm having trouble understanding why.
public class LetterE {
public static void main(String args[]) {
final int NUM_ACROSS = 3;
final int NUM_DOWN = 5;
int row;
int column;
for (row = 1; row <= NUM_DOWN; row++) {
if (row == 1 || row == 3 || row == NUM_DOWN)
for (column = 1; column <= NUM_ACROSS; column++) {
if (column == 1 || column == NUM_ACROSS)
System.out.print("*");
}
System.out.print("*");
System.out.print(" ");
System.out.println();
}
System.exit(0);
}
}
Basically my issue comes with the System.out.print statements. I don't understand the relationship between my loops and the print statements. For example, the first print statement is inside the curly brace and taking it out causes an incorrect output. On top of that, I don't understand what the other print statements outside of that first curly brace are for and why they can't be inside the curly brace.
Any guidance would be greatly appreciated. Trying my hardest to understand how this works, but I've been stuck on it for a while now.
Thank you very very much!
final int NUM_ACROSS = 3;
final int NUM_DOWN = 5;
int row;
int column;
I assume you know what the above code does, so I won't elaborate on that.
for (row = 1; row <= NUM_DOWN; row++) {
This code mean you want to execute the code inside the curly braces continuously as long as row <= NUM_DOWN. But before doing that, we assign 1 to row (this statement is executed only once). Each iteration ( = a full execution of the code inside the curly braces) row++ will be executed.
So we start off with row == 1, then row == 2, row == 3 ... until row == 6, at which point row > NUM_DOWN, because NUM_DOWN == 5.
If we would put all the values we have gotten for row in a list, the list would be equal to {1,2,3,4,5,6}, which contains 6 values. However, because the for loop is exited when row == 6, there are only 6 - 1 == 5 iterations.
Moving on:
if (row == 1 || row == 3 || row == NUM_DOWN){
Basically it means: if row == 1 OR row == 3 OR row == 5, then execute the code inside the curly braces. Otherwise, skip it.
for (column = 1; column <= NUM_ACROSS; column++) {
Basically the same as the other for loop, but just with different variables.
if (column == 1 || column == NUM_ACROSS)
Also the same as the if statement above, but again, with different parameters.
System.out.print("*");
This will print the * character once to the console without a newline ( = enter, basically).
The print statements that will be executed after this one will append another character to the already written characters, so your output will first look like this after the first iteration:
*
Then it will look like this after the third (in the second, column is equal to 2, so column == 1 || column == NUM_ACROSS is false and thus the code inside is not executed):
**
Then the loop is exited, and the other print statement is executed.
***
A space is also appended, but it is not visible because... well, it is a space :P
The println function is essentialy the same as print but it also appends the escape sequence \n. This escape sequence, called a newline, is like hitting enter on your keyboard: it starts a new line.
The next iteration, the code within the first if statement is skipped entirely, so we jump straight to the second print function. Now our output looks like this:
***
*
If we repeat the process, we will get:
***
*
***
.
***
*
***
*
.
***
*
***
*
***
Onto "optimizing" the program, because there is actually quite a lot of redundant code here:
int row;
int column;
Just put it inside the for statements like this:
for (int row = 1; row <= NUM_DOWN; row++) {
It is shorter and a bit more readable ;)
if (row == 1 || row == 3 || row == NUM_DOWN){
This one is a bit odd, because on one hand, declaring NUM_DOWN makes it easier to change the height if you want to, but on the other hand, you have to edit the constants 1 and 3 manually then either way.
Let's go with the somewhat more adaptable way:
if (row == 1 || row == NUM_DOWN / 2 + 1 || row == NUM_DOWN) {
Integers are always rounded down, so 5 / 2 == 2. The letter may look a bit odd when NUM_DOWN is even, but whatever.
for (int column = 1; column <= NUM_ACROSS; column++)
if (column == 1 || column == NUM_ACROSS)
Well, this is just a strange section of code: we would be better of starting off with column = 2 (2 because we will print another asterisk below) and scrapping the if statement entirely (the loop will be executed for the values 2 and 3, so 2 elements total --> 2 asterisks).
System.out.print(" ");
Since we can't read it, we can as well remove it altogether
System.out.println("*");
Again, it is shorter and it pretty much does the same thing.
System.exit(0);
Hmmm... It is not really needed, because your program returns 0 by default anyways.
The final program looks like this:
public class LetterE {
public static void main(String args[]) {
final int NUM_ACROSS = 3;
final int NUM_DOWN = 5;
for (int row = 1; row <= NUM_DOWN; row++) {
if (row == 1 || row == NUM_DOWN / 2 + 1 || row == NUM_DOWN)
for (int column = 2; column <= NUM_ACROSS; column++)
System.out.print("*");
System.out.println("*");
}
}
}
Try below code. I replaced inner loop print to '#' just to give you idea how it works.. The inner loop is to print additional * required for 3 lines (top, middle, and bottom). Outer System.out is by default we need * in each line and System.out.println is to move to next line. I moved the inner for loop in {} to make it more readable.
public class LetterE {
public static void main(String args[]) {
final int NUM_ACROSS = 3;
final int NUM_DOWN = 5;
int row;
int column;
for (row = 1; row <= NUM_DOWN; row++) {
if (row == 1 || row == 3 || row == NUM_DOWN){
for (column = 1; column <= NUM_ACROSS; column++) {
if (column == 1 || column == NUM_ACROSS)
System.out.print("L");
}
}
System.out.print("*");
System.out.print(" ");
System.out.println();
}
System.exit(0);
}
}
public class LetterE {
public static void main(String[] args) {
int row;
int column;
for (row = 1; row <= 5; row++) { //final int NUM_DOWN = 5
if (row == 1 || row == 3 || row == 5) {
for (column = 1; column <= 3; column++) {//final int NUM_ACROSS = 3
if (column == 1 || column == 3)
System.out.print("*");
}
}
System.out.print("*");
System.out.print("\n");
}
System.exit(0);
}
}
Look at my code.
I have added another bracket for if loop for making it easier to you.
following code prints 1 * for 5 rows.
for (row = 1; row <= 5; row++) {
System.out.print("*");
System.out.print("\n");
}
output:
row1: 1 = *
row2: 1 = *
row3: 1 = *
row4: 1 = *
row5: 1 = *
Inside this for loop there is another for loop with if condition
if (row == 1 || row == 3 || row == 5) {
for (column = 1; column <= 3; column++) {//final int NUM_ACROSS = 3
if (column == 1 || column == 3)
System.out.print("*");
}
}
This loop prints another 2 * for row 1,3,5
So, total no of * for
row1: 1 + 2 = ***
row2: 1 = *
row3: 1 + 2 = ***
row4: 1 = *
row5: 1 + 2 = ***
Hope that it will help you to understand.
public static void main(String[] args) {
String[] Test = new String[]{"1","2","3","4","5","6","7","8","9"};
}
I want to be able to print like this.
1 2 3
4 5 6
7 8 9
I have tried by using for loops three times to print it but i was wondering if there is an easier way to do it.
printf could help.
This loop should do:
for (int i = 0; i < Test.length; i++) {
System.out.printf("%s%s", Test[i], i % 3 == 2 ? "\n" : " ");
}
public static void main(String[] args) {
String[] Test = new String[]{"1","2","3","4","5","6","7","8","9"};
for(int i = 1; i <= Test.length; i++) {
System.out.print(Test[i - 1]+" ");
if(i % 3 == 0)
System.out.println();
}
}
Try:
for ( int i = 0 ; i < Test.length ; i++ ) {
System.out.print(Test[i]+" ");
if ( i%3 == 2 ) {
System.out.println();
}
}
or
for ( int i = 0 ; i < Test.length-2 ; i++ ) {
System.out.print(Test[i]+" "+Test[i+1]+" "+Test[i+2]+"\n");
}
and change the name for Test in test.
For perfect alignment, you need to do two passes. One to keep track of the maximum size of each to-be-printed column, and the second to print all the columns adjusted to the desired size.
This is because if you start printing the first line
1 2 3
some devious movement of the universe will eventually guarantee that the second row will contain the numbers
3425 2352342 2
and it will blow your alignment. However, if you walk the data one time, updating the maximum size of the column (if necessary)
(row 1) (column 1 max size is 1) (column 2 max size is 1) (column 3 max size is 1)
(row 2) (column 1 max size is 4) (column 2 max size is 7) (column 3 max size is 1)
then the second time you go through the data, you can print each row with the correct amount of padding (spaces for max column width - width of data, and then the value)
1 2 3
3425 2352342 2
Now as to how to transform a one dimensional array into a two dimensional array, it depends. One could just declare a two dimensional array from the start, or you could specify the width of the row, counting off elements until a row is "filled".
Both techniques will work, and depending on circumstance, you might find that one approach fits some problems better than the other (but there's likely not a perfect solution for all problems).
Full Disclosure: Homework.
Explanation: I cant understand my teacher.
Problem:
Write a method called printSquare that takes in two integer
parameters, a min and a max, and prints the numbers in the range from
min to max inclusive in a square pattern. The square pattern is
easier to understand by example than by explanation, so take a look at
the sample method calls and their resulting console output in the
table below. Each line of the square consists of a circular sequence
of increasing integers between min and max. Each line prints a
different permutation of this sequence. The first line begins with
min, the second line begins with min + 1, and so on. When the
sequence in any line reaches max, it wraps around back to min. You
may assume the caller of the method will pass a min and a max
parameter such that min is less than or equal to max
I cannot for the life of me figure out how to make the numbers stop at the 'max' value and start over in the middle of the line.
This is what I have so far, apologies but I have trouble with for loops.
for(int i = 0; i < row; i++)
{
for(int d = 0; d < row; d++)
{
System.out.print(d+1);
}
System.out.println(i);
}
I know I used row twice, but its the only way i can get the compiler to form a square shape with the loop. Does anyone even remotely understand what i'm trying to do? :/
This is actually a nice mathematical problem. Assume:
int side = to - from + 1; /// the size/width of the square.
the value at any point in the square (row, col) is:
from + ((row + col) % side)
you should be able to put that in your loops and "smoke it".
Edit based on comment asking for explanation.
The trick is to loop through all the positions in the 'matrix'. Given that the matrix is square, the loops are relatively simple, just two loops (nested) that traverse the system:
final int side = to - from + 1;
for (int row = 0; row < side; row++) {
for(int col = 0; col < side; col++) {
... magic goes here....
}
}
Now, in this loop, we have the variables row and col which represent the cell in the matrix we are interested in. The value in that cell needs to be proportional to the distance it is from the origin..... let me explain.... If the origin is the top left (which it is), then the distances from the origin are:
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
The distance is the sum of the row and the column...... (rows and columns start counting from 0).
The values we put in each matrix are limited to a fixed range. For the above example, with a square of size 5, it could have been specified as printSquare(1,5).
The value in each cell is the from value (1 in this example) plus the distance from the origin... naively, this would look like:
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
here the values in the cell have exceeded the limit of 5, and we need to wrap them around... so, the trick is to 'wrap' the distances from the origin..... and the 'modulo' operator is great for that. First, consider the original 'origin distance' matrix:
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
if we instead populate this matrix with 'the remainder of the distance when dividing by 5' (the modulo 5, or %5) we get the matrix:
0 1 2 3 4
1 2 3 4 0
2 3 4 0 1
3 4 0 1 2
4 0 1 2 3
Now, if we add this 'modulo' result to the from value (1), we get our final matrix:
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4
in a sense, all you need to know is that the value at each cell is:
the from value plus the remainder when you divide the 'distance' by the width.
Here's the code I tested with:
public static final String buildSquare(final int from, final int to) {
final StringBuilder sb = new StringBuilder(side * side);
final int side = to - from + 1;
for (int row = 0; row < side; row++) {
for(int col = 0; col < side; col++) {
sb.append( from + ((row + col) % side) );
}
sb.append("\n");
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(buildSquare(1, 5));
System.out.println(buildSquare(3, 9));
System.out.println(buildSquare(5, 5));
System.out.println(buildSquare(0, 9));
System.out.println(buildSquare(0, 3));
}
Since this is homework, I'll just give a hint.
I cannot for the life of me figure out how to make the numbers stop at the 'max' value and start over in the middle of the line.
Here's one way to do it.
Create the first number twice in an array. Taking the printSquare(1, 5) example, create an int array of 1, 2, 3, 4, 5, 1, 2, 3, 4, 5.
Use a loop to loop through the array, starting with element zero and ending with element 4, and another loop to display 5 digits (max - min + 1).
try this
int i,j,k;
for(i=min;i<=max;i++) {
for(j=i;j<=max;j++) {
System.out.print(j);
}
for(k=min;k<i;k++){
System.out.print(k);
}
System.out.println();
}
you can try
loop from min value to max value and put all the numbers in an array
now loop again from min value to max value
each time print the array and do a circular shift (for circular shift you can find lot of example in SO)
I think #rolfl's solution is the cleanest. I'd recommend going with that.
You can find another simple solution by observing that each output in your "square" simply shifts the first element to the end the list of numbers. To imitate this, you can put all the numbers from min to max in a data structure like LinkedList or ArrayDeque where you can easily add/remove items from both ends, then you'd print the contents in order, and shift the first entry to the end. E.g., coll.addLast(coll.removeFirst()). If you repeat that process max - min + 1 times, you should get the desired output.
no array no problem you can easily solve.
it work with any range of number.
static void printSquare(int min, int max){
int len = max - min + 1;
int copy_min = min, permanent_min = min;
for(int i = 0; i < len; i++){
for(int j = 0; j< len; j++){
if(min > max)
if(min % len < permanent_min)
System.out.print((min % len )+ len);
else
System.out.print(min % len);
else
System.out.print(min);
min++;
}
min = ++copy_min;
System.out.println();
}
}
public static void printSquare(int min, int max) {
for (int i = min; i <= (max -min)+min; i++) {
for( int j =i; j <= max ; j++) {
System.out.print(j);
}
for (int j1= min; j1<= i * 1 - 1; j1++) {
System.out.print(j1);
}
System.out.println();
}
}