understanding parts of this Sudoku solver - java

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.

Related

Arithmetic Progression in java

i'm just started to learn java yesterday. But, now i met difficulty to show the arithmetic progression like the display below:
1 2 2 2 3 3 3 3 3 4 4 4 4 4 4 4
From that example, i know that every odd numbers, the numbers increment. I've tried to make it, but the display just keep showing like this:
2 4 4 4 6 6 6 6 6 8 8 8 8 8 8 8 10 10 10 10 10 10 10 10 10
Here's my code:
for (int i = 0; i <= 10; i++) {
if (i % 2 == 0) {
for(int j = 1; j<i; j++){
System.out.print(i + " ");
}
}
}
And then, i want to take the last value of it. For example, if i have row = 3, it must be value = 2.
because :
row = 1 2 3 4 5 6 7 8 9 10
value = 1 2 2 2 3 3 3 3 3 4
Would you tell me, what line is exactly must be fix? Thank you
It's not about a line that is wrong, it's your approach that's a bit off. You could fix it in multiple ways. Easiest (but not most efficient) way is this:
for (int i = 0; i <= 10; i++) {
if (i % 2 == 0) {
for(int j = 1; j<i; j++){
System.out.print((i/2) + " ");
}
}
}
As you can see, only the output was changed and now it works. However, iterating over 11 numbers (0-10) when you only really care about 4-5 is not necessarily the best way to go here.
It also doesn't make your code easy to understand.
Here's an alternative.
int amount = 1;
for (int i = 1; i <= 5; i++) {
for (int j = 0; j < amount; j++) {
System.out.print(i + " ");
}
amount = amount + 2;
}
Here you can see that the outer for has been changed to only take the numbers we actually care about, which means we can remove the if completely.
We just have to somehow decide how many times we want to execute the print call, which is done with the amount variable.
Try this.
for (int i = 1, r = 1; i <= 4; ++i, r += 2)
System.out.print((i + " ").repeat(r));
You can calculate value from row with this method.
static int value(int row) {
return (int)Math.ceil(Math.sqrt(row));
}
So you can also do like this.
for (int row = 1; row <= 16; ++row)
System.out.print(value(row) + " ");
result:
1 2 2 2 3 3 3 3 3 4 4 4 4 4 4 4
Hey it's a representation of a sequence that grows by 2 every step.
i.e the first element is 1 which shows up one time.
the second element is 3 which shows up 3 times (2 2 2)
and so on and on..
so the code you need is:
int a = 1;
for(int i=1; i<=10;i++){
int j=1;
while(j<=a){
System.out.print(i);
j++;
}
a+=2;
}
printing the value in a wanted row:
Scanner in = new Scanner(System.in);
int rowU = in.nextInt(); // User inputs row
int row = 1; // a variable to keep track of the rows
int repeats = 1; // the number of times a value shoud appear
for(int value=1;value<=10;value++){
int j=1;
while(j<=repeats){
if(row==rowU) // if we got to the wanted row
System.out.println(value); // print the wanted value
j++;
row++;
}
repeats+=2;
}
There is a better, more efficient way to get the value of a wanted row:
int wanted_value = Math.ceil(Math.sqrt(wanted_row));
Thanks to #saka for bringing this one up!
Hope I helped :)
i % 2 == 0 means that the following code is only going to be executed, if i is even.
You could try removing the if, and change the second for to something like
int j = 0; j < 2 * i - 1; j++.
This code snippet will do the work
int n=4;
int printTimes=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<printTimes;j++)
System.out.print(i+" ");
printTimes+=2;
}
System.out.println();
Here is the example code.
int start = 1;
int end = 5;
int time = 1;
for (int i = start,j = time; i < end; i++,j+=2) {
for (int k = 0; k < j; k++) {
System.out.print(i+" ");
}
}

3 Dice Sum Counting Program Java

For my Computer Science Class, my teacher is asking us to do the following:
Program Description: You are learning to play a new game that involves 3 six-sided die. You know that if you knew the probability for each of the possible rolls of the die that you’d be a much better competitor.
Since you have just been studying arrays and using them to count multiple items that this program should be a snap to write. This will be cool since the last time we did this we work just looking for how many times 9 or 10 could be rolled and this program won’t require any if statements.
Required Statements: output, loop control, array
Sample Output:
Number Possible Combinations
1 0
2 0
3 1
4 3
5 6
6 10
7 15
8 21
9 25
10 27
11 27
12 25
13 21
14 15
15 10
16 6
17 3
18 1
I can easily do this with an if statement, but I don't understand how to do it without one. It is especially tricky because under hints, she wrote: "These programs utilize a counting array. Each time a value is generated the position at that index is incremented. It’s like the reverse of the lookup table." I have no idea what this means.
Here's my code with the if statement:
public class prog410a
{
public static void main(String args[])
{
System.out.println("Number\tPossible Combinations");
for (int x = 1; x <= 18; x++)
{
int count = 0;
for (int k = 1; k <= 6; k++)
{
for (int i = 1; i <= 6; i ++)
{
for (int j = 1; j <= 6; j++)
{
if (k + i + j == x)
count++;
}
}
}
System.out.println(x + "\t\t\t" + count);
}
}
}
So I guess my overall question is this: How can I emulate this, but by using some sort of array instead of an if statement?
You don't need the outer x loop. All you need is three nested loops, one for each die. You will also need an array of integers all initialized to zero. Inside the innermost dice loop, you just use the sum of the three dice as the index to you integer array and increment the value at that index.
After you complete the dice loops, then you can iterate over your integer array and output the frequency of your results.
Since this is homework, I won't write the code for you, just give you the general outline.
Create a count array of size 18. Initialise all values to 0.
Have three nested loops counting from 1 to 6 exactly like your three inner loops. These represent the values on your dice.
Inside your innermost loop, add the three loop counters together. This is your dice total and you use it as an index into the count array to increment the value at that index.
After you exit the three nested loops, use another loop to iterate through the count array to print out the values.
This seems to work - and without if:
public void test() {
// Remember to -1 because arrays are accessed from 0 to length-1
int[] counts = new int[18];
// Dice 1.
for (int k = 1; k <= 6; k++) {
// Dice 2.
for (int i = 1; i <= 6; i++) {
// Dice 3.
for (int j = 1; j <= 6; j++) {
// Count their sum (-1 as noted above).
counts[i + j + k - 1] += 1;
}
}
}
// Print out the array.
System.out.println("Number\tPossible Combinations");
for (int i = 0; i < counts.length; i++) {
System.out.println("" + (i + 1) + "\t" + counts[i]);
}
}
Essentially you build the results in an array then output them.
From Wikipedia: In computer science, a lookup table is an array that replaces runtime computation with a simpler array indexing operation. The savings in terms of processing time can be significant, since retrieving a value from memory is often faster than undergoing an 'expensive' computation or input/output operation., this means that usually we use lookup tables to save computation time by precalculating some process into a table in which we already stored the result. In this case you are using the process to store the number of possible outcomes in an array. Basically you are building a lookup table for the dice outcome. Only the three inner loops are needed.
for (int k = 1; k <= 6; k++)
{
for (int i = 1; i <= 6; i ++)
{
for (int j = 1; j <= 6; j++)
{
arr[k + i + j-1] = arr[k + i + j-1] +1;
}
}
}
And this is what is happening:
dices index
i j k (i+j+k)
1 1 1 3
1 1 2 4
1 1 3 5
1 1 4 6
1 1 5 7
1 1 6 8
1 2 1 4
1 2 2 5
1 2 3 6
1 2 4 7
1 2 5 8
1 2 6 9
1 3 1 5
1 3 2 6
.
.
.
You are enumerating each possible outcome and then adding the spot in the array with the index generated. When the nested loops are done, you will have an array containing the desired information.

Calculating matrix sqaure determinant

I'm trying to code a function that calculates a sqaured-matrix determinant (of which all numbers of the diagonal are multiplied) for self coding. I got the main idea but I can't get the right result because of some calculation error. this is the code I wrote:
public static int det(int[][] matrix, int n) {
int i,j, k, det=1;
for (i=0; i < matrix.length; i++) {
for (j=0; j < matrix[i].length; j++) {
if (i<j)
if(matrix[i][j] == 0) {
//isTriangle = true;
det *= matrix[i][i];
}
if (i>j)
if (matrix[i][j] == 0) {
//isTriangle = true;
det *= matrix[i][i];
}
}
}
return det;
}
After I run this function I get results that don't include the final number (matrix[n][n]) because it wasn't multiplied for some reason. Next thing I tried to set a for loop that will multiply all the members of the diagonal (det *= matrix[k][k]) outside the two loops but then I got very high numbers as a result. What am I doing wrong with the math here?
Your algorithm is not correct. It should look like this:
Make the input matrix triangular using Gaussian elimination.
Multiply all numbers on the diagonal(that is, find a product of matrix[i][i] for all i).
You cannot skip the first step.
You can also use a recursion.
Given the n by n matrix M, we create W(i,j) by striking out column i and row j of M.
So for the 3 x 3 matrix:
1 2 3
4 5 6
7 8 9
W(0,0) =
5 6
8 9
W(1,0) =
4 6
7 9
etc.
Now you can expand around any row or column.
Additionally you need to alternate + and -; for a 3 x 3 Matrix it would look like this:
+ - +
- + -
+ - +
So expanding around column 2, we get:
+ 3 * det
4 5
7 8
- 6 * det
1 2
7 8
+ 9 * det
1 2
4 5
Or
-1^(2+0) * M(2,0)*det(W(2,0))
+ -1^(2+1) * M(2,1)*det(W(2,1))
+ -1^(2+2) * M(2,2)*det(W(2,2))
I am deliberately working from example because the formula looks a bit scary:
det(M) = sum(i=0 to N-1){ -1 ^ i * M(i,0) * det(W(i,0)) }
Note that in this formula that we are expanding around the first row (instead of the third column as before)

Creating a looping square with java

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();
    }
    
}

Java Sudoku Solver Output

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.

Categories