Storing all diagonals from top right to bottom left in array - java

I am trying to store all of the values in the matrix from the top right to the bottom left and store them in an array.
int matrixSample [][] = {
{6,4,1,4},
{7,5,4,4},
{4,4,8,3},
{4,4,8,3}
};
The output should be
[4,1,4,4,4,3,6,5,8,3,7,4,8,4,4,4]
I can get the bottom right diagonal
static int[] getAllDiagonalsInMatrix(int matrix[][]){
// Sum of arithmetic progression
int diagonal[] = new int[matrix.length * (matrix.length + 1)*2];
int index = 0;
for(int row = 0; row < matrix.length; row++) {
for(int col = 0; col < matrix[row].length - row; col++) {
diagonal[index++] = matrix[row + col][col];
}
}
return diagonal;
}
Is this even possible to do using the same two loops by adjustments made in the loops above?

Okay, here is my thought process on your problem. However, I'm going to print values instead of collecting them to make it a little easier on me and keep the solution easy to read.
First, how do you get a diagonal? We need to do this frequently so lets start by making a function for that. Maybe we could pass in the top left corner of the diagonal and go from there.
public void getDiagonal(int[][] array, int row, int col) {
// While row and col are within the bounds of the array
while (row < array.length && col < array[row].length) {
// Print element in diagonal
System.out.println(array[row][col]);
// Diagonal moves from top-left to bottom-right
row++;
col++;
}
}
Now that we have a function to get a diagonal, we just need a way to call it. Essentially, we just need to follow an L shape going from the top-right to the top-left to the bottom-left.
// Get diagonals starting in the first row with a column > 0
for (int col = array.length - 1; col > 0; col--) {
getDiagonal(array, 0, col);
}
// Get all diagonals starting from the left most column
for (int row = 0; row < array.length; row++) {
getDiagonal(array, row, 0);
}
Now that we have a working way to iterate through the values, we can rewrite it to save the values into an array instead. You could also choose to remove the function entirely now that you have a process.
Edit: I almost forgot, but the mathematical solution you were looking for is as follows.
for (int row = 0; row < array.length; row++) {
for (int col = 0; col < array.length; col++) {
// Index along diagonal
int diagonal = Math.min(row, col);
// Which part of L contains value
if (col >= row) {
int start = array.length - 1 - (col - row);
int passed = start * (start + 1) / 2;
solution[passed + diagonal] = array[row][col];
} else {
int start = array.length - 1 - (row - col);
int passed = array.length * array.length - 1 - start * (start + 1) / 2; solution[passed - array.length + 1 + row] = array[row][col];
}
}
}

One solution is to iterate through a matrix where you consider positions outside of the matrix, but exclude every index out of bounds.
static int[] getDiagonals(int[][] mat) {
int diagonal[] = new int[mat.length * (mat[0].length)];
int index = 0;
int yStart = -mat[0].length;
for (int y = yStart; y < mat.length; y++) {
for (int x = 0; x < mat[0].length; x++) {
if (y + x >= 0 && y + x < mat.length) {
diagonal[index++] = mat[y+x][x];
}
}
}
return diagonal;
}
Might not be optimal as you are effectively traversing a matrix nearly twice the size, but it is pretty intuitive.

Related

implement game of life with only 2 array

I want to memory-efficient this (the game of life code of shiffman in the nature of code book). how can change the below code to have only two arrays and constantly swap them, writing the next set of states into whichever one isn’t the current array?
class GOL {
int w = 8;
int columns, rows;
int[][] board;
GOL() {
// Initialize rows, columns and set-up arrays
columns = width / w;
rows = height / w;
board = new int[columns][rows];
//next = new int[columns][rows];
// Call function to fill array with random values 0 or 1
init();
}
void init() {
for (int i = 1; i < columns - 1; i++) {
for (int j = 1; j < rows - 1; j++) {
board[i][j] = (int) random(2);
}
}
}
// The process of creating the new generation
void generate() {
int[][] next = new int[columns][rows];
// Loop through every spot in our 2D array and check spots neighbors
for (int x = 1; x < columns - 1; x++) {
for (int y = 1; y < rows - 1; y++) {
// Add up all the states in a 3x3 surrounding grid
int neighbors = 0;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
neighbors += board[x + i][y + j];
}
}
// A little trick to subtract the current cell's state since
// we added it in the above loop
neighbors -= board[x][y];
// Rules of Life
if ((board[x][y] == 1) && (neighbors < 2)) next[x][y] = 0;
else if ((board[x][y] == 1) && (neighbors > 3)) next[x][y] = 0;
else if ((board[x][y] == 0) && (neighbors == 3)) next[x][y] = 1;
else next[x][y] = board[x][y];
}
}
// Next is now our board
board = next;
}
// This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0'
void display() {
for (int i = 0; i < columns; i++) {
for (int j = 0; j < rows; j++) {
if ((board[i][j] == 1)) fill(0);
else fill(255);
stroke(0);
rect(i * w, j * w, w, w);
}
}
}
}
You might not like this, but the honest answer is: don't bother.
how can change the below code to have only two arrays and constantly swap them, writing the next set of states into whichever one isn’t the current array
This is already exactly what the code does.
The Game of Life requires two arrays. If you're coming up against real performance issues, then look for other areas of improvement. Focusing on the array is a red herring.
There's an old saying: premature optimization is the root of all evil. In other words, you shouldn't waste time trying to fix code before it's broken.
One obvious thing you might improve is: why are you using an int[] array instead of a boolean[] array? You only need to store two states: alive or dead, so using int values seems unnecessary. You'll save a little bit of memory if you switch to a boolean[] array, but again, you probably won't even notice the improvement.

Java pyramid of numbers - version 2

I'm reading a book and before I go to next chapter, I want to solve every exercise from current one. I have a problem with creating this output (the number of rows must be between 11 and 20)
I almost have it, even when I think my code is pretty bad and I could get it in less lines.
public class piramide {
public static void main(String args[]){
int max, n;
max = 20;
n=1;
for (int min=11; min<=max; min++){
if (n>9) n-=10;
int x=n-1;
int x2=n-1;
int b=min-1;
for (int j=1; j<min; j++){
while (b<max-1) {
System.out.print(" ");
b++;
}
System.out.print(x);
x--;
if (x<0) x=9;
}
System.out.print("A"+n+"A");
for (int j=1; j<min; j++){
System.out.print(x2);
x2--;
if (x2<0) x2=9;
}
System.out.println();
n+=2;
}
}
}
This is my current code and this is the output:
0987654321A1A0987654321
21098765432A3A21098765432
432109876543A5A432109876543
6543210987654A7A6543210987654
87654321098765A9A87654321098765
098765432109876A1A098765432109876
2109876543210987A3A2109876543210987
43210987654321098A5A43210987654321098
654321098765432109A7A654321098765432109
8765432109876543210A9A8765432109876543210
The problem I'm having is that the left part of the pyramid should be reversed. For example in the first row it should start at 0 (from the A1A) and finish in 1 but it starts in 1 and finish in 0, any idea how can I turn it to the other side?
Thanks to all of you who helped me ^^.
Oh, and the caps A are just so I could find the number easier in the output.
Have you worked the problem out?
The code will be much easier to understand with a couple changes...
max, min, and especially the single letter variables like n should have names that help describe what they are. This may also help you think about the problem when you don't have to keep in mind what all those random letters mean.
n I will rename to rowIndex
max I will rename to totalRows
min I will rename to columnIndex
Starting with that we have
public static void main(String args[])
{
int totalRows = 20;
int rowIndex = 1;
int columnIndex = 1;
//we look ready to start at row 1, column 1!
}
Now, this section of your code:
for (int min=11; min<=max; min++){
if (n>9) n-=10;
int x=n-1;
int x2=n-1;
int b=min-1;
for (int j=1; j<min; j++){
while (b<max-1) {
System.out.print(" ");
b++;
}
You are setting min, or, the columnIndex, to start at 11, because that is the "middle" of the pyramid. Then you print out spaces to catch up to the columnIndex.
x = rowIndex - 1;
x2 = rowIndex - 1;
b = columnIndex - 1;
j and b are now like a second and third column index, which is catching up to the actual columnIndex
Look at this example of how your for loop works:
for (int j=1; j <min; j++) { // j = 1;
while (b<max-1) { // 10 < 19
System.out.print(" "); // print space
b++; // b = 11
// 11 < 19
// print space
// b = ...(*skip to the end*) 19
// j = 2
// b is still 19, doesn't print anything
// j = 3, etc.
}
System.out.print(x);
x--;
if (x<0) x=9;
}
In other words, j and b are unnecessary because we already have a columnIndex we can use. Let's do some more renaming of variables.
x I will rename to printValue
x2 will be unnecessary, we only need one printValue, However, I will be adding a totalColumns to the beginning of our main method.
So now our finished code will look like:
public static void main(String args[])
{
int totalRows = 20;
int totalColumns = (totalRows * 2) - 1; //added totalColumns, notice the number of columns increases by two with each row and we start with 1 column.
int rowIndex = 0;//easier for looping to start with zero
int columnIndex = 0;
int printValue = 0;
while (rowIndex < totalRows) // we will want to spin through every row
{
//notice there is no limit to the length of a variable name!
int numberOfValuesInRow = (rowIndex*2) + 1;
int numberOfSpacesToOffsetOnEachSide = (totalColumns - numberOfValuesInRow) / 2;
//Print Spaces before the numbers in this row
for (int i = 0; i < numberOfSpacesToOffsetOnEachSide; i++) //i is commonly used to stand for index in a single for loop
{
System.out.print(" ");
columnIndex++; //keep track of columnIndex so we know when we are at the middle of the columns
}
//Print numbers in this row
for (int i = 0; i < numberOfValuesInRow; i++)
{
if (columnIndex < (totalColumns/2) + 1) { //depending on columnIndex position, increase or decrease printValue
printValue++;
} else {
printValue--;
}
System.out.print(printValue%10); //Print printValue, the % will return the remainder of (printValue/10)
columnIndex++;
}
System.out.println(); //start next line
columnIndex = 0; //reset columnIndex for the next row
rowIndex++;
}
}

Can I simplify this for loop?

The following segment of code is from a system that generates a 5 by 5 grid of JButtons. I need to iterate over an ArrayList of JButtons and pass the row and column of the JButton into the ButtonListener's constructor. The way the code is currently shown below works, but I was wondering if I could clean up the code at all or re-factor in any way. I seem to have a lot of instructions for trying to construct a grid.
int row = 1, col = 1;
for (JButton curButton : view.getButtons()) {
curButton.addActionListener(new ButtonListener(row, col));
row++;
if (row > 5) {
row = 1;
col++;
}
}
Is there any way I can improve the quality or simplify the above code segment?
int iterator = 0;
for (JButton curButton : view.getButtons()) {
curButton.addActionListener(new ButtonListener(iterator%5 + 1, iterator/5 + 1));
iterator++;
}
Note here that I'm using integer division, which always rounds down. iterator/5 + 1 will map {0,1,2,3,4,5,6,...} to {1,1,1,1,1,2,2...}
Can't you have:
col = row = 5;
for (int i = 0; i < col; i++) {
for (int j = 0; j < row; j++) {
curButton.addActionListener(new ButtonListener(i, j));
}
}
Might have to make col and row 6 or make i and j start at a different number.

How to get the contents of a column to slide down to the bottom row of my 7x7 2D array?

I've been lurking and found heaps of great information form here, however the last few days I have been stuck and haven't been able to find help with my issue so I thought id post.
I have some homework and I have to make the contents of my array drop down to the bottom row. If i rotate the grid the items should still drop down to the bottom row and if i eat an object from the bottom row, everything above it in that column should drop down too.
Any help is greatly appreciated.
Here is a demo video of what should happen:
http://youtu.be/CB07vN-C_-Y
This is what i have so far:
`public class Assignment
{
// This method should return a *new copy* of
// the 2D cell matrix, with entries rotated clockwise
// The original matrix should not be changed
public static int[][] rotateClockwise(int[][] cells)
{
int w = cells.length;
int h = cells[0].length;
int[][] matrix = new int[h][w];
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
matrix[i][j] = cells[j][h - i - 1];
}
}
return matrix;
}
// This method should return a *new copy* of
// the 2D cell matrix, with entries rotated anti-clockwise
// The original matrix should not be changed
public static int[][] rotateAnticlockwise(int[][] cells)
{
int w = cells.length;
int h = cells[0].length;
int[][] matrix = new int[h][w];
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
matrix[i][j] = cells[w - j - 1][i];
}
}
return matrix;
}
// This method should return a *new copy* of the array, except
// that if there is a 0 that has a non-zero in the preceding
// slot in the array, then those two entries should be swapped
// See ProgrammingProject.pdf for an example
// The original array should not be changed
public static int[] dropOne(int[] column)
{
return column; // this will compile but gives the wrong result
}
}`
I'd model a column as a Queue<Icon> col = new LinkedList<Icon>(); there's an outline here for Queue<Segment> and a complete example here for Queue<Bauble>. You can peek() at the head (bottom) of the queue; if it's empty, you remove() a block from the column and add() it to the tail (top).
Addendum: You might start with this example, drop the getGray(), change the layout to new GridLayout(0, 1). Then, instead of shuffle(list), you'd cycle the queue.
for(int i = 0; i < arrayWidth; i++) {
boolean reachedZero = false;
for( int j = 0; j < arrayHeight; j++) {
if(array[i][j] == 1 && reachedZero == true) {
while( j >=0 && array[i][j - 1] == 0) {
array[i][j-1] = array[i][j];
array[i][j] = 0;
j--;
reachedZero = false;
}
j--; // Maybe an error here, it's late
if( array[i][j] == 0) {
reachedZero = true;
}
}
}
This was posted by a lovely redditor (RankWeis) from the /learnprogramming sub-reddit.
http://www.reddit.com/r/learnprogramming/comments/126597/java_help_needed_on_adding_a_gravity_effect_to/

How to draw a set of horizontal lines?

I am new to OpenGL as learning exercise I decided to draw a set of horizontal lines from a grid of m x n matrix containing the vertices locations
This is what I have
and If I use LINE_STRIP
A code snippet using vertex arrays and indices will be great, I cant seem to be able to get the concept just from a text book I need to see and play with a code example
Any help will be much appreciated!
#Thomas
Got it working with the following code
totalPoints = GRID_ROWS * 2 * (GRID_COLUMNS - 1);
indices = new int[totalPoints];
points = new GLModel(this, totalPoints, LINES, GLModel.DYNAMIC);
int n = 0;
points.beginUpdateVertices();
for ( int row = 0; row < GRID_ROWS; row++ ) {
for ( int col = 0; col < GRID_COLUMNS - 1; col++ ) {
int rowoffset = row * GRID_COLUMNS;
int n0 = rowoffset + col;
int n1 = rowoffset + col + 1;
points.updateVertex( n, pointsPos[n0].x, pointsPos[n0].y, pointsPos[n0].z );
indices[n] = n0;
n++;
points.updateVertex( n, pointsPos[n1].x, pointsPos[n1].y, pointsPos[n1].z );
indices[n] = n1;
n++;
}
}
points.endUpdateVertices();
Then I update and draw by doing
points.beginUpdateVertices();
for ( int n = 0; n < totalPoints; n++ ) {
points.updateVertex( n, pointsPos[indices[n]].x, pointsPos[indices[n]].y, pointsPos[indices[n]].z );
}
points.endUpdateVertices();
This is the result
Fix it by changing the nested for loop
for ( int col = 0; col < GRID_COLUMNS; col++ ) {
for ( int row = 0; row < GRID_ROWS - 1; row++ ) {
int offset = col * GRID_ROWS;
int n0 = offset + row;
int n1 = offset + row + 1;
indices[n++] = n0;
indices[n++] = n1;
}
}
Now I can have any number of rows and columns
Thanks agin!
You need to draw a line for each segment and resuse an index, i.e. for the first part you'd draw a line for (0,1), (1,2), (2,3) and so on.
Edit:
Suppose you have a 4x5 array (4 lines, 5 vertices per line). You could then calculate the indices like this (pseudo code):
Vertex[] v = new Vertex[20]; // 20 vertices in the grid
for(int row = 0; row < numrows; row++) // numrows = 4
{
int rowoffset = row * numcols ; //0, 4, 8, 12
for(int col = 0; col < (numcols - 1); col++) //numcols = 5
{
addLineIndices(rowoffset + col, rowoffset + col +1); //adds (0,1), (1,2), (2,3) and (3, 4) for the first row
}
}
Then issue the draw call for numrows * (numcols - 1) linesegments (GL_LINES), i.e. 16 in the example. Note that addLineIndices would be a function that adds the index pair for one line segment to an index array which is then supplied to the draw call.

Categories