How to print an int array into a horizontal arrow? - java

Having an array such as int[] arr = new int[]{9, 6, 5, 2, 1, 2, 6, 3, 2, 7, 3, 8, 1, 5, 4, 7}; I want to print it like this:
* Output:
* 9
* 6 1
* 5 2 2
* 2 6 7 1
* 3 3 5
* 8 4
* 7
Without the * basically that's what I am trying to do. I intended to go over the array and just use System.out.println();until I reached then "end" which would be the 7 and then go to the next line but that didn't work.
I also tried printing 9 then 6 and 1 and so on but I couldn't make it to work either, I'm at a loss here and would appreciate guidance as to how can I think this through please.
EDIT
The intermediate step I have is making the array a "block" like this:
* Intermediate Step:
* 9 6 5 2
* 1 2 6 3
* 2 7 3 8
* 1 5 4 7
It should work for an array of any size.

I think this should work
You iterate 2 times. first you get the first row and all the diagonal rows below it, and then the last row and all the diagonal rows above it. You have to create a second array though to hold this info. I assumed that the array is same size for both X and Y. 7x7, 4x4 etc. tested with 4x4 data (your data)
String[][] array2 = new String[array.length*2][array.length];
for (int mb = 0; mb < array.length; mb++) {
String p1 = array[0][mb];
array2[mb][0] = p1;
int count = 0;
for (int i=1;i<=mb;i++) {
count++;
String p2 = array[i][mb-i];
array2[mb][count] = p2;
}
}
int counter = -1;
for (int mb = array.length -1; mb > 0; mb--) {
counter++;
String p1 = array[array.length -1][mb];
array2[mb+array.length -1][counter] = p1;
for (int i=0;i<counter;i++) {
String p2 = array[array.length -2 - i][array.length -counter + i];
array2[mb+array.length -1][i] = p2;
}
}

Well lets think you have two-dimensional array (you can change your one-dimension to two-dimensional easily)
PseudoCode :
whereToGo = RIGHT;
i = 0;
j = 0;
maxX = WIDTH;
maxY = HEIGHT;
minX = 0;
minY = 0;
while (somethingLeft){
addNumberToPyramid(array[i][j]);
if (whereToGo == RIGHT){
i++;
if (maxX == i) {
whereToGo = DOWN;
minY++;
}
} else if (whereToGo == DOWN){
//Same as if you go RIGHT, but increasing "j", at the end, you decrease maxY and then goLeft
} //... other two directions
}
This is how to parse input. Similar way for adding it to pyramid. I would prefer creating another 2D array, put that directly there as pyramid and then write method for printing this array correctly :
public class Pyramid{
//initialize minX, maxX etc.
int[][] array;
whereToGo = DOWN;
int i = 0, j = 0;
//initialize array size in constructor
public void addNumberToPyramid(int value){
if (whereToGo == DOWN){
array[i][j] == value;
j++;
if (j == maxY){
whereToGo = UPRIGHT;
maxY -= 2;
} else if (whereToGo == UPRIGHT){
} //... other else if directions
}
}
}

OK, first of all: You can't print a triangle like that for every length of an array. Say for example you had that array but missing the last entry; then your triangle would be missing one element at some point. In fact, you can print such a triangle if and only if the number of elements is the square of a natural number; in your example 16 = 4^2. Now, that 4 is also the length of your longest row.
OK, now how to do it. If you look at the intermediate step
9 6 5 2
1 2 6 3
2 7 3 8
1 5 4 7
and call that arr2, you want to print arr2[0][0] in the first row, arr2[1][0] and arr2[0][1] in the second row and so on until row 4 (which is of course the root of the length of the initial array). So you can write a nested loop that counts up like that.
Then you want to print arr2[1][3], arr2[2][2] and arr2[3][1] in the next row, then arr2[2][3] an arr2[3][2] and finally in the last row just arr2[3][3]. That is most easily done in a second nested loop.
I won't give you the exact code of course as this is obviously a learning task. But I will tell you that if you have a counter i for the outer loops and a counter j for the inner ones, the indexes in the intermediate array will depend on both i and j.

Related

Space complexity of a temp array that is outside a loop

I did come across a famous interview question, in which we are given a 2D array and we need to rotate the array by 90 degrees and while there are many ways to solve it, I decided to make use of an effective approach in which we do something like this.
/*
* clockwise rotate
* first reverse up to down, then swap the symmetry
* 1 2 3 7 8 9 7 4 1
* 4 5 6 => 4 5 6 => 8 5 2
* 7 8 9 1 2 3 9 6 3
*/
My code for above approach is:
public void rotate(int[][] matrix) {
int s = 0, e = matrix.length - 1;
while(s < e){
int[] temp = matrix[s];
matrix[s] = matrix[e];
matrix[e] = temp;
s++; e--;
}
for(int i = 0; i < matrix.length; i++){
for(int j = i+1; j < matrix[i].length; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
}
My main concern here is that the array that i'm using inside the first while loop might make the space complexity O(n). What if I simply do this:
int[] temp;
while( s < e ){
temp = matrix[s];
}
Would now be the space complexity O(1) or will it remain the same?
Your only space outside of the matrix being rotated is a single element and a pointer to a row, each of which is O(1). That the pointer points to something of O(N) space is irrelevant, as it is part of the input.
Note that you can do the rotation in about 1/2 the time: instead of reflecting the whole matrix two ways, moving each element twice, you can instead rotate each set of 4 elements where A replace B, B replaces C, C replaces D, and D replaces A.

how to add elements in a 2d array

I just want to know how this program works, and why the answer is 14.
here is the code:
public class extra {
public static void main(String[] args){
int[][] table = {{1,2,3},{4,5,6},{7,8,9}};
int sum = 0;
for( int i = 2; i > 0; i-- )
sum += table[i][3-i];
System.out.println(sum);
}
}
I understand the way the matrix is set up
123
456
789
but what is i in this problem, because I thought it was the number of rows, but since it is in a for loop, does it mean that i is the number in the matrix? Also how do the [i][3-i] come in to affect? The answer is 14, and I just want to know how it is 14.
It is only summing part of a diagonal, specifically table[2][1] which is 8, and table[1][2] which is 6.
The easiest way to see what is going on is to add an output statement in the loop:
for (int i = 2; i > 0; i--) {
sum += table[i][3 - i];
System.out.println(i + " " + (3 - i) + " " + table[i][3 - i]);
}
your program takes table[2][1] (value of 8) and table[1][2] (value of 6) elements, sums them and prints as output (value of 14)
regarding your question in a title your main method should be more like this:
public static void main(String[] args) {
int[][] table = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int sum = 0;
System.out.println("Before\n");
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
sum += table[i][j];
System.out.printf("Sum after %d iteration: %d\n", i + j + 1, sum);
}
}
System.out.println("\nIn total: " + sum);
}
i + j + 1 is a sum of current iteration which is sum of both axises, and since Java has 0-based indexed tables, it is increased by 1
Hope it helps!
i, in itself, does not correspond directly to anything in the matrix. It is just the name of the variable that the for loop changes each time it loops.
The [i][3-i] is how the i interacts with table. On the first round of the for loop, the i will be equal to 2. Thus, sum will be increased by table[2][1], which is the 3rd row and the 2nd column of the matrix, which has a value of 8.
On the second round of the for loop, the for loop, the i will be equal to 1. Thus, sum will be increased by table[1][2], which is the 2nd row and the 3rd column of the matrix, which has a value of 6.
Therefore, sum will be equal to 8+6=14.
What the for loop does is as follows:
i = 2. Enter loop.
Add table[2][3-2] to sum. Sum is now 8, because table[2][1] = 8.
Decrement i by 1.
i = 1. Enter loop.
Add table[1][3-1] to sum. Sum is now 14, because table[1][2] = 6.
Decrement i by 1.
i = 0. 0 is not greater than 0, so we exit the loop. The sum became 14.
Two-dimensional arrays like int[][] table have two indexes. One for the "outer" array (or rows), and one for the "inner" ones (columns).
Let's use int[][] table = {{1,2,3},{4,5,6},{7,8,9}}; from your code as an example:
table[1][2]: 1 means we should look in the array at index 1, which is {4,5,6}. 2 means we should look at {4,5,6}'s index 2, which is 6. In other words table[1][2] == 6.
table[2][0]: 2 means we should look in the array at index 2, which is {7,8,9}. 0 means we should look at {7,8,9}'s index 0, which is 7.
for (int i = 2; i > 0; i--)
so starting at 2 it checks if i is greater than zero
loops once then i-- subtracts 1
check again still greater than 0
loops again then subtracts 1 again
checks if greater than 0 now 0 it is not greater than 0 so stops looping
//thus loops 2 times
//[0] = 1st [1] = 2nd [2] = third ...
//counting in code starts at zero not 1 so and array of 3 counts a the spaces 0,1,2
int sum = 0;//sum starts at zero
//using the value of i translates as such
sum += table[2][3-2];//[2][1]this is 3rd group 2nd part so sum += 8
//then
sum += table[1][3-1];//[1][2]this is 2nd group 3rd part so sum += 6
0 + 8 + 6 = 14
Here's how to add elements in a 2D array in a easy way.
First when you initialize a 2D array think of the first brackets [ ] as a column and the second bracket [ ] as column rows.
For example: int[][] num = new int[10][5] which means 10 columns and 5 rows.
If you want to fill all the elements in a 2D array you must use two for loops:
int[][] num = new int[10][5];
for (int i =0; i < num.length;i++ ) {
for (int x=0; x < num[0].length;i++) { //we used num[0] because we need the length of the rows not the columns
num[i][x] = //any value you want to assign
}
}

Algorithm to create a diagonal pattern through a n x n grid

I would like to know the name of an Algorithm that solved the problem listed in the title, or explaination on how to do it, I'll try to explain it carefully, consider this:
9 8 6
7 5 3
4 2 1
It denotes a 3 x 3 grid, and I want to traverse the grid in the order noted there. The right bottom is the origin (0, 0) and left top is (2, 2).
So in coordinates the traversal looks like:
(0, 0) [Level 1]
(1, 0) [Level 2]
(0, 1) [Level 2]
(2, 0) [Level 3]
(1, 1) [Level 3]
(0, 2) [Level 3]
(2, 1) [Level 4]
(1, 2) [Level 4]
(2 ,2) [Level 5]
With the level denoting some sort of iteration.
Also if it is possible to generate this in a nice way, using java or even java 8, then I'd be happy to see it, because it is I think better as a naïve looping approach.
I'm wanting to use this for generating terrain for a graphics application, as with the conventional iterative approach (loop over width, loop over depth) it creates 'strange' random patterns, at least not the ones I want.
I think I have an idea in pseudo code, given input n:
while x < 2 && y < 2
do
"iterate over elements to the top right if they exist"
if (x < 2) x++
else
if (y < 2) y++
This would result in the expected iteration.
One way you could solve this would be to think of each number as an individual node with a left and top neighbor.
So your first level would be the following:
3
21
When requesting the node you would pass it the coordinate of 1(0,0) and then return (x+1,y) and (x, y+1) to give the two neighbors.
You can then do that again with any other node to walk the different paths.
The next level would consist of two nodes and their neighbors, for example:
6
53
and
5
42
So for level two when you pass in nodes 2 and 3 you would get 4, 5, 5, 6 as the results and you could just filter out the duplicates before going to the next level.
The key here is to loop through the list of nodes:
for(Node n: nodes)
{
Node left = new Node(n.x+1, n.y);
Node top = new Node(n.x, n.y+1);
//store these nodes in result list
}
With a node class that contains an x and y coordinate(you will have to make that object yourself). There is also probably a way more elegant approach to this but I am just trying to get you to think through the problem you are solving.
Don't you just want, for every "level of recursion" each A[i][j] with i + j = n n being the level of recursion and A being an array containing your grid?
Something like
int[][] A = {{1,2,3},{4,5,6},{7,8,9}};
for(int n=0;n < A.length + A[0].length;n++) {
for (int i=0;i<=n;i++) {
int j = n - i;
if(i<A.length && j<A[0].length)
System.out.print(A[i][j]+" ");
}
System.out.println();
}
With A being
9 6 3
8 5 2
7 4 1
You get
1
2 4
3 5 7
6 8
9
Each line is a level of iteration
You can do is as two set of doubly nested loops, first do the bottom left triangle and the diagonal. Then the top right triangle. You can see this running as a fiddle http://jsfiddle.net/SalixAlba/76zdLbp7/.
var size=5;
var x=0;
var y=0;
// Set up data array, store the index of the point
var data = new Array(size);
for(var i=0;i<size;++i) {
data[i]=new Array(size);
}
var pos=1;
// Bottom right triangle
for(var i=0;i<size;++i) { // should be size
for(var j=0;j<=i;++j) {
x = size - i + j - 1;
y = size - j - 1;
data[y][x] = pos;
console.log(i,j,x,y);
++pos;
}
}
// Top left triangle
for(var i=0;i<size-1;++i) {
for(var j=0;j<size-1-i;++j) {
x = j;
y = size - i - j - 2;
data[y][x] = pos;
console.log(i,j,x,y);
++pos;
}
}
var res="";
for(var i=0;i<size;++i) {
res = res + data[i].toString() + "\n";
}
$("textarea#output").val(res);

How to flip rows in a 1D short/int array representing a 2D array in Java

I need to flip a 1-D 64-element array of shorts (I can switch to ints if it's easier, but I assume the same processes will work for either) on it's head in Java. I represent it here as a square table for ease of understanding, since the actual problem is on a chessboard.
For example:
short[] example = new short[]
{
1, 2, 3,
4, 5, 6,
7, 8, 9
};
would become:
7 8 9
4 5 6
1 2 3
Please note that this is NOT the same as reversing the array (every answerer to similar questions I have found has made this mistake, hence my having to ask!). Reversing the array would give:
9 8 7
6 5 4
3 2 1
Apologies if I've missed any important info, any help is appreciated!
EDIT: The array is 1D and contains 64 elements, so short[64], and the reversed array is separate to the original. As far as what I've tried, I'm just struggling to wrap my head around it. I know how to reverse the array, but that's not what I'm after, and I had originally tried to reverse the index using:
byte index = (byte)(((byte)(position + 56)) - (byte)((byte)(position / 8) * 16));
Which is a code snippet I found on Chessbin, but this returns incorrect values and gives IndexOutOfBounds errors. In hindsight it's not clear to me if that code is meant to flip the index or reverse it. Since maths is not my strong suit, I tried to work around it with separate arrays.
My proposal would be like this:
public class Flipper {
public short[] flip(short[] array, int columns) {
short[] flipped = new short[array.length];
for(int i=0;i<array.length;i++){
int row = (i/columns); //use the fact that integer/integer is rounded down
int column = (i%columns);
flipped[i] = array[array.length-((columns*(row+1))-column)];
}
return flipped;
}
}
Which can be tested with:
public class FlipperTest {
private Flipper flipper = new Flipper();
#Test
public void test() {
short[] array = new short[]{1,2,3,4,5,6,7,8,9};
short[] actualResult = flipper.flip(array, 3);
assertThat(actualResult, equalTo(new short[]{7,8,9,4,5,6,1,2,3}));
}
}
Hope the code is self-explanatory
You have a physical 1D array representing a logical 2D array, and you want to swap rows. You can do this partly by mapping 2D array indices into a 1D array index.
Let height be the number of rows, and width be the number of columns.
for ( int i = 0; i < height/2; ++i ) {
int k = height - 1 - i;
for ( int j = 0; j < width; ++j ) {
short temp = array[i * width + j];
array[i * width + j] = array[k * width + j];
array[k * width + j] = temp;
}
}
I've written this for readability. You or the compiler may optimize some of the repeated computations.
You might be able to optimize further by using a 2D array, which would allow you to swap references to rows in O(height), rather than copying all the rows in O(height * width).

Matrix Multiplication Java

I need help, I am trying to make use of Lattice Multiplication in java for use in a BigInt class I am having to write for a class.
Right now I have the code storing the digits needed for the adding part of the algorithm in a 2 dimensional array. From there though I am at a lose as to how to make a loop to go through the array and add the numbers in what would be a diagonal.
For instance here is the test numbers etc:
200
*311
= 62200
The array is holding:
6 0 0
2 0 0
2 0 0
6 is (2,2) in the array and the bottom right is (0,0)
I need to add in a diagonal, such as (1,0) + (0,1) = 0
The issue is how do I do this, since not only is it moving up and left in different ways, but it goes from 1 element to 2 elements to 3 elements, then back the other way, and of course this will get bigger the longer the number is.
This is the code that I have:
public int multiply(BigInt val){
int[] bigger;
int[] smaller;
int[] dStore;
int lengthMax = (val.getSize()+this.getSize()) - 1;
int first = 0;
int second = 0;
int[][] tempResult;
//Checks to see which is bigger and then adds that to bigger
if(val.getSize() >= this.getSize()){
bigger = val.getData();
smaller = this.getData();
dStore = new int[val.getSize()+this.getSize()];
}else{
bigger = this.getData();
smaller = val.getData();
dStore = new int[val.getSize()+this.getSize()];
}
tempResult = new int[smaller.length][bigger.length];
for(int i=0;i < smaller.length;i++){
for(int j = 0;j < bigger.length;j++){
tempResult[i][j] = smaller[i] * bigger[j];
}
}
** there is the return statement etc below
This might help as to explain lattice multi better: Lattice Multi Video
I would try a different approach. Look at the lattice in the video and imagine that you rotates the array a little bit to the left so that the diagonals becomes vertical. The array would then look like this:
2 3 5
8 3
2 4 0
Now, just summarize the columns and you would have the total.
You would of course have to split the numbers into arrays of digits first. The easiest way to do that (but not the most efficient) is to convert them into strings ...
Good luck!
To move diagonally, you'd increment both x and y:
// Loop though the diagonal of an array
x = 0;
y = 0;
while (x < ARR_X_SIZE && y < ARR_Y_SIZE) {
// Do something with arr[x][y]
x++;
y++;
}
This is the basic loop; you can change the x and y increments to determine the direction you need to go. The key to going through the whole array is the value of the coordinates going into the loop. Array:
1 2 3
4 5 6
7 8 9
If you set x = 1; y=0 at the beginning of the loop, you'll get 2 6. Set x = 0, y = 1 and you'll get 4 8.
I hope this helps you with your assignment. Good luck on the rest! That is definately an interesting algorithm to implement.

Categories

Resources