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;
}
}
Related
My task is to create a multidimensional array that is seperated in n pieces from a range of min to max.
So if the range is 0 til 90 and it is devided in 6 pieces it should look like this
int[][] array = { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},
{15, 16, 17, 18, . . ., 29},
{. . .},
{. . .},
{. . .},
{. . ., 90}
}
public class H {
public static void main(String[] args) {
int min = 0;
int max = 90;
int n = 6;
// 90 / 6 = 15
int elementsInBin = (max - min) / n; //15
int[][] bin = new int[n][elementsInBin];
//n = 6
for(int i = 0; i < n; i++){
int leftBound = elementsInBin * i;
int rightBound = (elementsInBin * i) + (elementsInBin-1);
int span = rightBound - leftBound;
for(int j = leftBound; j < span; j++){
System.out.print(bin[i][j]);
}
}
}
so the first loop is n long because these are the rows and im defining the left and right border of the interval of the row.
the next for loop starts with the left bound 0 and with the right bound 14 and it counts up the span.
then in the new next loop the left border is at 15 and the right border is at 15 + 15 -1 so 29 and the next for-loop should count from the new left border (15) to 29.
but my output is always
00000000000000
im not getting what im doing wrong.
I'm having trouble with an assignment where we are required to print out this array:
1 10 11 20 21
2 9 12 19 22
3 8 13 18 23
4 7 14 17 24
5 6 15 16 25
My code is somewhat correct but it is not printing 10 and 19 where it should be.
My output:
Choose a number for the rows from 0 to 16.
5
Choose a number for the columns from 0 to 16
5
1 0 10 0 19
2 9 11 18 20
3 8 12 17 21
4 7 13 16 22
5 6 14 15 23
My code:
//snake move with the number
import java.util.Scanner;
public class SnakeMove {
public static void main(String[] args) {
//create Scanner object
Scanner inScan = new Scanner(System.in);
//prompt the user to choose number for the Row from 0 to 16
System.out.println("Choose a number for the rows from 0 to 16.");
//take the input from user with nextInt() method
//use the variable int row
int row = inScan.nextInt();
//prompt the user to choose number for the Col from 0 to 16
System.out.println("Choose a number for the columns from 0 to 16");
//take the input from user with nextInt()
//use the variable int col
int col = inScan.nextInt();
if (row != col) {
System.out.println("Run the program again and choose the same number for Row and Col");
System.exit(0);
}
int[][] arr = move(row, col);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}//main method
static int[][] move(int row, int col) {
boolean flag = true;
int count = 1;
int[][] array = new int[row][col];
for (int j = 0; j < array[0].length; j++) {
if (flag) {
for (int i = 0; i < array.length; i++) {
//assign the increment value of count
// to specific array cells
array[i][j] = count;
count++;
}
flag = false;
} else {
//row decrement going up
for (int i = array.length - 1; i > 0; i--) {
//assign the increment value of count
// to specific array cells
array[i][j] = count;
count++;
}
flag = true;
}
}//column increment
return array;
}//move method
}//end SnakeMove class
Can anyone detect what is causing the error? Any help would be appreciated.
I believe this is a good alternative and easy to understand. Do comment if you have a simplified version of the same.
Code:
import java.util.Arrays;
import java.util.Scanner;
public class SnakePatternProblem {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // *INPUT*
int row = scanner.nextInt();
int col = scanner.nextInt();
int[][] array = new int[row][col];
// Initializing first row of the array with a generalized expression
for (int i = 0; i < col; i++) {
if (i % 2 != 0) array[0][i] = col * (i+1);
else array[0][i] = (col * i) + 1;
}
array[0][0] = 1; // this element is not covered in the above loop.
// Nested loop for incrementing and decrementing as per the first row of elements.
for (int i= 1; i< row; i++){
for (int j=0; j< col; j++){
if(j%2==0) array[i][j] = array[i-1][j] + 1;
else array[i][j] = array[i-1][j] - 1;
}
}
System.out.println(Arrays.deepToString(array)); // *OUTPUT
}
}
Explanation:
Consider first row of 5 x 5 matrix named "arr" with snake pattern:
1 10 11 20 21
The element in the odd column is equivalent to ((currentColumn + 1) * Total_No_Of_columns);
Example: arr[0][1] = (1 + 1)* 5 = 10
The element in the even column is equivalent to (currentColumn * Total_No_Of_columns) + 1;
Example: arra[0][2] = (2 * 5) + 1 = 11;
Important Note: element at first row, first column is Zero
arr[0][0] = 1 -> must be declared
Now, the remaining matrix is incrementing or decrementing loop from the first element in that column.
Elements with even column number gets incremented by 1 in each row from the first element of that column.
1 -> First element of column-0
2 -> (1 + 1)
3 -> (2 + 1).... so on
4
5
Elements with odd column number gets decremented by 1 in each row from the first element of that column.
10 -> First element of column - 1
9 -> (10 - 1)
8 -> (9 - 1).... so on
7
6
This will generate the "snaking" pattern you described.
It could be simplified with ternary but this makes it more readable I think
It would be interesting to find a more clever way about it though, if anyone finds a better way pls comment
public static int[][] genArray(int length) {
int[][] arr = new int[length][length];
int counter = 0;
for (int col = 0; col < arr.length; col++) {
if (col % 2 == 0) {
for (int row = 0; row < arr.length; row++) {
arr[row][col] = counter++;
}
} else {
for (int row = arr.length - 1; row >= 0; row--) {
System.out.println("row: " + row + ", col: " + col);
arr[row][col] = counter++;
}
}
}
}
return arr;
}
You can create such an array as follows:
int m = 5;
int n = 4;
int[][] snakeArr = IntStream.range(0, n)
.mapToObj(i -> IntStream.range(0, m)
// even row - straight order,
// odd row - reverse order
.map(j -> (i % 2 == 0 ? j : m - j - 1) + i * m + 1)
.toArray())
.toArray(int[][]::new);
// output
Arrays.stream(snakeArr)
.map(row -> Arrays.stream(row)
.mapToObj(e -> String.format("%2d", e))
.collect(Collectors.joining(" ")))
.forEach(System.out::println);
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
Transposing snake array:
int[][] transposedSA = new int[m][n];
IntStream.range(0, m).forEach(i ->
IntStream.range(0, n).forEach(j ->
transposedSA[i][j] = snakeArr[j][i]));
// output
Arrays.stream(transposedSA)
.map(row -> Arrays.stream(row)
.mapToObj(e -> String.format("%2d", e))
.collect(Collectors.joining(" ")))
.forEach(System.out::println);
1 10 11 20
2 9 12 19
3 8 13 18
4 7 14 17
5 6 15 16
An easy way to do it is to create a 2-D array as shown below and then print its transpose.
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
21 22 23 24 25
It is a 2-D array of the dimension, LEN x LEN, where LEN = 5.
The above pattern goes like this:
The pattern starts with a start value of 1.
When the main loop counter is an even number, the counter, which assigns a value to the array, starts with start value and increases by one, LEN times. Finally, it sets start for the next row to start with final_value_of_the_array_value_assignment_counter - 1 + LEN.
When the main loop counter is an odd number, the counter, which assigns a value to the array, starts with start value and decreases by one LEN times. Finally, it sets start for the next row to start with start + 1.
The transpose of the above matrix will look like:
1 10 11 20 21
2 9 12 19 22
3 8 13 18 23
4 7 14 17 24
5 6 15 16 25
In terms of code, we can write it as:
public class Main {
public static void main(String[] args) {
final int LEN = 5;
int[][] arr = new int[LEN][LEN];
int start = 1, j, k, col;
for (int i = 0; i < LEN; i++) {
if (i % 2 == 0) {
k = 1;
for (j = start, col = 0; k <= LEN; j++, k++, col++) {
arr[i][col] = j;
}
start = j - 1 + LEN;
} else {
k = 1;
for (j = start, col = 0; k <= LEN; j--, k++, col++) {
arr[i][col] = j;
}
start++;
}
}
// Print the transpose of the matrix
for (int r = 0; r < LEN; r++) {
for (int c = 0; c < LEN; c++) {
System.out.print(arr[c][r] + "\t");
}
System.out.println();
}
}
}
Output:
1 10 11 20 21
2 9 12 19 22
3 8 13 18 23
4 7 14 17 24
5 6 15 16 25
Change the value of LEN to 10 and you will get the following pattern:
1 20 21 40 41 60 61 80 81 100
2 19 22 39 42 59 62 79 82 99
3 18 23 38 43 58 63 78 83 98
4 17 24 37 44 57 64 77 84 97
5 16 25 36 45 56 65 76 85 96
6 15 26 35 46 55 66 75 86 95
7 14 27 34 47 54 67 74 87 94
8 13 28 33 48 53 68 73 88 93
9 12 29 32 49 52 69 72 89 92
10 11 30 31 50 51 70 71 90 91
I have to code function that create two-dimensional array of Integer numbers with random size from [50, 100] and divisible by 4. Number of rows is equal to number of columns. Next, an array is fulfill with random numbers (except elements that are on diagonal) from range [a, b), where a and b are enter by user.
Values on diagonal have got fulfill in random arrangement in 75% by number 1, and the rest of 25% with number -1.
Functions, should print-out to console amount of cells which value is less than product of index from row and column these cell.
I have no idea how to deal with these diagonals and amount of cells...
So far I come off with something like this:
public static void createArray()
{
Random generator = new Random();
Scanner in = new Scanner(System.in);
int drawed = 1, rows, cols;
while (drawed %4 != 0)
{
drawed = 50 + generator.nextInt(51);
}
rows = drawed;
cols = rows;
int[][] array = new int[rows][cols];
System.out.println("Input a: ");
int a = in.nextInt();
System.out.println("Input b: ");
int b = in.nextInt();
for (int i = 0; i < array.length; i++)
for (int j = 0; j < array[i].length; j++)
{
if (i != j)
array[i][j] = a + generator.nextInt(b - a);
}
}
How to fulfill diagonal in 75% with number 1, and the rest (25%) with number -1?
How count cells which value is less than product from index of rows and columns?
Hi I could not understood your last point of displaying the output to console. However the following program will solve the problem you are facing for diagonal values.
public class Application {
public static void main(String[] args) {
doJob(12, 20, 200);
}
private static void doJob(int size, int a, int b) {
if (size % 4 == 0) {
int[][] array = new int[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i != j && (i + j) != (size - 1))
array[i][j] = generateRandomNumber(a, b);
}
}
int positiveOneSize = calculateLocationRequiredForOne(size * 2);
int negetiveOneSize = (size - 1) - positiveOneSize;
/* Fill the diagonals with random values for positive one */
while (positiveOneSize > 0 || negetiveOneSize > 0) {
int location = generateRandomNumber(0, size - 1); // Random loc
int posOrNeg = generateRandomNumber(0, 2);
if (posOrNeg == 0) {
array[location][location] = 1;
array[location][(size - 1) - location] = 1;
} else {
array[location][location] = -1;
array[location][(size - 1) - location] = -1;
}
positiveOneSize--;
negetiveOneSize--;
}
/* Print array */
for (int m = 0; m < size; m++) {
for (int n = 0; n < size; n++) {
System.out.print(" " + array[m][n]);
}
System.out.println();
}
}
else {
System.out.println("Error");
}
}
private static int generateRandomNumber(int a, int b) {
return a + (int) (Math.random() * ((b - a) + 1));
}
private static int calculateLocationRequiredForOne(int size) {
return (int) (0.75 * size);
}
}
I have no idea how to deal with these diagonals
First, let's try to draw a diagonal of any char, as in this answer
Basically you have to know when the indexes belong to the diagonal or not, this can be done with some logic, let's use a N x N board where N = 8:
[0][0] [0][1] [0][2] [0][3] [0][4] [0][5] [0][6] [0][7]
[1][0] [1][1] [1][2] [1][3] [1][4] [1][5] [1][6] [1][7]
[2][0] [2][1] [2][2] [2][3] [2][4] [2][5] [2][6] [2][7]
[3][0] [3][1] [3][2] [3][3] [3][4] [3][5] [3][6] [3][7]
[4][0] [4][1] [4][2] [4][3] [4][4] [4][5] [4][6] [4][7]
[5][0] [5][1] [5][2] [5][3] [5][4] [5][5] [5][6] [5][7]
[6][0] [6][1] [6][2] [6][3] [6][4] [6][5] [6][6] [6][7]
[7][0] [7][1] [7][2] [7][3] [7][4] [7][5] [7][6] [7][7]
There is a pattern there for the diagonals: can you see it?
\: Row and column are the same number
/ Row = number - column - 1
How to fulfill diagonal in 75% with number 1, and the rest (25%) with number -1?
You need to know how many numbers you're gonna use, but... you already know that! Remember N? Well we're going to use a formula to know what is 75% of N:
75% of N = N * 75 / 100
25% of N = N * 25 / 100
In our case using N = 8 that becomes:
8 * 75 = 600 / 100 = 6
8 * 25 = 200 / 100 = 2
Then create your own function which returns either 1 or -1 based on how many positive or negative numbers you've added already as in the code below
How count cells which value is less than product from index of rows and columns?
That, in code means that you need to know how many values are less than i * j
if (array[i][j] < i * j) {
count++;
}
Joining everything (without using a Scanner as I'm lazy for that):
import java.util.Random;
public class SquareDiagonalNumbers {
private static int positive = 0;
private static int negative = 0;
private static int n = 8;
private static int positiveOnes = n * 75 / 100; //75%
private static int negativeOnes = n * 25 / 100; //25%
private static int a = 10;
private static int b = 20;
public static void main(String[] args) {
int[][] array = new int[n][n];
int products = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
array[i][j] = i == j || i == (n - j - 1) ? randomOnes() : randomNumber();
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.print(array[i][j] + " ");
}
System.out.println();
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (array[i][j] < i * j) {
products++;
System.out.println("At [" + i + ", " + j + "] number " + array[i][j] + " is lower than [i * j]: " + (i * j));
}
}
}
System.out.println("Total of numbers lower than the product of their row and column: " + products);
}
private static int randomNumber() {
Random r = new Random();
return r.nextInt(b - a) + a;
}
private static int randomOnes() {
Random r = new Random();
boolean isPositive = r.nextBoolean();
if (isPositive) {
if (positive < positiveOnes) {
positive++;
return 1;
} else {
negative++;
return -1;
}
} else {
if (negative < negativeOnes) {
negative++;
return -1;
} else {
positive++;
return 1;
}
}
}
}
Produces a similar output to this:
-1 17 14 19 14 19 14 -1
11 1 11 18 18 14 1 14
11 14 1 14 12 1 17 13
16 10 12 1 1 12 10 11
11 11 14 -1 1 19 14 19
15 12 -1 19 14 1 13 15
13 -1 17 10 12 12 1 10
1 19 15 18 12 11 13 1
At [0, 0] number -1 is lower than [i * j]: 0
At [0, 7] number -1 is lower than [i * j]: 0
At [1, 6] number 1 is lower than [i * j]: 6
At [2, 2] number 1 is lower than [i * j]: 4
At [2, 5] number 1 is lower than [i * j]: 10
At [2, 7] number 13 is lower than [i * j]: 14
At [3, 3] number 1 is lower than [i * j]: 9
At [3, 4] number 1 is lower than [i * j]: 12
At [3, 5] number 12 is lower than [i * j]: 15
At [3, 6] number 10 is lower than [i * j]: 18
At [3, 7] number 11 is lower than [i * j]: 21
At [4, 3] number -1 is lower than [i * j]: 12
At [4, 4] number 1 is lower than [i * j]: 16
At [4, 5] number 19 is lower than [i * j]: 20
At [4, 6] number 14 is lower than [i * j]: 24
At [4, 7] number 19 is lower than [i * j]: 28
At [5, 2] number -1 is lower than [i * j]: 10
At [5, 4] number 14 is lower than [i * j]: 20
At [5, 5] number 1 is lower than [i * j]: 25
At [5, 6] number 13 is lower than [i * j]: 30
At [5, 7] number 15 is lower than [i * j]: 35
At [6, 1] number -1 is lower than [i * j]: 6
At [6, 3] number 10 is lower than [i * j]: 18
At [6, 4] number 12 is lower than [i * j]: 24
At [6, 5] number 12 is lower than [i * j]: 30
At [6, 6] number 1 is lower than [i * j]: 36
At [6, 7] number 10 is lower than [i * j]: 42
At [7, 3] number 18 is lower than [i * j]: 21
At [7, 4] number 12 is lower than [i * j]: 28
At [7, 5] number 11 is lower than [i * j]: 35
At [7, 6] number 13 is lower than [i * j]: 42
At [7, 7] number 1 is lower than [i * j]: 49
Total of numbers lower than the product of their row and column: 32
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.
im trying to create a matrix from a file, the file is like this:
Where my first line has the size of the matrix= 10 x 9
And in the other lines, we have 15 values distributed aleatory.
3 5
4 5 6
12 34 12 12 8
34 23
12 34 34 10 89
With the info size i will define my matriz. I use this method for read:
public static void read(){
String line= "";
int i = 0;
try {
while((line = bf.readLine()) != null){
if (i == 0){
//Call method that get the size and create my global matriz
}else{
String[] list = line.split(" ");
//I need help here, for insert correctly in the array
}
i++;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
How i can do for insert orderly in the matrix? My matrix should be like:
4 5 6 12 34
12 12 8 34 23
12 34 34 10 89
Any idea?
This is one way to do it:
String input = "3 5\n" +
"4 5 6\n" +
"12 34 12 12 8\n" +
"34 23\n" +
"12 34 34 10 89\n";
Scanner in = new Scanner(input);
final int rows = in.nextInt();
final int cols = in.nextInt();
int[][] matrix = new int[rows][cols];
int row = 0, col = 0;
for (int i = 0; i < rows * cols; i++) {
matrix[row][col] = in.nextInt();
if (++col == cols) {
row++;
col = 0;
}
}
System.out.println(Arrays.deepToString(matrix));
Output:
[[4, 5, 6, 12, 34], [12, 12, 8, 34, 23], [12, 34, 34, 10, 89]]
It is not necessarily the best way to do it, but I wanted to show the manual increment logic of col and row, where row is incremented when col rolls over.
Using answer by sebenalern, it'd work like this:
int[][] matrix = new int[rows][cols];
for (int row = 0; row < rows; row++)
for (int col = 0; col < cols; col++)
matrix[row][col] = in.nextInt();
Using answer by Paul, it'd work like this:
int[][] matrix = new int[rows][cols];
for (int i = 0; i < rows * cols; i++)
matrix[i / 5][i % 5] = in.nextInt();
All 3 versions rely on the Scanner to simply provide all the values in a sequence, regardless of how they were put together on lines.
If you don't want to use Scanner (e.g. because it is slow), and read the input line-by-line, then values on a line, the 1st version would be easier to use. Otherwise the 3rd is the shortest, and the 2nd version is the most straightforward.
Just a hint - I'll leave your homework to you - :
In this case it would be pretty simple to maintain a counter of all values that have been read so far, and map each of these counter-values to a matrix-value like this:
0 = (0 , 0)
1 = (1 , 0)
...
5 = (0 , 1)
6 = (1 , 1)
...
Using something like this:
int row = counter / rowLength;
int col = counter % rowLength;
In your case:
matrix[counter/5][counter%5] = someValue;