I'm solving a challenge about making an algorithm.
There is a game of land.
The Land of Landing game consists of 4 rows in total N rows, with scores in all the columns.
When stepping down from the first row, down one row, you must step down on one of the four squares of each row.
However, there is a special rule that can not be repeated in the same row when landing one row at a time.
For example,
| 1 | 2 | 3 | 5 |
| 5 | 6 | 7 | 8 |
| 4 | 3 | 2 | 1 |
If you have stepped on line 1 through line 4 (5), you can not step on line 4 (8) on line 2.
I was trying to use Dynamic Programming in Java.
import java.lang.Math;
import java.util.*;
class Solution {
int [][] dp = new int[100001][4];
int solution(int[][] land) {
int r = land.length;
for (int i = 0; i < 4; i++)
{
dp[0][i] = land[0][i];
}
for (int i = 0; i <r; i++)
{
for (int j = 0; j < 4; ++j)
{
for(int k = 0; k < 4; ++k)
{
if (j != k)
{
dp[i][j] = Math.max(dp[i][j], land[i][j] + dp[i-1][k]);
}
}
}
}
int ans = 0;
for (int i = 0; i < 4; ++i)
{
ans = Math.max(ans, dp[r-1][i]);
}
return ans;
}
}
it shows error
java.lang.ArrayIndexOutOfBoundsException: -1
I was thinking that it was probably something wrong with the Conditional statement.
In C++, these conditional statements are right. It's running perfect. Why am I getting an error in Java? Is there any difference using array between Java and C++?
Can you please tell me how can I solve this error?
dp[i-1][k] - i starts from ZERO in upper loop, so results of this expression becomes -1 as index.
Java array index starts from ZERO, not -1, which is why ArrayIndexOutOfBoundsException.
I don't know the business case, but one way to solve this is, start first for loop from 1 instead 0.
Related
I am working on a program that prints out a table filled with randomly-generated integers. Most of the logic is relatively straightforward and works pretty well. One thing I would like to do is to add up and print out total values for each column, as well as the final total of all the values in the table. I have searched around trying to find an answer but have had no luck with figuring it out.
rowNbr = 7; // ROW CONTROLS
colNbr = 5; //COLUMN CONTROLS
rpt01 = String.format("%0" + (colNbr-1) + "d", 0).replace("0",dash); //Redefine rpt01
colBld = String.format("|---------------|%s\n",rpt01); //Redefine colBld
String cnrTxt = "First Quarter";
System.out.printf(colBld);
System.out.printf("|%-15s",cnrTxt);
for(int i = 1; i < colNbr; i = i++){ //Open for loop (columns)
String regTxt = "Region " + i++;
System.out.printf("|%-10s",regTxt);
} //End for
System.out.printf("|\n");
//Initialize array
int sales[] = new int[100];
int idx = 0;
for(int i = 1; i <= rowNbr-3; i++){
String prodTxt = "Product " + i;
System.out.printf(colBld);
System.out.printf("|%-15s|",prodTxt);
for(int j = 0; j < colNbr-1; j++){ //Open for loop (columns 2)
sales[idx] = (int)(Math.random() * 16 + 1);
System.out.printf("%-10d|",sales[idx]);
idx++;
} //End for
System.out.printf("\n");
} //End for
int totalNbr = 0; //Placeholder zero
int regNbr = 0; //Placeholder zero
String totalTxt = "Final Total: ";
String regTxt = "Region Totals";
System.out.printf(colBld);
System.out.printf("|%-15s|%-10s|\n",regTxt,regNbr);
System.out.printf(colBld);
System.out.printf("|%s%s\n",totalTxt,totalNbr);
System.out.printf(colBld);
Here is what the code currently looks like once run:
|---------------|----------|----------|----------|----------|
|First Quarter |Region 1 |Region 2 |Region 3 |Region 4 |
|---------------|----------|----------|----------|----------|
|Product 1 |2 |10 |3 |1 |
|---------------|----------|----------|----------|----------|
|Product 2 |15 |15 |7 |16 |
|---------------|----------|----------|----------|----------|
|Product 3 |15 |13 |7 |9 |
|---------------|----------|----------|----------|----------|
|Product 4 |4 |14 |11 |11 |
|---------------|----------|----------|----------|----------|
|Region Totals |0 |
|---------------|----------|----------|----------|----------|
|Final total: 0
|---------------|----------|----------|----------|----------|
Honestly have no idea where to even begin with this. Any help is appreciated!
Since you have already sequentially filled the sales array with random Integer values to represent sequentially displayed Regions it is then a simple matter of stepping through the array elements in increments of the number of regions and summing the elements detected in each step.
To determine the actual number of Regions that will be displayed and the number of Region Totals to keep track of, we can base it from the value contained within the colNbr variable less 1 (5 - 1 = 4 regions will be displayed).
Knowing this we declare yet another integer Array named regionTotals and give it a length of 4:
int[] regionTotals = new int[colNbr-1];
Now it's a matter of stepping through the sales array elements and summing the proper sales array element to the proper regionTotal element, like this:
int regionCols = colNbr-1;
int[] regionTotals = new int[regionCols];
int stepCounter = 0;
for (int i = 0; i < sales.length; i++) {
stepCounter++;
if (stepCounter > regionCols) { stepCounter = 1; }
int regionIndex = (stepCounter - 1);
regionTotals[regionIndex]+= sales[i];
}
System.out.println("\nRegion Totals: " + Arrays.toString(regionTotals) + "\n");
Place the above code directly above the declaration & initialization of the totalNbr integer variable:
int totalNbr = 0; //Placeholder zero
How you format the regionTotals array elements into your table is up to you but do remember, the Array is zero based so the element at index 0 of the array contains the summation for Region 1.
I'm trying to build a sudoku solver. I know my code is messy and there will probably be a much simpler way to do it, but I would like finish the algorithm the way I started.
The algorithm starts doing what I want (filling the blank spaces with the first number that could fit), but when it reaches a point with no options, I don't know how to go back and erase the last number I inserted to try with another combination. But I can't just erase the last number from the matrix because it could be a number that wasn't placed by the algorithm.
If someone could help I would really appreciate it.
public class Backtracking{
public static void Sudoku(int[][] sudokuTable){
if (isAnswer(sudokuTable)){
printSudoku(sudokuTable);
}else{
for (int j = 1; j <=9; j++){
if (canfit(sudokuTable, j)){
addToSudoku(sudokuTable, j);
printSudoku(sudokuTable);
Sudoku(sudokuTable);
}
}
}
}
public static void addToSudoku(int[][] sudokuTable, int n){
int i = 0;
int j = 0;
boolean done = false;
while (i < 9 && !done){
while (j < 9 && !done){
if (sudokuTable[i][j] == 0){
sudokuTable[i][j] = n;
done = true;
}
j++;
}
i++;
}
}
public static void printSudoku(int[][] sudokuTable){
for (int i = 0; i < 9; i++){
for (int j = 0; j < 9; j++){
System.out.print(sudokuTable[i][j] + " ");
}
System.out.println();
}
System.out.println();
}
public static boolean isAnswer(int[][] sudokuTable){
int sum = 0;
for (int i = 0; i < 9; i++){
for (int j = 0 ; j < 9; j++){
if (sudokuTable[i][j] > 9 || sudokuTable[i][j] < 1)
return false;
else
sum++;
}
}
if (sum != 405)
return false;
return true;
}
public static boolean canfit(int[][] sudokuTable, int n){
int i = 0;
int j = 0;
boolean pos = false;
boolean fit = true;
while (i < 9 && !pos){
while (j < 9 && !pos){
if (sudokuTable[i][j] == 0)
pos = true;
else
j++;
}
if (!pos)
i++;
}
for (int k = 0; k < 9; k++){
if (sudokuTable[i][k] == n && k != j)
fit = false;
}
if (fit){
for (int l = 0; l < 9; l++){
if(sudokuTable[l][j] == n && l != i)
fit = false;
}
}
if (fit){
if (i >= 0 && i < 3)
i = 0;
else if (i >=3 && i < 6)
i = 3;
else if (i >=6 && i < 9)
i = 6;
if (j >= 0 && j < 3)
j = 0;
else if (j >=3 && j < 6)
j = 3;
else if (j >=6 && j < 9)
j = 6;
for (int m = i; m < i+3; m++){
for (int o = j; o < j+3; o++){
if (sudokuTable[m][o] == n)
fit = false;
}
}
}
return fit;
}
Try to return true or false from your Sudoko method.
when isAnswer() method returns true, print table. Then return true from Sudoko() method.
Now inside your for loop, where you are calling Sudoko() method recursively, check if it returns true, or false. If it returns true, that means your choice is correct and it leads to a solution, you need not to do anything else. If it returns false, remove the number you set using addToSudoko() method. Make the table as it was before calling addToSudoko() method and continue iterating.
And if your for loop, loops for 9 times and none of the number has a suitable spot, that means if loop ends, return false.
Hope this helps
Actually you can backtracking moves by using an array, each time a move is wrong you just start to remove some moves and try a different move, however this has a problem:
the complexity of trying all possible moves is huge (how long does it takes to try all digits on a number with 81 digits? even if you cut computation time here and there , you will need all the time of the universe)
the main problem in sudoku is that you have no clue which was the wrong move if you move randomly.
Assume the following case sudoky with 2x2 cells:
+----+----++-----+-----+
| 1 | 2 || 3 | 4 |
+----+----++-----+-----+
| 4 | 3 || 1 | 2 |
+====+====++=====+=====+
| 2 | 1 || 4 | 3 |
+----+----++-----+-----+
| 3 | 4 || 2 | 1 |
+----+----++-----+-----+
If you use your algorithm in the following (unsolved) case:
+----+----++-----+-----+
| 1 | || | 4 |
+----+----++-----+-----+
| | || | |
+====+====++=====+=====+
| 2 | || | |
+----+----++-----+-----+
| | 4 || | 1 |
+----+----++-----+-----+
it is possible he will run into the following sequence
+----+----++-----+-----+
| 1 | || 2 | 4 |
+----+----++-----+-----+
| | || 2 | |
+====+====++=====+=====+
| 2 | || | |
+----+----++-----+-----+
| | 4 || | 1 |
+----+----++-----+-----+
Actually the added "twos" are both wrong, but when your algorithm find that those are wrong because you have 2 "twos" in the same column, you don't know which one was the wrong one (the first added, the second added, or both?)
A correct backtracking algorithm would works like this:
You start with a 81 cells arrays, and you start placing numbers (in sequence).
.
for(int i=0; i<81; i++)
array[i] = TryNumber();
.
then you check after each added number if that was correct.
.
if(SomeNumberNotCorrect())
break; // you know you can stop "tryingnumbers" so you can save on loop executions
.
But you don't know which was the wrong number
Now writing a correct algorithm that solves sudokus by attemps and do not run in million of years is pretty long and I cannot write it here but I don't think the way you choosen is the best. The best way is to apply the same strategies used by players. Just keep in mind that if you want an algorithm to resolve sudokus in a similiar way to how Chess is played by computer your algorithm would require much more time than a Chess game (infact a computer cannot analize chess moves more than 5-6 turns). But infact Sudokus can be resolved with much faster algorithms.
Instead I've already done in past a simple solver you could actually try to apply the same strategies a player would use to solve it:
In example:
For each cell, check if current Sector, Column and Line have already all numbers except 1, then you can add that number. And to check that for each cells you just need 81*81*81 moves.
When your solver do not find anymore solutions on a Sudoku, it is just because you have to develop as player a new strategy and then you need to apply it to your program, in short you will have a program that will be able to solve every sudoku (not very hard, and actually this is the reason that there are a lot of free sudoku solvers out there).
I was trying to create the simpliest matrix - 2d array and I have trouble with my code, it is kind of working, but not correctly.
Code:
int result = 0;
int[][] matrix = new int[2][2];
for(int rows = 0; rows < matrix.length; rows++)
for(int cols = 0; cols < matrix[rows].length; cols++)
matrix[rows][cols] = (rows + cols);
System.out.println("matrix is: "+matrix);
result = matrix[0][0]*matrix[1][1]-matrix[0][1]*matrix[1][0];
System.out.println("Result is: "+result);
Output:
matrix is: [[I#1db9742
Result is: -1
I had this one:
int result = 0;
char[][] matrix= new char[2][2];
for(int rows = 0; rows < 2; rows++)
for(int cols = 0; cols < 2; cols++)
matrix[rows][cols] = (char)('1' + rows * 2 + cols);
for(int rows = 0; rows < 2; rows++)
for(int cols = 0; cols < 2; cols++)
System.out.println("matrix is: "+matrix[rows][cols]);
result = matrix[0][0]*matrix[1][1]-matrix[0][1]*matrix[1][0];
System.out.println("Result is: "+result);
Output:
matrix is: 1
matrix is: 2
matrix is: 3
matrix is: 4
Result is: -2
But I do not want char, I want integer (because what if work with big matrix calculations later) and I do not understand tis part:
('1' + rows * 2 + cols)
because I copied it from some other code. How to get the first one to work like second and what is that part in brackets (why writen like that)? Thanks in advance!
I got nice stuff with 1 2 3 4 that is what I wanted, but I also need explanation for what that "('1' + rows * 2 + cols)" means. I want to get 1 2 3 4 for matrix 2D array, and then 1*4-2*3 for result. Maybe '1' is to start from 1, not from 0 in loop and write from 1 in array. I found it in some other code, not my solution, first one is mine and not working properly. I added:
for(int cols = 0; cols < matrix[rows].length; cols++)
as you suggested.
*I rewrote it to english.
Sorry for language confusion.
I don’t understand why I get characters instead of 2D array when printing matrix after loop, before calculating.
I think the result is correct.
This is your matrix :
| 0 1 |
| 1 2 |
And this is what you do : 0 * 2 - 1 * 1
and the good answer is = -1.
The code for what you want is :
int i = 1;
for(int redovi = 0; redovi < matrica.length; redovi++)
for(int kolone = 0; kolone < matrica.length; kolone++)
matrica[redovi][kolone] = i;
++i;
So we will get a matrix like this one :
|1 2|
|3 4|
And so the good answer for what you want. If I well understood.
You should look closer on what you write into matrix. The first looks like:
0 1
1 2
and second:
'1' '2'
'3' '4'
So both determinants are calculated almost as you expect. You can change one line in the first code to this:
matrix[rows][cols] = (1 + rows*matrix[rows].length + cols);
So that your matrix is 1234.
By the way, using char[][] worked because any char can be represented as a number that is an index in character map.
I also need explanation for what that "('1' + rows * 2 + cols)" means
Character '1' is 49th in character map, '2' is 50th and so on. Try to compile this, for example:
System.out.println((int)'1');
So "('1' + rows * 2 + cols)" generates a matrix that can be represented as int[][]:
49 50
51 52
This question already has answers here:
How does this while block work? [closed]
(2 answers)
Closed 7 years ago.
Consider the following method:
public int foo(int n) {
int x = 1;
int k = 0;
while (x <= n) {
x = x * 2;
k = k + 1;
}
return k;
}
What value is returned by foo(13)? I know the answer is 4 but could someone please tell me why it is 4?
x doubles with every iteration through the loop, and k increases by 1 every time through.
It's simple enough to draw out with a table.
x | k
1 | 0
2 | 1
4 | 2
8 | 3
16 | 4
32 | <end of loop>
x doubles at each step until it becomes greater than 13. So x = 1 -> 2 -> 4 -> 8 -> 16. So it gets doubled 4 times and k is also incremented 4 times. So from 0 it becomes 4.
Below is the step/algorithm steps:
X=1 k=0 n =13
Step 1: x=2 k=1
Step 2: x=4 k=2
Step 3: x=8 k = 3. Since 8<13...
Step 4: x=16 k= 4. 16>13, so return k=4.
Its finding n < 2^k where k is your answer. When n = 13: 13 < 2^k = 2^4 = 16.
K is the number of times the while loop is entered.
As x is 2 power, 2^3 is little than 13, so it enters one last time, 2^4 is bigger than 13, and then k is 4
pretty simple...
public int foo([13]) {
int x = 1;
int k = 0;
while (x <= n) {
x = x * 2;
k = k + 1;
}
return k;
}
your while loop stops when x is bigger or equal to n[13]
each time x is multiplied by 2
(definition)x = 1
x = 2
x = 4
x = 8
x = 16 (is now over n[13])
and so the while loop runs 4 times
while (x <= n) {
x = x * 2;
k = k + 1;//dis thang
}
k[0]+1=1
k[1]+1=2
k[2]+1=3
k[3]+1=4
and thats why its 4.
Pasted below is a program to print Pascal's triangle. The way to compute any given position's value is to add up the numbers to the position's right and left in the preceding row. For instance, to compute the middle number in the third row, you add 1 and 1. the sides of the triangle are always 1 because you only add the number to the upper left or the upper right (there being no second number on the other side).
int pascal[][]=new int[50][50]; int j;
for(int i=0;i<m;i++)
{
pascal[i][i]=1;
for(j=1;j<i;j++)
{
pascal[i][j]=pascal[i-1][j-1]+pascal[i-1][j];
}
for(int n=1;n<=m-i;n++)
{
System.out.print(" ");
}
for(int k=1;k<=i;k++)
{
System.out.print(pascal[i][k]);
System.out.print(" ");
}
System.out.println(" ");
}
Is there any way to accomplish this without using arrays?
I'm trying this combination without arrays:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
You can easily compute it using Combination.
You can compute combination as:
|n| = (n!) / ((n-k)!*k!)
|k|
So if you want to print the image above you would start as:
int size = 5;
for(int i = 0; i < size; i++){
for(int k = 0; k < (size - i)/2; k++)
System.out.print(" "); // print the intendation
for(int j = 0; j <= i; j++){
System.out.print(combination(i,j));
}
System.out.println("");
}