How to count length of each square (smaller matrix) in matrix - java

I'm solving an algorithmic task with matrices involved.
I need to count each inner square (smaller matrix) inside a larger one.
Is there any dependencies between original length and each next?
As an example I have this matrix:
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
As you may see Rows = 6, Cols = 6, Length = Rows * Cols;
Problem statement: How to calculate the length of inner matrices:
8 9 10 11
14 15 16 17
20 21 22 23
26 27 28 29
And the last one
15 16
21 22
What I could do:
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
//mirrored row and col e.g. 0 1 2 3 2 1 0
int rowMir = i >= (int)Math.round(M/2.0d) ? (M - 1 - i) : i;
int colMir = j >= (int)Math.round(N/2.0d) ? (N - 1 - j) : j;
int depth = row > col ? col : row; //depth of inner square for each element in iteration. square's border in other words.
//In current matrix there are 3 inner squares (0, 1, 2)
}
}
Is it useful at all? I've tried to calculate it basing on values I've got, but no success until now. Googling gave me nothing in this case.
EDIT
The solution I'm looking for is to get size of the matrix for each element dynamically. Example for value at [i][j] I've counted the depth, the inner matrix it belongs to.

You can simply decrease by a step of 2 at each iteration:
int minDim = Math.min(rows, columns);
for(int i = minDim ; i >= 0 ; i -= 2) {
System.out.println("Inner length: " + ((rows - i) * (columns - i)))
}

In case you actually want to print all the inner matrices and get the count then you can do something like this:
public static void main (String[] args)
{
/* Define Matrix */
int matrixSize = 6;
int[][] matrix = new int[][]{{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}};
/* Initialize Count Counter */
int count = 0;
/* Count/Print Inner Matrices */
for(int x = 2; x < matrixSize; x++) {
for(int i = 0; i <= matrixSize - x; i++) {
for(int j = 0; j <= matrixSize - x; j++) {
/* Call Print Matrix Function */
printMatrix(matrix, i, j, x);
++count; /* Increment Counter */
}
}
}
/* Print Actual Count */
System.out.println("\nTotal Inner Square Matrices Count: " + count);
}
/**
* Print Matrix
* Arguments: Matrix, Row Index, Column Index, Matrix Size
**/
public static void printMatrix(int[][] matrix, int i, int j, int size) {
System.out.println();
/* Row Iterator */
for(int iIndex = i; iIndex < i + size; iIndex++) {
System.out.println();
/* Column Iterator */
for(int jIndex = j; jIndex < j + size; jIndex++) {
System.out.print(" " + matrix[iIndex][jIndex]);
}
}
}
Output:
1 2
7 8
2 3
8 9
...
Total Inner Matrices: 54

Related

How do I create a 2x2 subarray of a 5x5 2d array, rotate it, then add it back to the original array?

I'm trying to create a game like "fifteen" but instead of sliding tiles into one empty space, the empty space is removed and you have to choose individual 2x2 grids to rotate in order to get all the numbers in the correct order.
I'm stuck as to how to create a subarray from the original and have it so that the rotation of the subarray is applied to the original array.
For example:
01 02 03 04 05
06 07 09 14 10
11 12 08 13 15
16 17 18 19 20
21 22 23 24 25
in order to solve the game, you would need to choose the number 9 and and rotate {09, 14} {08, 13}
clockwise.
I'm relatively new to programming and java so any help would be greatly appreciated!
Assuming you have a two dimensional array (an array of columns) then your first index is the x coordinate and the second index the y coordinate in your grid. The x and y parameter present the position where the user has clicked on. However, this method will throw an exception if you choose a position at the border.
private static int[][] rotate2x2SubArray(int[][] grid, final int x, final int y) {
final int topLeft = grid[x][y];
final int topRight = grid[x + 1][y];
final int bottomRight = grid[x + 1][y + 1];
final int bottomLeft = grid[x][y + 1];
//topRight's new value is topLeft's old value
grid[x + 1][y] = topLeft;
//bottomRight's new value is topRight's old value
grid[x + 1][y + 1] = topRight;
//bottomLeft's new value is bottomRight's old value
grid[x][y + 1] = bottomRight;
//topLeft's new value is bottomLeft's old value
grid[x][y] = bottomLeft;
return grid;
}
This is just my approach. There a probably a hundred ways which might be faster/slower or more flexible(rotate a variable size).
Here's a proof of concept. This is the original 5 x 5 array.
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
This is the array after the 8 has been rotated counter-clockwise.
1 2 3 4 5
6 7 9 14 10
11 12 8 13 15
16 17 18 19 20
21 22 23 24 25
This is the array after the 16 has been rotated clockwise.
1 2 3 4 5
6 7 9 14 10
11 12 8 13 15
21 16 18 19 20
22 17 23 24 25
Here's the runnable code. I didn't check for the row or column being less than the last row or column. All I did was create the method to rotate the 2 x 2 subarray.
public class RotateSubArray {
public static void main(String[] args) {
RotateSubArray rotate = new RotateSubArray();
int[][] array = rotate.createArray();
System.out.println(rotate.printArray(array));
array = rotate.rotateSubArray(array, 1, 2, false);
System.out.println(rotate.printArray(array));
array = rotate.rotateSubArray(array, 3, 0, true);
System.out.println(rotate.printArray(array));
}
public int[][] createArray() {
int[][] output = new int[5][5];
int count = 1;
for (int i = 0; i < output.length; i++) {
for (int j = 0; j < output[i].length; j++) {
output[i][j] = count++;
}
}
return output;
}
public String printArray(int[][] output) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < output.length; i++) {
for (int j = 0; j < output[i].length; j++) {
builder.append(String.format("%3d", output[i][j]));
}
builder.append(System.lineSeparator());
}
return builder.toString();
}
public int[][] rotateSubArray(int[][] array, int row, int column,
boolean clockwise) {
int temp = array[row][column];
int nextRow = row + 1;
int nextColumn = column + 1;
if (clockwise) {
array[row][column] = array[nextRow][column];
array[nextRow][column] = array[nextRow][nextColumn];
array[nextRow][nextColumn] = array[row][nextColumn];
array[row][nextColumn] = temp;
} else {
array[row][column] = array[row][nextColumn];
array[row][nextColumn] = array[nextRow][nextColumn];
array[nextRow][nextColumn] = array[nextRow][column];
array[nextRow][column] = temp;
}
return array;
}
}

programming puzzle : how to count number of bacteria that are alive?

Recently, I had encountered an interesting programming puzzle which had some good twist and turn mentioned in the puzzle. Below the question which amazed me, I simply eager to know if any relevant solution probably in java is feasible for below scenario.
Problem statement:
There is a grid of dimension m*n, initially, a bacterium is present at the bottom left cell(m-1,0) of the grid with all the other cells empty. After every second, each bacteria in the grid divides itself and increases the bacteria count int the adjacent(horizontal,vertical and diagonal) cells by 1 and dies.
How many bacteria are present at the bottom right cell(m-1,n-1) after n-1 seconds?
I had taken references from
https://www.codechef.com/problems/BGH17
but failed to submit the solution
Below is the image for more insite of problem
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
public class BacteriaProblem {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Number of Rows: ");
int m = sc.nextInt();
System.out.println("Number of Columns: ");
int n = sc.nextInt();
int[][] input = new int[m][n];
input[m - 1][0] = 1;
Stack<String> stack = new Stack<>();
stack.push(m - 1 + "~" + 0);
reproduce(stack, input, n - 1);
System.out.println("Value at Bottom Right corner after n-1 secs: " + input[m - 1][n - 1]);
}
private static void reproduce(Stack<String> stack, int[][] input, int times) {
//exit condition
if (times < 1) {
return;
}
//bacteria after splitting
List<String> children = new ArrayList<>();
//reproduce all existing bacteria
while (!stack.isEmpty()) {
String[] coordinates = stack.pop().split("~");
int x = Integer.parseInt(coordinates[0]);
int y = Integer.parseInt(coordinates[1]);
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) continue;
split(input, x + i, y + j, children);
}
}
input[x][y]--;
}
//add all children to stack
for (String coord : children) {
stack.push(coord);
}
//reduce times by 1
reproduce(stack, input, times - 1);
}
private static void split(int[][] input, int x, int y, List<String> children) {
int m = input.length;
int n = input[0].length;
if (x >= 0 && x < m && y >= 0 && y < n) {
input[x][y]++;
children.add(x + "~" + y);
}
}
}
Well, I was asked this question in an Online Hackerrank test and couldn't solve it at that time.
I did later try to code it and here's the soln in C++,
long countBacteriasAtBottomRight(int m, int n){
long grid[m][n];
// Set all to 0, and only bottom left to 1
for (int i=0; i<m; i++){
for (int j=0; j<n; j++){
grid[i][j] = 0;
}
}
grid[m-1][0] = 1;
// Start the cycle, do it for (n-1) times
int time = n-1;
vector<long> toBeUpdated;
while (time--){
cout << "\n\nTime: " << time;
for (int i=0; i<m; i++){
for (int j=0; j<n; j++){
while (grid[i][j] > 0){
grid[i][j]--;
// upper left
if (i > 0 && j > 0){
toBeUpdated.push_back(i-1);
toBeUpdated.push_back(j-1);
}
// upper
if (i > 0){
toBeUpdated.push_back(i-1);
toBeUpdated.push_back(j);
}
// upper right
if (i > 0 && j < n-1){
toBeUpdated.push_back(i-1);
toBeUpdated.push_back(j+1);
}
// left
if (j > 0){
toBeUpdated.push_back(i);
toBeUpdated.push_back(j-1);
}
// bottom left
if (i < m-1 && j > 0){
toBeUpdated.push_back(i+1);
toBeUpdated.push_back(j-1);
}
// bottom
if (i < m-1){
toBeUpdated.push_back(i+1);
toBeUpdated.push_back(j);
}
// bottom right
if (i < m-1 && j < n-1){
toBeUpdated.push_back(i+1);
toBeUpdated.push_back(j+1);
}
// right
if (j < n-1){
toBeUpdated.push_back(i);
toBeUpdated.push_back(j+1);
}
};
}
}
// Update all other cells
for (int k=0; k<toBeUpdated.size(); k+=2){
grid[toBeUpdated[k]][toBeUpdated[k+1]]++;
}
for (int i=0; i<m; i++){
cout << endl;
for (int j=0; j<n; j++)
cout << grid[i][j] << " ";
}
// Clear the temp vector
toBeUpdated.clear();
};
return grid[m-1][n-1];
}
The starting situation only has a value in the left-most column 0. We need to know the situation in the right-most column n-1 after time n-1. This means that we only have to look at each column once: column x at time x. What happens to column x after time x is no longer important. So we go from left to right, adding up the cells from the previous column:
1
1 8
1 7 35
1 6 27 104
1 5 20 70 230
1 4 14 44 133 392
1 3 9 25 69 189 518
1 2 5 12 30 76 196 512
1 1 2 4 9 21 51 127 323 ...
You will also notice that the result for the last cell is only influenced by two cells in the previous column, and three in the one before that, so to calculate the end result for e.g. the case n=9, you only need to calculate the values in this triangle:
1
1 4 14
1 3 9 25 69
1 2 5 12 30 76 196
1 1 2 4 9 21 51 127 323
However high the grid is, we only ever have to go up n/2 (rounded up) rows. So the total number of sums we have to calculate is n2/4, or n×m if m < n/2.
Also note that we don't have to store all these values at once, because we go column by column from left to right. So we only need a one-dimensional array of size n/2, and the current values in it are transformed like this (e.g. going from column 4 to 5 in the example above):
[4, 5, 3, 1] (0) -> 0 + 5 - 0 = 5
[9, 5, 3, 1] (5) -> 9 + 3 - 5 = 7
[9,12, 3, 1] (7) -> 12 + 1 - 7 = 6
[9,12, 9, 1] (6) -> 9 + 0 - 6 = 3
[9,12, 9, 4] (3) -> 4 + 0 - 3 = 1
[9,12, 9, 4, 1] (1) (additional value is always 1)
where we iterate over the values from left to right, add up the value to the left and right of the current element, subtract a temporary variable which is initialized to 0, store the result in a temporary variable, and add it to the current element.
So the theoretical time complexity is O(n2) or O(n.m) and the space complexity is O(n) or O(m), whichever is smaller. In real terms, the number of steps is n2/4 and the required space is n/2.
I don't speak Java, but here's a simple JavaScript code snippet which should easily translate:
function bacteria(m, n) {
var sum = [1];
for (var col = 1; col < n; col++) {
var temp = 0;
var height = Math.min(col + 1, n - col, m);
if (height > sum.length) sum.push(0);
for (var row = 0; row < height; row++) {
var left = row > 0 ? sum[row - 1] : 0;
var right = row < sum.length - 1 ? sum[row + 1] : 0;
temp = left + right - temp;
sum[row] += temp;
}
}
return sum[0];
}
document.write(bacteria(9, 9));

print 2 arrays like matrix for my assignment

I want my output to be like this e.g. if the user inputs 3:
without using 2d array
1 2 3
1 1 2 3
2 1 4 6
3 3 6 9
My code so far
public void matrixmutilplication() {
String thenumberofmatrix = JOptionPane.showInputDialog(null, "Enter the number of column and rows ");
int i = Integer.parseInt(thenumberofmatrix);
int[] cloumnarray = new int[i];
int[] rowarray = new int[i];
for (int z = 0; z <= i - 1; z++) {
cloumnarray[z] = z + 1;
rowarray[z] = z + 1;
}
for (int j = 0; j < i; j++) {
System.out.println(cloumnarray[j] * rowarray[j]);
}
}
I tried different options and can't get this to work properly.
public static void matrixmutilplication() {
String thenumberofmatrix = JOptionPane.showInputDialog(null, "Enter the number of column and rows ");
int i = Integer.parseInt(thenumberofmatrix);
for (int a = 0; a <= i; a++) {
for (int b = 0; b <= i; b++) {
// top corner, don't print nothing
if (a == 0 && b == 0) System.out.print("\t");
// top row 0-1, 0-2, 0-3 etc... just 1,2,3...
else if (a == 0) {
System.out.print(b + "\t");
// last line, print extra line break
if (b == i)
System.out.print("\n");
}
// first column 1-0, 2-0, 3-0... just a + space (tabulator)
else if (b == 0) System.out.print(a + "\t");
// any other cases, are candidates to multiply and give result
else System.out.print(a*b + "\t");
}
//look this is out of scope of nested loops, so,
// in each a iteration, print line break :)
System.out.print("\n");
}
}
public static void main(String[] args) throws Exception {
matrixmutilplication();
}
OUTPUT (3)
1 2 3
1 1 2 3
2 2 4 6
3 3 6 9
OUTPUT (5)
1 2 3 4 5
1 1 2 3 4 5
2 2 4 6 8 10
3 3 6 9 12 15
4 4 8 12 16 20
5 5 10 15 20 25
But problem (for me) is the numbers are not padded in the natural order, so, to achieve your goal, exactly as in your demo, will need a bit of padding like this
public static void matrixmutilplication() {
String thenumberofmatrix = JOptionPane.showInputDialog(null, "Enter the number of column and rows ");
int i = Integer.parseInt(thenumberofmatrix);
for (int a = 0; a <= i; a++) {
for (int b = 0; b <= i; b++) {
if (a == 0 && b == 0) System.out.print("\t");
else if (a == 0) {
System.out.print(String.format("%3s", b));
if (b == i)
System.out.print("\n");
}
else if (b == 0) System.out.print(a + "\t");
else System.out.print(String.format("%3s", a*b));
}
System.out.print("\n");
}
}
public static void main(String[] args) throws Exception {
matrixmutilplication();
}
OUTPUT (7)
1 2 3 4 5 6 7
1 1 2 3 4 5 6 7
2 2 4 6 8 10 12 14
3 3 6 9 12 15 18 21
4 4 8 12 16 20 24 28
5 5 10 15 20 25 30 35
6 6 12 18 24 30 36 42
7 7 14 21 28 35 42 49
What looks quite good :)
So this should be pretty simple.
public void matrixmutilplication() {
String thenumberofmatrix = JOptionPane.showInputDialog(null, "Enter the number of column and rows ");
int i = Integer.parseInt(thenumberofmatrix);
for (int a = 0; a < i; a++) {
for (int b = 0; b < i; b++) {
System.out.print(a*b + "\t");
}
System.out.print("\n");
}
}
Whenever you're working with a matrix involving two arrays (especially if you're trying to a solve a problem that deals with patterns), you want to have a nested for loop like so:
for(int row = 0; row < numSelected; row++) {
for(int col = 0; col < numSelected; col++) {
...
}
}
That way, each cell in the matrix will be covered. Now using that, you can try multiplying the row index and the col index and storing that to the correct cell.

2d array diagonally filling

1 2 3
4 5 6
7 8 9
this is my normal array, but i need to make it diagonally like this
1 2 4
3 5 7
6 8 9
this is very stupid way to make it work, but even it is not working because i am not able to find 2nd column elements.
for (i = 0; i < arr.length; ++i) {
for (n = 0; n < arr[0].length; ++n) {
if (i == 0 && n == 0){
arr[i][n] = 0;
} else if (i == 0 && n == 1) {
arr[i][n] = 2;
} else if (i == 1 && n == 0) {
arr[i][n] = 3;
} else if (n == 0) {
arr[i][n] = arr[i - 1][n] - arr[i - 2][n] + 1 + arr[i - 1][n];
} else {
arr[i][n] = arr[i][n - 1] - arr[i][n - 2] + 1 + arr[i][n - 1];
}
}
}
Well, if you were to enumerate the indices in order for that fill pattern, you would get
0,0
1,0
0,1
2,0
1,1
0,2
2,1
1,2
2,2
So, you need to iterate through the total of the two indices. That is, the additive total. As you can see, 0,0 totals 0, 1,0 and 0,1 total 1, and so on. Giving us something like this:
0 1 2
1 2 3
2 3 4
To iterate in this diagonal pattern, we can do the following:
// set up your matrix, any size and shape (MxN) is fine, but jagged arrays will break
int[][] matrix = {{0,0,0},{0,0,0},{0,0,0}};
// number is the value we will put in each position of the matrix
int number = 1;
// iterate while number is less than or equal to the total number of positions
// in the matrix. So, for a 3x3 matrix, 9. (this is why the code won't work for
// jagged arrays)
for (int i = 0; number <= matrix.length * matrix[0].length; i++) {
// start each diagonal at the top row and from the right
int row = 0;
int col = i;
do {
// make sure row and length are within the bounds of the matrix
if (row < matrix.length && col < matrix[row].length) {
matrix[row][col] = number;
number++;
}
// we decrement col while incrementing row in order to traverse down and left
row++;
col--;
} while (row >= 0);
}
Note that while this implementation will work for all matrix sizes (and shapes), it won't be as efficient as possible. Where n is matrix.length (assuming a square matrix), this implementation is an optimal O(n^2) class algorithm in big O notation; however, it effectively performs 2*n^2 iterations, whereas an optimal solution would only perform n^2.
You want to achive something like this:
1 2 4 7
3 5 8 B
6 9 C E
A D F G
In the grid of size NxN, for every point (x,y) in the grid, you can determine the value like this (still needs some corrections for offset at 0, see final formula):
if you are on the upper left half, calculate the area of the triangle that is above and left of you and add your distance from the top
if you are in the lower right half (or on the middle), calculate the area of the triangle below and right of you, add your distance from the bottom and subtract that from the whole area
Let's try it as a formula:
int N = 4; int[][] v = new[N][N];
for(int y = 0; y < N; y++) for(int x = 0; x < N; x++)
v[x][y] = ( x + y < N ) ?
( ( x + y + 1 ) * ( x + y ) / 2 + y + 1 ) :
( N * N + 1 - ( N - y ) - ( 2 * N - x - y - 1 ) * ( 2 * N - x - y - 2 ) / 2 );
I have no idea what complexity this is, but the experts can surely confirm that it is O(N^2) ? Also if it has some cool name like dynamic code, please let me know!
The advantage I see here is that you don't need to jump around memory and can fill all fields with one linear run through the memory. Also having it as a history independent formula can be optimized by the compiler or allow better parallelisation. If you had a machine with N^2 units, they could calculate the whole matrix in one operation.
Diagonal of an M by N Matrix, with Robust Array Formatting
Given that a lot of these answers have already covered the basic N by N arrays, and some are pretty efficient, I went ahead and made a more robust version that handles M by N arrays, along with a nice formatted printer, for your own enjoyment/masochistic viewing.
The efficiency of this method is O(N^2). The format of the printer is O(N^2).
Code
Main
You can set whatever rows and columns you want, assuming positive integer values.
public static void main(String[] args) {
//create an M x N array
int rows = 20;
int columns = 11;
int[][] testData = new int[rows][columns];
//iteratively add numbers
int counter = 0;
for(int i = 0; i < rows; i++) {
for(int j = 0; j < columns; j++) {
testData[i][j] = ++counter;
}
}
//print our test array
printArray(testData);
System.out.println("");
//print our diagonal array
printArray(diagonal(testData));
}
Printing a 2-Dimensional Array
This method works specifically for this example by determining the number of entries using M x N, and then counting the digits. If you want to, say, display any sized array based on the longest item in the array, you could easily adapt this code to do that. A decent challenge best assigned to the reader. O(N^2) for this, but due to having to search the array for the largest value, one that takes the largest digit will by nature require another O(N^2) for search.
static void printArray(int[][] array) {
//get number of digits
int count = array.length * array[0].length;
//get power of function
int power;
//probably the only time I'd ever end a for loop in a semicolon
//this gives us the number of digits we need
//You could also use logs I guess but I'm not a math guy
for(power = 0; count / Math.pow(10, power) > 1; power++);
for(int i = 0; i < array.length; i++){
System.out.print("{");
for(int j = 0; j < array[0].length; j++){
//Let's say Power is 0. That means we have a single-digit number, so we need
// +1 for the single digit. I throw in 2 to make it extra wide
System.out.print(String.format("%" + Integer.toString(power + 2)
+ "s", Integer.toString(array[i][j])));
}
System.out.println("}");
}
}
The Diagonal Converter
There's a lot of edge cases to be tested for when we account for M x N, so I went ahead and seem to have covered all of them. Not the neatest, but looks to be working.
static int[][] diagonal(int[][] input) {
//our array info
final int numRows = input.length;
final int numColumns = input[0].length;
int[][] result = new int[numRows][numColumns];
//this is our mobile index which we will update as we go through
//as a result of certain situations
int rowIndex = 0;
int columnIndex = 0;
//the cell we're currently filling in
int currentRow = 0;
int currentColumn = 0;
for(int i = 0; i < numRows; i++) {
for(int j = 0; j < numColumns; j++) {
result[currentRow][currentColumn] = input[i][j];
//if our current row is at the bottom of the grid, we should
//check whether we should roll to top or come along
//the right border
if(currentRow == numRows - 1) {
//if we have a wider graph, we want to reset row and
//advance the column to cascade
if(numRows < numColumns && columnIndex < numColumns - 1 ) {
//move current row down a line
currentRow = 0;
//reset columns to far right
currentColumn = ++columnIndex;
}
//if it's a square graph, we can use rowIndex;
else {
//move current row down a line
currentRow = ++rowIndex;
//reset columns to far right
currentColumn = numColumns - 1;
}
}
//check if we've reached left side, happens before the
//top right corner is reached
else if(currentColumn == 0) {
//we can advance our column index to the right
if(columnIndex < numColumns - 1) {
currentRow = rowIndex;
currentColumn = ++columnIndex;
}
//we're already far right so move down a row
else {
currentColumn = columnIndex;
currentRow = ++rowIndex;
}
}
//otherwise we go down and to the left diagonally
else {
currentRow++;
currentColumn--;
}
}
}
return result;
}
Sample Output
Input
{ 1 2 3}
{ 4 5 6}
{ 7 8 9}
{ 10 11 12}
Output
{ 1 2 4}
{ 3 5 7}
{ 6 8 10}
{ 9 11 12}
Input
{ 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}
Output
{ 1 2 4 7 11 16}
{ 3 5 8 12 17 22}
{ 6 9 13 18 23 27}
{ 10 14 19 24 28 31}
{ 15 20 25 29 32 34}
{ 21 26 30 33 35 36}
Input
{ 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 64 65 66}
{ 67 68 69 70 71 72}
{ 73 74 75 76 77 78}
{ 79 80 81 82 83 84}
{ 85 86 87 88 89 90}
{ 91 92 93 94 95 96}
{ 97 98 99 100 101 102}
{ 103 104 105 106 107 108}
{ 109 110 111 112 113 114}
{ 115 116 117 118 119 120}
{ 121 122 123 124 125 126}
{ 127 128 129 130 131 132}
{ 133 134 135 136 137 138}
{ 139 140 141 142 143 144}
{ 145 146 147 148 149 150}
Output
{ 1 2 4 7 11 16}
{ 3 5 8 12 17 22}
{ 6 9 13 18 23 28}
{ 10 14 19 24 29 34}
{ 15 20 25 30 35 40}
{ 21 26 31 36 41 46}
{ 27 32 37 42 47 52}
{ 33 38 43 48 53 58}
{ 39 44 49 54 59 64}
{ 45 50 55 60 65 70}
{ 51 56 61 66 71 76}
{ 57 62 67 72 77 82}
{ 63 68 73 78 83 88}
{ 69 74 79 84 89 94}
{ 75 80 85 90 95 100}
{ 81 86 91 96 101 106}
{ 87 92 97 102 107 112}
{ 93 98 103 108 113 118}
{ 99 104 109 114 119 124}
{ 105 110 115 120 125 130}
{ 111 116 121 126 131 136}
{ 117 122 127 132 137 141}
{ 123 128 133 138 142 145}
{ 129 134 139 143 146 148}
{ 135 140 144 147 149 150}
Luke's intuition is a good one - you're working through down-and-left diagonals. Another thing to notice is the length of the diagonal: 1, 2, 3, 2, 1. I'm also assuming square matrix. Messing with your for indicies can yield this:
int len = 1;
int i = 1;
while(len <= arr.length){
//Fill this diagonal of length len
for(int r = 0; r < len; r++){
int c = (len - 1) - r;
arr[r][c] = i;
i++;
}
len++;
}
len--; len--;
while(len > 0){
//Fill this diagonal of length len
for(int c = arr.length - 1; c > (arr.length - len - 1); c--){
int r = arr.length - len + 2 - c;
arr[r][c] = i;
i++;
}
len--;
}
System.out.println(Arrays.deepToString(arr));
Here is the code translated from here to Java and adjusted to your problem.
int[][] convertToDiagonal(int[][] input) {
int[][] output = new int[input.length][input.length];
int i = 0, j = 0; // i counts rows, j counts columns
int n = input.length;
for (int slice = 0; slice < 2 * n - 1; slice++) {
int z = slice < n ? 0 : slice - n + 1;
for (int k = z; k <= slice - z; ++k) {
// store slice value in current row
output[i][j++] = input[k][slice - k];
}
// if we reached end of row, reset column counter, update row counter
if(j == n) {
j = 0;
i++;
}
}
return output;
}
Input:
| 1 2 3 |
| 4 5 6 |
| 7 8 9 |
Output:
| 1 2 4 |
| 3 5 7 |
| 6 8 9 |
Click here for running test code
This is a simple dynamic programming (ish) solution. You basically learn from the last move you made.
NOTE: THIS IS A O(N^2) ALGOIRTHM
Initialize:
int m = 4;
int n = 4;
int[][] array = new int[m][n];;
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
array[i][j] = 0;
}
}
The work:
array[0][0] = 1;
for(int i = 0; i < m; i++){
if(i != 0){ array[i][0] = array[i-1][1]+1;}
// This is for the start of each row get 1+ the diagonal
for(int j = 1; j < n; j++){
if(i == 0){
array[i][j] = array[i][j-1]+j;
// only for the first row, take the last element and add + row Count
}else{
if(i == m-1 && j == n -1){
// This is only a check for the last element
array[i][j] = array[i][j-1]+1;
break;
}
// all middle elements: basically look for the diagonal up right.
// if the diagonal up right is out of bounds then take +2 the
// prev element in that row
array[i][j] = ((j+1) != (m)) ? array[i-1][j+1] +1: array[i][j-1]+2;
}
}
}
Printing the solution:
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
System.out.print(array[i][j]);
}
System.out.println("");
}
return 0;
}
You need to do a conversion from index 0..n for x/y (from 0 to x*y) and back to x/y from index...
public void toPos(int index){
return...
}
public int toIndex(int x, int y){
return...
}
I've left the implementation details to you.
Here is Complete working code for your problem. Copy and paste if you like
public class FillArray{
public static void main (String[] args){
int[][] array = {
{1,2,3},
{4,5,6},
{7,8,9}}; //This is your original array
int temp = 0; //declare a temp variable that will hold a swapped value
for (int i = 0; i < array[0].length; i++){
for (int j = 0; j < array[i].length; j++){
if (i < array.length - 1 && j == array[i].length - 1){ //Make sure swapping only
temp = array[i][j]; //occurs within the boundary
array[i][j] = array[i+1][0]; //of the array. In this case
array[i+1][0] = temp; //we will only swap if we are
} //at the last element in each
} //row (j==array[i].length-1)
} //3 elements, but index starts
//at 0, so last index is 2
}
}

Printing a number triangle

CS student here. I've just received an introduction to loops and I'm not sure I understand them very well. I'm trying to print a triangle of numbers n, such that if n = 4 you'd get something like this:
4
3 7
2 6 9
1 5 8 10
Instead I'm winding up with something like:
4
3 5
Suffice it to say I'm lost. Here's my code:
void drawT3 (int n)
{
int k = 1;
int t = 1;
for (int i=1;i<=n;i++)
{
k = n;
int j;
for (j=1;j<=n-i;j++)
System.out.print(" ");
for (j=1;j<=t;j++)
{
System.out.printf("%3d",k);
k += (n - j);
}
n--;
t++;
System.out.println();
}
}
void printTriangle(int n)
{
// build an auxiliary 2D array
final int t[][] = new int[n][n];
int i = 1;
for (int s = n - 1; s <= 2 * (n - 1); s++)
{
for (int x = s - n + 1; x < n; x++)
{
t[x][s - x] = i++;
}
}
// print the array
for (int y = 0; y < n; y++)
{
for (int x = 0; x < n; x++)
{
if (t[x][y] > 0)
{
System.out.printf("%3d", t[x][y]);
}
else
{
System.out.printf(" ");
}
}
System.out.println(); // start new line
}
}
Build an auxiliary 2D array of size n.
Put numbers into array as human will do, from 1 to n, following the diagonals. s in the code represents x + y sum. That sum is constant for every diagonal. In the first diagonal (the longest one) sum is equal to n - 1. In the second diagonal sum is 1 more, n. In the last "diagonal" (bottom right corner) the sum is 2 * (n - 1). That's exactly our loop: for (int s = n - 1; s <= 2 * (n - 1); s++). Having the sum and x we can obtain y with simple subtraction, y = s - x.
Print the array. Each cell of array is initialized with 0 (int's default value). So, if a cell has zero, we just print 3 spaces, to preserve the shape of triangle.
PS. My code was written for "educational purposes" :) To show how it can be done, in easy way. It's not optimized for speed nor memory.
public static void main(String[] args) {
// TODO code application logic here
triangle(4);
}
static public void triangle(int n){
int x = 0;
for (int i = n;i>0;i--){
System.out.print(i + " ");
x = i+n;
for (int j=0;j<n-i;j++){
System.out.print(x - j + " ");
x = x + n -j;
}
System.out.println("");
}
}
Output for 4:
4
3 7
2 6 9
1 5 8 10
Output for 6:
6
5 11
4 10 15
3 9 14 18
2 8 13 17 20
1 7 12 16 19 21
Observe that there are many ways to print out a triangle of numbers as described above, For example, here are two,
// for n=5,
// 1 2 3 4 5
// 6 7 8 9
// 10 11 12
// 13 14
// 15
And
// 5
// 4 9
// 3 8 12
// 2 7 11 14
// 1 6 10 13 15
And since recursion is Fun!
class triangle
{
//Use recursion,
static int rowUR( int count, int start, int depth )
{
int ndx;
if(count<=0) return start;
//-depth?
for (ndx=0;ndx<depth;ndx++)
{
System.out.print(" ");
}
//how many? 5-depth, 5,4,3,2,1
for( ndx=0; ndx<count; ++ndx )
{
System.out.printf("%3d",start+ndx);
}
System.out.printf("\n");
if( count>0 )
{
rowUR( count-1, ndx+start, depth+1 );
}
return ndx;
}
//Use recursion,
static int rowLR( int count, int start, int depth )
{
int ndx, accum;
if( start < count )
rowLR( count, start+1, depth+1 );
for( ndx=0; ndx<depth; ++ndx )
{
System.out.print(" ");
}
accum=start;
//how many? 5-depth, 1,2,3,4,5
for( ndx=0; ndx<(count-depth); ++ndx )
{
System.out.printf("%3d",accum);
accum+=count-ndx;
}
System.out.printf("\n");
return ndx;
}
public static void main(String[] args)
{
int count=4, depth=0, start=1;
System.out.printf("rowUR\n");
rowUR( count=5, start=1, depth=0 );
System.out.printf("rowLL\n");
rowLL( count=5, start=1, depth=0 );
}
};
int n=4,i,j,k,t;
for (i=n;i>=1;i--)
{
t=i;
k=n;
for(j=1;j<i;j++)
System.out.printf(" "); // for leading spaces
System.out.printf("%3d",i); // for first digit(or number) in each row (in your example these are 4,3,2,1)
for(j=i;j<n;j++)
{
t+=k;
System.out.printf("%3d",t);
k--;
}
System.out.print("\n");
}
OUTPUT:
for n=8
8
7 15
6 14 21
5 13 20 26
4 12 19 25 30
3 11 18 24 29 33
2 10 17 23 28 32 35
1 9 16 22 27 31 34 36
http://ideone.com/C1O1GS
make space around numbers according to your need.
PS: I would never suggest to write any pattern code using array unless it is very complicated. array will use extra memory space.

Categories

Resources