Knight's Least Amount of Moves Debug Java - java

Basically I need to find the smallest amount of moves it would take for a knight to reach a certain position on a 8x8 grid numbered 0-63 inclusive.
I have cross checked all test cases that I could think of and every test case is exactly what I am looking for. I used an elimination and placement algorithm modeled after an O(1) solution but for a knight instead.
The test cases I receive for the problem are confidential and I am left to guess what I have missed. When I try to verify my code I receive an output of:
Test 1 passed!
Test 2 failed.
Test 3 passed!
Test 4 failed.
Test 5 failed.
Test 6 failed.
Test 7 failed.
Test 8 failed.
Test 9 failed.
Test 10 failed.
Code:
public class Test {
public static boolean found = false;
public static void main (String[] args) {
int[][] arr = { // 0 1 2 3 4 5 6 7
{ 0, 1, 2, 3, 4, 5, 6, 7}, // 0
{ 8, 9, 10, 11, 12, 13, 14, 15}, // 1
{16, 17, 18, 19, 20, 21, 22, 23}, // 2
{24, 25, 26, 27, 28, 29, 30, 31}, // 3
{32, 33, 34, 35, 36, 37, 38, 39}, // 4
{40, 41, 42, 43, 44, 45, 46, 47}, // 5
{48, 49, 50, 51, 52, 53, 54, 55}, // 6
{56, 57, 58, 59, 60, 61, 62, 63}, // 7
};
int src = 63; // Changed to parameters values later on in testing
int dest = 30; // Changed to parameters values later on in testing
int[] loc = pos(arr, src);
int[][] productMatrix;
int finalNumber = 0;
while(!found && arr[loc[0]][loc[1]] != dest)
{
productMatrix = createknights(arr, loc[0], loc[1], dest);
printMatrix(productMatrix);
System.out.println("--------------------");
finalNumber++;
}
System.out.println(finalNumber);
}
public static int[][] createknights(int[][] arr, int r, int c, int goal)
{
arr[r][c] = -1;
int[][] knightLoc = getKnightLoc(arr);
for(int i = 0; i < knightLoc.length; i++)
{
int[][] possiblePositions = {
{knightLoc[i][0] - 2, knightLoc[i][1] - 1}, //Up Left
{knightLoc[i][0] - 2, knightLoc[i][1] + 1}, //Up Right
{knightLoc[i][0] + 2, knightLoc[i][1] - 1}, //Down Left
{knightLoc[i][0] + 2, knightLoc[i][1] + 1}, //Down Right
{knightLoc[i][0] - 1, knightLoc[i][1] - 2}, //Left Up
{knightLoc[i][0] + 1, knightLoc[i][1] - 2}, //Left Down
{knightLoc[i][0] - 1, knightLoc[i][1] + 2}, //Right Up
{knightLoc[i][0] + 1, knightLoc[i][1] + 2} //Right Down
};
for( int[] row : possiblePositions)
{
if( checkLoc(arr, row[0], row[1]) )
{
if( arr[row[0]][row[1]] == goal )
{
found = true;
break;
}
arr[row[0]][row[1]] = -1;
}
}
}
return arr;
}
public static int[][] getKnightLoc(int[][] arr)
{
int knightNum = getKnightNum(arr);
int[][] knightLocArray = new int[knightNum][2];
for(int i = 0; i < arr.length; i ++)
{
for(int a = 0; a < arr[i].length; a++)
{
if(arr[i][a] == -1)
{
knightLocArray[(knightNum - 1)] = new int[]{i,a};
knightNum--;
}
}
}
return knightLocArray;
}
public static int getKnightNum(int[][] arr)
{
int knightNum = 0;
for(int i = 0; i < arr.length; i ++)
{
for(int a = 0; a < arr[i].length; a++)
{
if(arr[i][a] == -1)
{
knightNum++;
}
}
}
return knightNum;
}
public static boolean checkLoc(int[][] arr, int r, int c)
{
if(r >= 0 && c >= 0 && r < arr.length && c < arr[r].length && arr[r][c] != -1)
{
return true;
}
return false;
}
public static int[] pos(int[][] arr, int src)
{
for(int i = 0; i < arr.length; i ++)
{
for(int a = 0; a < arr[i].length; a++)
{
if(arr[i][a] == src)
{
return new int[]{i , a};
}
}
}
return null;
}
public static void printMatrix(int[][] arr)
{
for(int i = 0; i < arr.length; i ++)
{
for(int a = 0; a < arr[i].length; a++)
{
System.out.print(arr[i][a] + " ");
}
System.out.println();
}
}
}
The O(1) model I checked my answers with:
O(1) model
Output example (ending value is the answer: src=63, dest=30):
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 -1 47
48 49 50 51 52 -1 54 55
56 57 58 59 60 61 62 -1
--------------------
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 -1 30 -1
32 33 34 35 -1 37 -1 39
40 41 42 -1 44 45 -1 -1
48 49 50 51 -1 -1 54 55
56 57 58 -1 60 -1 62 -1
--------------------
0 1 2 3 4 5 6 7
8 9 10 11 -1 13 -1 15
16 17 18 -1 20 -1 22 -1
24 25 -1 27 -1 -1 30 -1
32 -1 34 -1 -1 -1 -1 -1
40 41 -1 -1 -1 45 -1 -1
48 -1 50 -1 -1 -1 54 -1
56 57 -1 -1 -1 -1 -1 -1
--------------------
3 <----Answer
Please tell me what I am missing. Thanks!
Edit:
int src & int dest will not be hard coded at run time. The values will be replaced with parameter values. The values are hard coded for testing purposes.

I’m afraid your program prints 3 every time. This is because you have hardcoded the source as square 63 and the destination as square 30. Coincidentally the answers to two of the test cases are indeed 3. This is a reasonable guess. So you pass those two and fail the rest.
Instead you should of course read the input in whatever way is specified with your assignment.

It turns out that this block of code is a perfect solution except for the fact that apparently the test cases are tested in one continuous section of code.
For example, making a separate method allowed for me to call this section of code:
public static void main (String[] args) {
//Test Cases
System.out.println(answer(63,5));
System.out.println(answer(19,4));
System.out.println(answer(63,0));
}
This would print out:
5
0
0
After further debugging, I found what had caused the leading zeros is disregarding the found variable at the top of the code. Thus, leading to completely incorrect answers.
Previous Code:
while(!found && arr[loc[0]][loc[1]] != dest)
{
productMatrix = createknights(arr, loc[0], loc[1], dest);
printMatrix(productMatrix);
System.out.println("--------------------");
finalNumber++;
}
System.out.println(finalNumber);
New Code:
while(!found && arr[loc[0]][loc[1]] != dest)
{
productMatrix = createknights(arr, loc[0], loc[1], dest);
printMatrix(productMatrix);
System.out.println("--------------------");
finalNumber++;
}
found = false;
System.out.println(finalNumber);
Thus now relaying the correct answers.
Thank you Ole V.V. for brainstorming a solution! I guess just needed some time away from the problem and a couple of ideas.

Related

How can I read matrix array different way in Java?

I have a 8x8 matrix array. I want to read matrix values (elements) as shown in the picture.
Ho can I do it?
I've defined array like this.
public static void main(String args[]) {
int[][] myArray = new int[8][8];
int start = 0;
for (int i = 0; i<8; i++){
for (int j = 0; j<8; j++) {
myArray[i][j] = start;
start++;
}
}
}
public static List<Integer> readMatrix(int[][] matrix) {
int totalRows = matrix.length;
int totalCols = matrix[0].length;
List<Integer> res = new ArrayList<>(totalRows * totalCols);
List<Integer> diagonal = new ArrayList<>(Math.max(totalRows, totalCols));
boolean reverseOrder = true;
for (int col = totalCols - 1; col >= 0; col--) {
for (int row = 0; row < totalRows && col + row < totalCols; row++)
diagonal.add(matrix[row][col + row]);
if (reverseOrder)
Collections.reverse(diagonal);
res.addAll(diagonal);
reverseOrder = !reverseOrder;
diagonal.clear();
}
for (int row = 1; row < totalRows; row++) {
for (int col = 0; col < totalCols && col + row < totalRows; col++)
diagonal.add(matrix[col + row][col]);
if (reverseOrder)
Collections.reverse(diagonal);
res.addAll(diagonal);
reverseOrder = !reverseOrder;
diagonal.clear();
}
return res;
}
Here's my solution. Code contains comments explaining the traversal algorithm.
public class MatrixTraversal {
private static int[][] matrix;
private static void displayElement(int row, int col, int length, int count) {
System.out.printf("%" + length + "d. Next element [%" + length + "d][%" + length + "d] = %" + length + "d%n",
(count + 1),
row,
col,
matrix[row][col]);
}
private static void displayMatrix() {
int length = getLength();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (j > 0 && j < matrix[i].length) {
System.out.print(" ");
}
System.out.printf("%" + length + "d", matrix[i][j]);
}
System.out.println();
}
System.out.println();
}
private static int getLength() {
int rows = matrix.length;
int cols = matrix[0].length;
int number = rows * cols;
int length = (int) (Math.log10(number) + 1);
return length;
}
private static void initMatrix(int rows, int cols) {
System.out.printf("rows = %d , columns = %d%n", rows, cols);
System.out.println();
if (rows > 0 && cols > 0) {
matrix = new int[rows][cols];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
matrix[row][col] = (row * cols) + col;
}
}
displayMatrix();
}
else {
throw new IllegalArgumentException("rows and columns must both be positive");
}
}
// Algorithm:
// 1. Start at first row, last column.
// 2. Go to same row, column to left.
// a. If can't go left, go down one row, i.e. same column, next row.
// b. If can't go left, go to step 3.
// 3. Go diagonally down and to the right until reach either last row or last column.
// a. If can't go diagonally down and to the right, go to 4.
// 4. Go to same column, next row.
// a. If can't go down, go left, i.e. same row, column to left.
// b. If can't go left, go to step 5.
// 5. Go diagonally up and to the left until reach either first row or first column.
// a. If can't go diagonally up and to the left, go to 6.
// 6. Go back to step 2.
// 7. Finish at last row, first column.
private static void traverse() {
int length = getLength();
int total = matrix.length * matrix[0].length;
System.out.println("Total = " + total);
int row = 0;
int col = matrix[row].length - 1;
System.out.println("Start col = " + col);
int count = 0;
System.out.printf("%" + length + "d. First element [%" + length + "d][%" + length + "d] = %" + length + "d%n",
1,
row,
col,
matrix[row][col]);
count++;
while (count < total) {
if (col - 1 >= 0) {
col--;
displayElement(row, col, length, count);
count++;
}
else {
if (row < matrix.length - 1) {
row++;
displayElement(row, col, length, count);
count++;
}
}
while (row < matrix.length - 1 && col < matrix[row].length - 1) {
row++;
col++;
displayElement(row, col, length, count);
count++;
}
if (row < matrix.length - 1) {
row++;
displayElement(row, col, length, count);
count++;
}
else {
if (col - 1 >= 0) {
col--;
displayElement(row, col, length, count);
count++;
}
}
while (row > 0 && col > 0) {
row--;
col--;
displayElement(row, col, length, count);
count++;
}
}
}
/**
* Requires following two <tt>java</tt> command arguments (in listed order):
* <ol>
* <li>number of rows in matrix</li>
* <li>number of columns in matrix</li>
* </ol>
*
* #param args - <tt>java</tt> command arguments.
*/
public static void main(String[] args) {
if (args.length > 1) {
int rows = Integer.parseInt(args[0]);
int cols = Integer.parseInt(args[1]);
initMatrix(rows, cols);
traverse();
}
else {
System.out.println("ARGS: <# of rows in matrix> <# of columns in matrix>");
}
}
}
Tested on different dimensions including one row and several columns and one column and several rows. Here is the output for an 8x8 matrix.
rows = 8 , columns = 8
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63
Total = 64
Start col = 7
1. First element [ 0][ 7] = 7
2. Next element [ 0][ 6] = 6
3. Next element [ 1][ 7] = 15
4. Next element [ 2][ 7] = 23
5. Next element [ 1][ 6] = 14
6. Next element [ 0][ 5] = 5
7. Next element [ 0][ 4] = 4
8. Next element [ 1][ 5] = 13
9. Next element [ 2][ 6] = 22
10. Next element [ 3][ 7] = 31
11. Next element [ 4][ 7] = 39
12. Next element [ 3][ 6] = 30
13. Next element [ 2][ 5] = 21
14. Next element [ 1][ 4] = 12
15. Next element [ 0][ 3] = 3
16. Next element [ 0][ 2] = 2
17. Next element [ 1][ 3] = 11
18. Next element [ 2][ 4] = 20
19. Next element [ 3][ 5] = 29
20. Next element [ 4][ 6] = 38
21. Next element [ 5][ 7] = 47
22. Next element [ 6][ 7] = 55
23. Next element [ 5][ 6] = 46
24. Next element [ 4][ 5] = 37
25. Next element [ 3][ 4] = 28
26. Next element [ 2][ 3] = 19
27. Next element [ 1][ 2] = 10
28. Next element [ 0][ 1] = 1
29. Next element [ 0][ 0] = 0
30. Next element [ 1][ 1] = 9
31. Next element [ 2][ 2] = 18
32. Next element [ 3][ 3] = 27
33. Next element [ 4][ 4] = 36
34. Next element [ 5][ 5] = 45
35. Next element [ 6][ 6] = 54
36. Next element [ 7][ 7] = 63
37. Next element [ 7][ 6] = 62
38. Next element [ 6][ 5] = 53
39. Next element [ 5][ 4] = 44
40. Next element [ 4][ 3] = 35
41. Next element [ 3][ 2] = 26
42. Next element [ 2][ 1] = 17
43. Next element [ 1][ 0] = 8
44. Next element [ 2][ 0] = 16
45. Next element [ 3][ 1] = 25
46. Next element [ 4][ 2] = 34
47. Next element [ 5][ 3] = 43
48. Next element [ 6][ 4] = 52
49. Next element [ 7][ 5] = 61
50. Next element [ 7][ 4] = 60
51. Next element [ 6][ 3] = 51
52. Next element [ 5][ 2] = 42
53. Next element [ 4][ 1] = 33
54. Next element [ 3][ 0] = 24
55. Next element [ 4][ 0] = 32
56. Next element [ 5][ 1] = 41
57. Next element [ 6][ 2] = 50
58. Next element [ 7][ 3] = 59
59. Next element [ 7][ 2] = 58
60. Next element [ 6][ 1] = 49
61. Next element [ 5][ 0] = 40
62. Next element [ 6][ 0] = 48
63. Next element [ 7][ 1] = 57
64. Next element [ 7][ 0] = 56
How do you solve any coding problem? One step at a time.
Following the path in your picture, let's list the first several integer array subscripts.
0, 7
0, 6
1, 7
2, 7
1, 6
0, 5
0, 4
1, 5
2, 6
3, 7
You need to list enough subscripts to see the pattern that develops.
One possible solution would be to code the subscripts in a different array. Unfortunately, this solution would lock you into an 8 x 8 matrix.
So, let's write some code to get the first few values of the matrix. It's not going to be pretty code. We're still trying to figure out the pattern.
import java.util.Arrays;
public class ArrayWalk {
public static void main(String args[]) {
int height = 8;
int width = 8;
ArrayWalk aw = new ArrayWalk();
int[][] myArray = aw.createArray(height, width);
int[] values = aw.walkArray(myArray);
System.out.println(Arrays.toString(values));
}
private int[][] createArray(int height, int width) {
int[][] myArray = new int[height][width];
int start = 0;
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
myArray[h][w] = start;
start++;
}
}
return myArray;
}
private int[] walkArray(int[][] myArray) {
int height = myArray.length;
int width = myArray[0].length;
int length = height * width;
int[] values = new int[length];
int index = 0;
int h = 0;
int w = width - 1;
values[index++] = myArray[h][w];
w--;
values[index++] = myArray[h][w];
h++;
w++;
values[index++] = myArray[h][w];
h++;
values[index++] = myArray[h][w];
h--;
w--;
values[index++] = myArray[h][w];
h--;
w--;
values[index++] = myArray[h][w];
w--;
values[index++] = myArray[h][w];
h++;
w++;
values[index++] = myArray[h][w];
h++;
w++;
values[index++] = myArray[h][w];
h++;
w++;
values[index++] = myArray[h][w];
h++;
values[index++] = myArray[h][w];
h--;
w--;
values[index++] = myArray[h][w];
h--;
w--;
values[index++] = myArray[h][w];
h--;
w--;
values[index++] = myArray[h][w];
h--;
w--;
values[index++] = myArray[h][w];
return values;
}
}
As you can see, we've determined that we need to set the width and height of the matrix, and we need to return an integer array to hold the matrix values.
So far, so good.
More importantly, we see a pattern developing. Let's just look at the subscripts.
w--
h++
w++ (once)
h++
h--
w-- (twice)
This pattern repeats, with the exception that the double subscript repeats once, twice, three times, up to seven times (the width - one). Then the double subscript repeats six, five, four, etc. times.
The top row and bottom row always shift to the left. The first column and last column always shift down.
Now, at this point, I'm not sure if what I just said works for a rectangular matrix. I'm pretty sure that it works for a square matrix.
Let's code a helper method with the knowledge we've gained. This pattern is a factory pattern.
private Dimension[] createIncrements() {
Dimension[] increments = new Dimension[4];
increments[0] = new Dimension(-1, 0);
increments[1] = new Dimension(1, 1);
increments[2] = new Dimension(0, 1);
increments[3] = new Dimension(-1, -1);
return increments;
}
A java.awt.Dimension holds a width and a height. So, we define the four increments that we saw in the code pattern. We can then cycle through these increments. The trick will be keeping track of how many times we need to increment using the first and third (zero-based) increment. We'll have to count up from 1 to 7 and back down to 1.
I've been experimenting for several hours now. This is a hard problem to solve. I'll pick up where I left off tomorrow.
I hope the description that I've given you so far is helpful.
Edited to add: I'm not sure I'd have come up with the algorithm in the other answers. All I did ultimately was to write some code to test different array sizes.
Here are the results of one test.
-------------------
| 0 | 1 | 2 |
-------------------
| 3 | 4 | 5 |
-------------------
| 6 | 7 | 8 |
-------------------
[2, 1, 5, 8, 4, 0, 3, 7, 6]
Another test
-------------------------------
| 0 | 1 | 2 | 3 | 4 |
-------------------------------
| 5 | 6 | 7 | 8 | 9 |
-------------------------------
[4, 3, 9, 8, 2, 1, 7, 6, 0, 5]
Finally, the 8 x 8 test from the image.
-------------------------------------------------
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
-------------------------------------------------
| 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
-------------------------------------------------
| 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
-------------------------------------------------
| 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
-------------------------------------------------
| 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
-------------------------------------------------
| 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
-------------------------------------------------
| 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
-------------------------------------------------
| 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
-------------------------------------------------
[7, 6, 15, 23, 14, 5, 4, 13, 22, 31, 39, 30, 21, 12, 3, 2, 11, 20, 29, 38,
47, 55, 46, 37, 28, 19, 10, 1, 0, 9, 18, 27, 36, 45, 54, 63, 62, 53, 44, 35,
26, 17, 8, 16, 25, 34, 43, 52, 61, 60, 51, 42, 33, 24, 32, 41, 50, 59, 58,
49, 40, 48, 57, 56]
And here's the code.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ArrayWalk {
public static void main(String args[]) {
int height = 8;
int width = 8;
ArrayWalk aw = new ArrayWalk();
int[][] myArray = aw.createArray(height, width);
System.out.println(aw.printArray(myArray));
int[] values = aw.walkArray(myArray);
System.out.println(Arrays.toString(values));
}
private int[][] createArray(int height, int width) {
int[][] myArray = new int[height][width];
int start = 0;
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
myArray[h][w] = start;
start++;
}
}
return myArray;
}
private int[] walkArray(int[][] myArray) {
int totalRows = myArray.length;
int totalCols = myArray[0].length;
List<Integer> res = new ArrayList<>(totalRows * totalCols);
List<Integer> diagonal = new ArrayList<>(
Math.max(totalRows, totalCols));
boolean reverseOrder = true;
for (int col = totalCols - 1; col >= 0; col--) {
for (int row = 0; row < totalRows && col + row < totalCols; row++) {
diagonal.add(myArray[row][col + row]);
}
if (reverseOrder) {
Collections.reverse(diagonal);
}
res.addAll(diagonal);
reverseOrder = !reverseOrder;
diagonal.clear();
}
for (int row = 1; row < totalRows; row++) {
for (int col = 0; col < totalCols && col + row < totalRows; col++) {
diagonal.add(myArray[col + row][col]);
}
if (reverseOrder) {
Collections.reverse(diagonal);
}
res.addAll(diagonal);
reverseOrder = !reverseOrder;
diagonal.clear();
}
int[] output = new int[res.size()];
for (int i = 0; i < res.size(); i++) {
output[i] = res.get(i);
}
return output;
}
private String printArray(int[][] myArray) {
String output = "";
for (int h = 0; h < myArray.length; h++) {
output += printDashes(myArray[h].length) + "\n";
output += printLine(myArray[h]) + "\n";
}
output += printDashes(myArray[0].length) + "\n";
return output;
}
private String printDashes(int width) {
int count = width * 6 + 1;
String output = "";
for (int i = 0; i < count; i++) {
output += "-";
}
return output;
}
private String printLine(int[] array) {
String output = "|";
for (int i = 0; i < array.length; i++) {
String value = String.format("%3d", array[i]);
output += " " + value + " |";
}
return output;
}
}

Find The Longest Increasing Sequence in a 2 Dimensional Array [duplicate]

This question already has answers here:
How to determine the longest increasing subsequence using dynamic programming?
(20 answers)
Closed 5 years ago.
I've been working on this problem for awhile and couldn't come up with the solution; I hope you can help out..
I'm trying to find the longest increasing sequence of numbers. For example, if I have the following 4X4 array:
[![enter image description here][1]][1]
int [] nums = {
{97 , 47 , 56 , 36},
{35 , 57 , 41 , 13},
{89 , 36 , 98 , 75},
{25 , 45 , 26 , 17}
};
THE EXPECTED RESULT : return 8 and the LIS 17, 26, 36, 41, 47, 56, 57, 97
I don't have the answer to it yet, I'm trying to reach it.
17 (3,3)
26 (3,2)
36 (2,1)
41 (1,2)
47 (0,1)
56 (0,2)
57 (1,1)
97 (0,0)
I hope my example is clear enough..
This is my code; when I try to find the longest increasing path, it doesn't do it backward not diagonally. Can anyone help me please?
public class Solution2 {
static int[] dx = { 1, -1, 0, 0 };
static int[] dy = { 0, 0, 1, -1 };
public static int longestIncreasingPath(int[][] matrix) {
if (matrix.length == 0)
return 0;
int m = matrix.length, n = matrix[0].length;
int[][] dis = new int[m][n];
int ans = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
ans = Math.max(ans, dfs(i, j, m, n, matrix, dis));
}
}
return ans;
}
static int dfs(int x, int y, int m, int n, int[][] matrix, int[][] dis) {
if (dis[x][y] != 0)
return dis[x][y];
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && ny >= 0 && nx < m && ny < n && matrix[nx][ny] > matrix[x][y]) {
dis[x][y] = Math.max(dis[x][y], dfs(nx, ny, m, n, matrix, dis));
}
}
return ++dis[x][y];
}
public static void main(String[] args) {
int arr[][] = {
{ 97, 47, 56, 36 },
{ 35, 57, 41, 13 },
{ 89, 36, 98, 75 },
{ 25, 45, 26, 17 }
};
System.out.println(longestIncreasingPath(arr));
}
}
I assume we are looking for a strictly increasing sequence (this is not clear from the original problem description).
This problem can then be solved by a dynamic programming approach:
1) sort the cells by their value into decreasing order.
2) in decreasing order assign the length of the longest path starting at this cell:
2a) if you cannot reach any of the previously visited cells assign 1
2b) otherwise assign 1 + max(reachable previous cell)
When this is finished, the overall maximum is the length of the longest path. The path itself can also be found by remembering the max cell in step 2b).
In the example this gives:
0,3 2,1
cell 98 97 89 75 57 56 47 45 41 36 36 35 26 25 17 13
length 1 1 1 2 2 3 4 2 5 6 6 7 7 7 8 7
As far as I understand, you try to implement a depth-first search to find the longest path of increasing order. If so, first of all it is better to mark numbers you visited somehow. A convenient solution is an array. As far as the numbers are marked, you can use it to check whether the particular number has already been counted in an increasing sequence. This is as a little hint for you.
If you are still confused about a depth-first search, I would recommend to read the Depth-First Search Wikipedia page to get a better understanding of what the algorithm is all about.
HTH, Evgeniy

Scanner and while loop addition

I just posted yesterday but I am back with another question, I know the answer to this problem but I'm stuck on how they got it.
import java.util.*;
public class test {
public static void main(String[] args) {
String s = "12 13 14 15 18 16 17 20 2";
Scanner c = new Scanner(s);
int sum = 0;
while(c.nextInt()% 2 == 0)
sum += c.nextInt();
System.out.println(sum);
}
}
The output is 44 but I keep getting 46 on my own. I may be doing it wrong since I am not too familiar on how c.nextInt() works.
I am thinking it goes:
12 % 2 = 0, so add 13
14 % 2 = 0, so add 15
18 % 2 = 0, so add 16
17 % 2 =/= 0, so skip
20 % 2 = 0, so add 2
for a total of = 46
am I missing something?
EDIT: Solved, forgot that loops don't just "skip". I'm dumb
Yes , here answer is 44. Here you are repeating while loop until ( number%2 == 0 ) became FALSE.
in your case :
you are adding 13 + 15 + 16 and the next number to check the while condition is 17
here ( 17%2 == 0 ) is FALSE so condition fails and is not entering into the loop .
here comes the total 44 ( 13 + 15 + 16 )
I hope this will help!
Here is a breakdown going through the loop each time:
c.nextInt() gets 12, 12 % 2 == 0, so this condition is TRUE
sum = 0 and c.nextInt() = 13 so sum += 13 equals 13
Second c.nextInt() gets 14, 14 % 2 == 0, so this condition is TRUE
sum = 13 and c.nextInt() = 15 so sum += 15 equals 28
c.nextInt() gets 18, 18 % 2 == 0, so this condition is TRUE
sum = 0 and c.nextInt() = 16, so sum += 16 equals 44
c.nextInt() gets 17, 17 % 2 == 1, so this condition is FALSE, the loop exits
Print 44
Java while loop is used to execute statement(s) until a condition holds true.If the condition holds false , this while loop will be break out.So
17 % 2 != 0, this while loop will be break out.So sum=44.

java divisor finding takes unlimited time

I've started my friend's school task as practicing, but I stucked at one point. I think my code is right, but definitely not if I see the result.
My problem is the following. The program has to go from 1 to a natural number, and find the least number which has that number of divisors as the current number.
for example: [1;1], [2;2], [3;4], [4;6], [5;16], [6;12]
because the 12 is the least number which has 6 divisor.
Extra requirement is to find all the 100 divisor-number pair in approx. 5 minutes on a standard, not too fast, not too slow PC.
But if I run the code, it stuck at the 23th number, and couldn't go further.
I've tried to shorten the operation number with a condition (if the current number has more divisor than what currently need, it breaks the loop), but it doesn't make any difference, and I don't know why couldn't find the right number and go on.
I would be grateful if Somebody could help me.
Thanks in advance!
public static String message (int numb){
String[] messages = new String[4];
messages[0] = "Working...";
messages[1] = "Done!";
messages[2] = "Please give the interval! [1-100]";
return messages[numb];
}
public static int intervIn (){
Scanner sc = new Scanner(System.in);
int inter = sc.nextInt();
sc.close();
return inter;
}
public static int finding (int need){
int divisor = 1;
int out=1;
if (need!=1){
for (;out<2147483647;){
for (int i = 2;i<=out/2;i++){
if (out%i!=0){
}
else {
divisor++;
if (divisor>=need){
break;
}
}
}
divisor++;
if (divisor==need){
break;
}
else {
divisor=1;
out++;
}
}
}
return out;
}
public static int[][] doit (int row, int column){
int[][] arrayN = new int[row][column];
int divisorNeed = 1;
for (int k = 0;k<row;k++){
arrayN[k][0]=divisorNeed;
arrayN[k][1]=finding(divisorNeed);
divisorNeed++;
}
return arrayN;
}
public static void main(String[] args) {
System.out.println(message(2));
int intervIn = intervIn();
System.out.println(message(0)+'\n');
int[][] arrayNRevis = doit(intervIn,2);
System.out.println(message(1));
for (int i=0;i<intervIn;i++){
System.out.print("[");
for (int j=0;j<2;j++){
System.out.print(arrayNRevis[i][j]+" ");
}
System.out.println("\b]");
}
}
Output now (after almost 8 hours..):
Please give the interval! [1-100] 100 Working...
[1;1] [2;2] [3;4] [4;6] [5;16] [6;12] [7;64] [8;24] [9;36] [10;48]
[11;1024] [12;60] [13;4096] [14;192] [15;144] [16;120] [17;65536]
[18;180] [19;262144] [20;240] [21;576] [22;3072]
Obviously you are not stuck on the 23rd number but it will take approx 120 hours to evaluate it. See http://oeis.org/A005179
Here is a APL NARS2000 workspace that speed up things a lot.
The first 100 take only 1/10 second.
)WSID
C:\Users\Ab\AppData\Roaming\NARS2000\workspaces\combfactor
)FNS
combfactor factors listws save
)VARS
COMBFACTOR DESCRIBE DIV RESULTSfor100
∇ z ← combfactor n;f;p
[1] f ← (⊂,n),factors n ⋄ ⍝ find all factors combinations of n
[2] p ← ⍸0π⍳¯2π32 ⋄ ⍝ The first 32 primes numbers
[3] z ← ((⍴¨f)↑¨⊂⍟p)+.רf-1 ⋄ ⍝ give ratios of all combinations
[4] z ← ∊¯1+((⌊/z)=z)/f ⋄ ⍝ get the combination with minimum ratio
[5] z ← (0x+(⍴z)↑p)×.*z ⋄ ⍝ evaluate p_1^(f_1-1) * p_2^(f_2-1) * ... * p_n^(f_n-1)
∇
∇ z ← {fmax} factors n;f;d
[1] :if 0 = ⎕NC 'fmax' ⋄ fmax ← 2*63 ⋄ :endif
[2] z ← ⍬ ⋄ f ← ⌊fmax⌊n÷2
[3] :while f ≥ 2
[4] :if 0 = f∣n
[5] d ← n÷f ⋄ :if d ∧.≤ f,fmax ⋄ z ,← ⊂f,d ⋄ :endif
[6] z ,← f,¨f factors d
[7] :endif ⋄ f -← 1
[8] :endwhile
∇
COMBFACTOR
RESULTSfor100 ← ⍪(,¨⍳100),¨combfactor¨,¨⍳100 ⋄ ⍝ 0.1 second
DESCRIBE
DESCRIBE
⍝ def factors(number, max_factor=sys.maxint):
⍝ result = []
⍝
⍝ factor = min(number / 2, max_factor)
⍝ while factor >= 2:
⍝ if number % factor == 0:
⍝ divisor = number / factor
⍝
⍝ if divisor <= factor and divisor <= max_factor:
⍝ result.append([factor, divisor])
⍝
⍝ result.extend([factor] + item for item in factors(divisor, factor))
⍝
⍝ factor -= 1
⍝
⍝ return result
⍝
⍝ print factors(12) # -> [[6, 2], [4, 3], [3, 2, 2]]
⍝ print factors(24) # -> [[12, 2], [8, 3], [6, 4], [6, 2, 2], [4, 3, 2], [3, 2, 2, 2]]
⍝ print factors(157) # -> []
DIV
divisors←{z[⍋z←∊∘.×/1,¨(∪π⍵)*¨⍳¨∪⍦π⍵]}
RESULTSfor100
1 1
2 2
3 4
4 6
5 16
6 12
7 64
8 24
9 36
10 48
11 1024
12 60
13 4096
14 192
15 144
16 120
17 65536
18 180
19 262144
20 240
21 576
22 3072
23 4194304
24 360
25 1296
26 12288
27 900
28 960
29 268435456
30 720
31 1073741824
32 840
33 9216
34 196608
35 5184
36 1260
37 68719476736
38 786432
39 36864
40 1680
41 1099511627776
42 2880
43 4398046511104
44 15360
45 3600
46 12582912
47 70368744177664
48 2520
49 46656
50 6480
51 589824
52 61440
53 4503599627370496
54 6300
55 82944
56 6720
57 2359296
58 805306368
59 288230376151711744
60 5040
61 1152921504606846976
62 3221225472
63 14400
64 7560
65 331776
66 46080
67 73786976294838206464
68 983040
69 37748736
70 25920
71 1180591620717411303424
72 10080
73 4722366482869645213696
74 206158430208
75 32400
76 3932160
77 746496
78 184320
79 302231454903657293676544
80 15120
81 44100
82 3298534883328
83 4835703278458516698824704
84 20160
85 5308416
86 13194139533312
87 2415919104
88 107520
89 309485009821345068724781056
90 25200
91 2985984
92 62914560
93 9663676416
94 211106232532992
95 21233664
96 27720
97 79228162514264337593543950336
98 233280
99 230400
100 45360
And here is a C program that take 62 microsecond !
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define MaxInt 0x7fffffffffffffff
#define ll long long
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131};
ll minimums[16]; // contains minimum for each level
ll ipow(ll base, int exp) {
ll result = 1;
while (exp) {
if (exp & 1) result *= base;
exp >>= 1; base *= base;
} return result;
}
ll factors(ll number, ll max_factor, int level) {
ll result = MaxInt;
ll factor = min(number / 2, max_factor);
while (factor >= 2) {
if (number % factor == 0) {
ll divisor = number / factor;
ll tempf = ipow(primes[level], factor-1);
if (divisor <= factor && divisor <= max_factor) {
ll tempd = ipow(primes[level+1], divisor-1);
minimums[level] = min(minimums[level], tempf * tempd);
}
ll fct = factors(divisor, factor, level+1);
if (fct < MaxInt)
minimums[level] = min(minimums[level], tempf * fct);
result = minimums[level];
minimums[level+1] = MaxInt;
}
factor -= 1;
}
return result;
}
ll fact(int number) {
for (int level = 0; level < 16; level++) minimums[level] = MaxInt;
ll res = factors(number, MaxInt, 0);
if (res < MaxInt) return res;
else return 0;
}
int main(int argc, char *argv[]) {
int N = 100;
if (argc > 1) N = atoi(argv[1]);
ll res[N];
clock_t Start = clock();
for(int n = 1; n <= 10000; n++)
for (int i = 1; i <= N; i++) res[i] = fact(i);
printf("\n%0.6f second(s)\n", (clock() - Start)/1000.0/10000.0);
for (int i = 1; i <= N; i++)
if (res[i] > 0) printf("%d %lld\n", i, res[i]);
else if (i > 64 ) printf("%d 2 power %d\n", i, i-1);
else printf("%d %lld\n", i, ipow(2, i-1));
return 0;
}
Every natural number N can be expressed as multiplication of prime numbers p_i raised to some powers k_i where k_i >= 0. So let's say you have number n equal to:
n = p_1^k_1 * p_2^k_2 * ... * p_z^k_z
this number will have (k_1+1)*(k_2+1)*...*(k_z+1) dividers, e.g.
18 = 2^1 * 3^2
and have (1+1)*(2+1) dividers or 6 dividers: 1, 2, 3, 6, 9, 18.
Prime numbers may be precomputed using sieve algorithm (https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)
Then you may use dynamic programming to compute number of dividers of given number n. If n = n_1 * p_i^k_i (n can be divided by p_i^k_i), then number of dividers of n is number of dividers of n_1 * (k_i+1).
This should speed up computation of dividers counts.

Random Number Generator of Even and Odd Numbers

I need to create an application that generates 25 random integers between 0 and 99 and then outputs those integers on two separate lines one for odd numbers and one for even numbers. I will need to use one array for even numbers and one for odd numbers. This is what I have so far:
public static void main(String[] args) {
//Odd Numbers
int[] oddNums = new int[25];
for (int index = 0; index < oddNums.length; index++) {
oddNums[index] = (int) (Math.random()*99);
}
System.out.print("ODD: ");
for (int index = 0; index < oddNums.length; index++) {
System.out.print(oddNums[index] + " ");
}
//Even Numbers
int[] evenNums = new int[25];
for (int index = 0; index < evenNums.length; index++) {
evenNums[index] = (int) (Math.random()*99);
}
System.out.print("\nEVEN: ");
for (int index = 0; index < evenNums.length; index++) {
System.out.print(evenNums[index] + " ");
}
}
I have set up the program to print out 25 random integers, but I do not know how I am going to get the program to print out only even numbers on one line and odd numbers on another (I am new to java).
Here is a sample output I am getting:
ODD: 28 36 54 98 35 1 59 43 96 69 41 66 37 15 30 17 29 67 56 83 71 4
24 70 38
EVEN: 34 45 36 26 73 84 60 39 21 49 28 98 69 14 32 24 72 29 26 88 77 2
23 58 47
This is wrong since there are both even and odd numbers on both lines.
This is what the output should look like:
ODD: 25 97 23 45 63 91 13 47 93 51 29
EVEN: 22 94 46 74 18 48 32 84 28 92 56
There are only odd numbers on one line and even numbers on another line.
Does anyone know what I need to add here?
A little modification to your program will yield the desired result.
public static void main(String[] args) {
//Odd Numbers
int[] randomNumbers = new int[25];
int[] evenNumbers = new int[25];
int[] oddNumbers = new int[25];
int k = 0, l = 0;
for (int index = 0; index < randomNumbers.length; index++) {
randomNumbers[index] = (int) (Math.random() * 99);
}
for (int i = 0; i < 25; i++) {
if (randomNumbers[i] % 2 == 0) {
evenNumbers[k] = randomNumbers[i];
k++;
} else {
oddNumbers[l] = randomNumbers[i];
l++;
}
}
}
You can generate an even number uniformly at random in [0,100] with the formula n = 2*x where x is uniformly random in [0, 49].
You can similarly generate an uniformly random odd number with n = 2*x+1 where x is uniformly random in [0,49].
You can just generate the 25 number. After generating those ints, you can locate them in the array they belong.
int num;
int oddIndex = -1;
int evenIndex = -1;
for (index = 0; index < 25 ; index++){
num = (int) (Math.random()*99);
if (num % 2 == 1){
oddIndex++;
oddNum[oddIndex] = num;
}
else{
evenIndex++;
evenNum[evenIndex] = num;
}
}
In this case, you're not sure about the sizes of each array. So, I advise you to use ArrayList instead of array. If you use an ArrayList, you won't need to deal with oddIndex and evenIndex.
Firstly,The random function you have written will be generating random numbers between 0 and 99. It will not be considering whether the numbers are odd or even.
If there is no restriction on the number of odd numbers and number of even numbers, just use the random generator once and depending on whether it is odd or even place it in the correct array.
For doing so, use the MOD operator i.e. check for remainder after dividing by 2 to see odd or even
At some point in your code, you need to have something like,
Pseudocode:
if (nextNumber is odd) then
put nextNumber at end of ODD array
else
put nextNumber at end of EVEN array
endif
You should also have a look at util.Random.nextInt() which is preferable for generating random integers.
Here's a solution that uses Java 8 streams:
public class NumberGenerator {
public static void main(String[] args) {
Random random = new Random();
int[] ints = random.ints(25, 0, 99).sorted().toArray();
int[] even = IntStream.of(ints).filter(x -> x % 2 == 0).toArray();
int[] odd = IntStream.of(ints).filter(x -> x % 2 == 1).toArray();
System.out.println(Arrays.toString(even));
System.out.println(Arrays.toString(odd));
}
}
First an array of all random integers are being created. 25 random integers are created and they should all be between 0 and 99.
The evens and odds are filtered out into two separate arrays.
[0, 4, 6, 16, 18, 22, 40, 42, 58, 64, 82, 84, 98]
[7, 27, 29, 31, 35, 55, 73, 75, 75, 79, 83, 91]

Categories