Java and traversing loop - java

This question is somewhat related to my earlier post about how to traverse multi-dimensional arrays.
EDIT: I've added three images of how I would like the cube to be rearranged. The first image shows a 2x2x2 cube with numbers set in their default positions. The second image shows the same cube with the first column rotated counterclockwise. The third image shows the Z, X and Y axes.
EDIT 2: I've changed the values.
EDIT 1: Based on what I could estimate with pen and paper, I have the following loop iterations. In this case it will be the numbers 0, 2, 4 and 6 in the cube above. These are the Z, X and Y values from where the numbers should be taken:
z x y
0 0 0
0 1 0
1 0 0
1 1 0
EDIT 2: I've changed the values and replaced old z with zz and old x with xx. This was needed as one side (container) had to use the z value while the other (containerTemp) needed the zz value (the z value in reverse).
EDIT 1: The numbers 0, 2, 4 and 6 should be placed in the following locations just as they are taken from the locations mentioned above:
zz xx y
1 0 0
0 0 0
1 1 0
0 1 0
EDIT 2: It means that the value 0 at position 0 0 0 (z x y) will be moved to the location of value 4 at position 1 0 0 (zz xx y).
Note: I understand that this is not normally how the Z, X and Y positions are used in a 3D matrix and perhaps that is why find it harder to solve this. I have the rotations and flips completed for each slice of the cube so I do not feel like I should change the way the code works as of this moment (of course I'm open for WOW recommendations, if I think like a moron). I just wanted to become better at matrix manipulations as I never sit with this kind of stuff even in my career.
SOLVED: I used the following code for my project. The code will however not work for 2x3x2 groupings. So I guess this solution should only be used for equal sized cubes. I will look into it but it is not required for my project as of this moment. If someone feels like know a better way please tell me as I want to learn more!
for (int y = 0; y < yDim; y++) {
for (int z = 0; z < zDim; z++) {
for (int x = 0, zz = xDim - 1, xx = z; x < xDim; x++, zz--) {
System.out.println("["+zz+"]["+xx+"]["+y+"] = ["+z+"]["+x+"]["+y+"]");
containerTemp[zz][xx][y] = container[z][x][y];
}
}
}

Think about like that - every time you turn a Rubik's cube, you turn one slice of the cube which is actually a two-dimensional array which you know how to solve.
So each turn you need to:
Realize what is the right two-dimensional array you need (I guess it will be given using a fixed value of x, y or z, for example - y=2 will define a two-dimensional array of xonz where all the y values are 2)
Apply on it the algorithm you have already
Copy the results to the original three-dimensional array.
So for the case of y=2 it will be something like (pseudo code):
// defining the two-dimensional array (the "slice") from the cube-array
for (i = 0; i < N; i++) {
for (k = 0; k < N; k++) {
arr[i,k] = origArr[i,2,k]
}
}
// turning the two-dimensional array with the function we already have
turnedArr = turn(arr)
// copying the resulted two-dimensional array back to the cube
for (i = 0; i < N; i++) {
for (k = 0; k < N; k++) {
origArr[i,2,k] = turnedArr[i,k]
}
}
Of course, you'll have to pay attention to where you start the iteration for every axis's index and if you're increasing or decreasing etc, but that's the main idea.

Related

Is there a way to skip index in an array?

The input is supposed to be:
5
21,45
62,34
48,77
32,13
40,25
Where first line is the amount of coordinates. The rest of the lines are the coordinates.
The output is supposed to be:
20,12
63,78
Where the first line is the minimum X and Y values -1 and the second line is the maximum X and Y values +1.
int drops;
drops=scan1.nextInt();
String[] array=new String[drops];
int[] S=new int[drops*2];
for(int x=0;x<drops;x++) {
array[x]=scan2.nextLine();
String[] NoComma=array[x].split(",");
for(String s:NoComma) {
System.out.println(s);
S[x]=Integer.parseInt(s);
System.out.println(S[x]);
}
}
So far I was able to take away the comma and convert the string values into int but I don't know how to continue from here.
I have an idea which is to skip index in the array so I can get a pattern similar to (stay, skip, stay, skip, stay, skip).
I'm feeling kind of lost. If you see this please help.
This is not a “which ones do I skip” (homework) problem. It’s a programming problem.
Since it’s homework, I want to rob you of the chance to learn by spoon feeding you code, but I will assist:
at the top of your code, define 4 int variables called minX, maxX, minY and maxY
set max’s to zero
set min’s to a very large number
loop over the lines - keep your outer loop
for each line:
read int x from the scanner, then a comma, then int y, then
nextLine
set minX to the minimum of x and minX
do similar for maxX, minY and maxY
subtract 1 from min’s
add 1 to Max’s
print em
Given that the first and second part of a coordinate pair are completely unrelated, why are you insisting on shoving them into a single array?
Stop doing that and this problem becomes much simpler. Have two arrays: The 'x' coords, and the 'y' coords. Then all you need to do is write code that 'finds the smallest number' and 'finds the largest number', which are trivial tasks (in fact, can be done in one go: Sort the inputs - now smallest is first item and largest is last, easy peasy), and adding 1 / subtracting 1 is even simpler than that.
int[] x, y; is what you're looking for.
If you already have them in an Array directly next to each other, then you can also work your way through them this way.
As you probably are a beginner, I'd suggest this way:
int minX = Integer.MAX_VALUE; //everything is smaller than this,
int minY = Integer.MAX_VALUE; //the first one should just replace it
//when dealing with the max values, use the opposite: Integer.MIN_VALUE
//to make everything bigger than the initial value
for(int i=1;i<array.length;i+=2) { //start at 1 to avoid the count, "i+=2" to make it skip the Y coordinate entry
minX = Math.min(minX, array[i]);
minY = Math.min(minX, array[i+1]); //take it from the next one
}
This will work its way through the entries, while only targeting the X coordinate with the value of i. By looking forward into the Y value using array[i+1] you don't need to iterate over that seperately. Just keep track of the current X index you're at and add one, and you get the Y coordinate. Using this solution, just make sure to subtract one at the end to get your desired output.
If you want a quicker solution with some more advanced techniques, I can suggest you to look into Streams:
int minX = IntStream.range(0, array.length-1) //create a sequential stream. "-1" because the first one is just the count
.filter(i -> i % 2 == 0) //take every X coordinate by removing every odd element (keep the even ones)
.map(i -> array[i+1]) //now place the real entries in there
.min().orElse(0); //get the minimum value, if none return 0
//maxX works the same, just replace min() by max() in the last line
int minY = IntStream.range(0, array.length-1) //create a sequential stream. "-1" because the first one is just the count
.filter(i -> i % 2 == 1) //take every X coordinate by removing every even element
.map(i -> array[i+2]) //now place the real entries in there. +2 to skip count, skip X and use Y coordinate
.min().orElse(0); //get the minimum value, if none return 0
//maxY works the same, just replace min() by max() in the last line
This will create a list of indices first, to split the array into X and Y coordinates, then replace the indexes with the real values and finally the min() or max() operation returns the biggest/smallest value of that stream. The value of orElse will only be used, if the array is empty/has a length of 0.
I've checked your code and somehow completed it. Also, you can check comments to see what happened there:
public static void main(String[] args)
{
int drops;
Scanner input = new Scanner(System.in);
System.out.println("Please enter number of points:");
drops=Integer.parseInt(input.nextLine());
int[][] array=new int[drops][2];
System.out.println("OK, now enter coordinates per line( comma separated )");
String[] rawCords;
// Getting inputs
for(int x=0;x<drops;x++) {
rawCords = input.nextLine().split(",");
array[x][0] = Integer.parseInt(rawCords[0]);
array[x][1] = Integer.parseInt(rawCords[1]);
}
// Finding Max and Min
int maxX = array[0][0],
minX = array[0][0],
maxY = array[0][1],
minY = array[0][1];
for(int i=0; i<drops; i++)
{
// Max
if (array[i][0] > maxX)
maxX = array[i][0];
if (array[i][1] > maxY)
maxY = array[i][1];
// MIN
if (array[i][0] < minX)
minX = array[i][0];
if (array[i][1] < minY)
minY = array[i][1];
}
System.out.println("Min: " + (minX-1) + "," + (minY-1));
System.out.println("Max: " + (maxX+1) + "," + (maxY+1));
}

Can someone explain to me this code of multiplying two variables using shifts? [duplicate]

This question already has answers here:
Bitwise Multiply and Add in Java
(4 answers)
Closed 4 years ago.
So I have the following code to multiply two variables x and y using left and right shifts.
class Multiply {
public static long multiply(long x,long y) {
long sum = 0;
while(x != 0) {
if((x & 1) != 0) {
sum = sum+y;
}
x >>>= 1;
y <<= 1;
}
return sum;
}
public static void main(String args[]) {
long x = 7;
long y = 5;
long z = multiply(x,y);
}
}
But I dont understand the logic behind it, I understand that when you do
y<<=1
You are doubling y, but what does it mean that the number of iterations of the while loop depends on the number of bits x has?
while(x != 0)
Also why do I only sum if the rightmost bit of x is a 1?
if((x & 1) != 0) {
sum = sum+y;
}
I've really tried to understand the code but I haven't been able to get my head around the algorithm.
Those of us who remember from school how to multiply two numbers, each with two or more digits, will remember the algorithm:
23
x45
---
115
92x
----
1035
For every digit in the bottom factor, multiply it by the top factor and add the partial sums together. Note how we "shift" the partial sums (multiply them by 10) with each digit of the bottom factor.
This could apply to binary numbers as well. The thing to remember here is that no multiplication (by a factor's digit) is necessary, because it's either a 0 (don't add) or a 1 (add).
101
x110
-----
000
101
101
-----
11110
That's essentially what this algorithm does. Check the least significant bit; if it's a 1, add in the other factor (shifted), else don't add.
The line x >>>= 1; shifts right so that the next bit down becomes the least significant bit, so that the next bit can be tested during the next loop iteration. The number of loops depends on where the most significant bit 1 in x is. After the last 1 bit is shifted out of x, x is 0 and the loop terminates.
The line y <<= 1; shifts the other factor (multiplies by 2) in preparation for it be possibly added during the next loop iteration.
Overall, for every 1 bit in x at position n, it adds 2^n times y to the sum.
It does this without keeping track of n, but rather shuffling the bits x of 1 place right (dividing by 2) every iteration and shuffling the bits of y left (multiplying by 2).
Every time the 0 bit is set, which is tested by (x & 1) != 0, the amount to add is the current value of y.
Another reason this works are these equivalences:
(a + b) * y == a*y + b*y
x * y == (x/2) * (y*2)
which is the essence of what’s going on. The first equivalence allows bit-by-bit addition, and the second allows the opposite shuffling.
The >>> is an unsigned right shift which basically fills 0 irrespective of the sign of the number.
So for value x in the example 7 (in binary 111) the first time you do x >>>= 1; You are making the left most bit a zero so it changes from 111 to 011 giving you 3.
You do it again now you have 011 to 001 giving you 1
Once again and you have 001 to 000 giving you 0
So basically is giving you how many iterations before your number becomes zero. (Basically is diving your number in half and it is Integer division)
Now for the y value (5) you are adding it to your sum and then doubling the value of y
so you get:
y = 5 sum = 5
y = 10 sum = 15
y = 20 sum = 35
Only 3 iterations since x only needed to shift 3 times.
Now you have your result! 35

Finding smallest neighbour in a 2D array

I have some code that is supposed to find the smallest of the 8 neighboring cells in a 2D array. When this code runs, the smallest is then moved to, and the code run again in a loop. However when it is run the code ends up giving a stack overflow error as it keeps jumping between two points. This seems to be a logical paradox as if Y < X then X !< Y. So it think it is my code at fault, rather than my logic. Here's my code:
private Point findLowestWeight(Point current) {
float lowest = Float.MAX_VALUE;
Point ret = new Point(-1, -1);
LinkedList<Point> pointList = new LinkedList<Point>();
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (!(i == 0 && j == 0)) {
if ((current.x + i >= 0 && current.x + i <= imageX - 2)
&& (current.y + j >= 0 && current.y + j <= imageY - 2)) {
pointList.add(new Point(current.x + i, current.y + j));
}
}
}
}
for (Point p : pointList){
if (map[p.x][p.y] < lowest){
lowest = map[p.x][p.y];
ret = p;
}
}
return ret;
}
You need a stopping case.
find the smallest of the 8 neighboring cells in a 2D array. When this code runs, the smallest is then moved to, and the code run again in a loop
is a fine way to start but says nothing about stopping.
Do you care about the value of the current cell? If so you need to check 9 not 8. If you simply want to move down hill then you need to check where you've been or any flat multi-cell valley will put you into an infinite loop. Consider only moving if moving down.
If you truly don't care where you are then even a single cell valley will put you into an infinite loop as you bounce in and out of it. In which case you'd need some other stopping condition. Consider stopping after imageX * imageY iterations.
Do you move even if the smallest neighbour is greater than the value in the center?
Example:
2 2 2 2
2 0 1 2
2 2 2 2
You start with center cell 0. The smallest neighbour is 1. If you move to 1, the smallest neighbour is 0. You can continue endless.
Probably you should not move, if the smallest neighbour is greater than the current cell.

Summing EVERY individual diagonal in a 2D array java

I am having trouble with part of my homework assignment. Essentially, what we have to do is take a 2D array full of random numbers and sum each row, column, and diagonal. I have figured out the rows and columns, but cannot get the diagonals. Here is my code pertaining to the diagonals:
for (int c = 0 ; c < columnCount; c++)
{
int sum = 0;
for (int i = (7 - c); i >= 0; i--)
{
sum += board[(7 - c) - i][i];
}
return sum;
}
I have gotten some of the diagonals summed, but cannot figure out how to get the rest. For instance:
_ 0 1 2 3 4 5 6 7
0 X X X X X X X X
1 X X X X X X X
2 X X X X X X
3 X X X X X
4 X X X X
5 X X X
6 X X
7 X
As you can see, I have only summed half of the board (it is going from top right to bottom left each time). I will eventually need to sum the diagonals in the opposite direction as well...if anyone has insight on that.
I have already looked around on here and on other websites, but the only thing I can find is how to sum the MAJOR diagonals. I need to sum every single diagonal on an 8X8 board. I have really thought through this but no matter what I try I cannot get the other values without going out of bounds. I appreciate any help!
There are tons of options to do this. Based on the method you are currently using (and trying to be consistent with it), I'd suggest following it up by going from rows 1-7 and completing the missing summations (hint: for remaining items, start at right edge and move down-and-left).
The question that pmkrefeld linked to in the comments contains code to do it (well, hypothetically, I didn't look at it and have no idea if it actually works). The answer there was just given away. It is working code but you will learn more by trying to implement it yourself.
Sometimes it helps to work this things out on paper. Draw your array, then think: How would a human do it? If you can come up with a clear algorithm that way and wrap your head around it, then it will become straightforward to translate it to Java (or whatever language).
For calculating the remaining part of the matrix you can insert two nested for loops below your code. Something like this-
sum = 0;
int t,k;
int result[] = new int[20];
for(c = 1; c <= 7; c++) {
t = c;
for(i = 7; i >= c; i--) {
sum += board[i][t];
t++;
}
result[k] = sum; // result[k] will store each diagonal sum
k++;
sum = 0;
}

Manhattan Distance Clarification

I would like to know the difference in calculating the manhattan distance of the following code snipets. I have 2D array int[][] state and want to calculate the manahattan distance from a current node to the goal node:
example:
current node
0 1 3
4 2 5
7 8 6
0 == empty tile
I must now calculate the manhattan distance from this node to the goal node:
1 2 3
4 5 6
7 8 0
These are some of the examples i have found:
1) This one uses the x and y coordinates to calculate the distance
public int manhattan(Node currentNode, Node goalNode) {
return Math.abs(currentNode.x - goalNode.x) + Math.abs(currentNode.y - goalNode.y);
}
2) This one uses the coordinate but does some calculation in the which i don't understand the meaning.
private static int manhattan(int[] pos, int tile) {
int[] dest = new int[] { (tile - 1) % size, (tile - 1) / size };
return Math.abs(dest[0] - pos[0]) + Math.abs(dest[1] - pos[1]);
}
3) This one the person uses the numbers in the cells to do the calculations
public int Manhattan(Node current Node goal){
int dist = 0;
for(int x = 0; x < current.row; x++)
for(int y = 0; y < current.col; y++)
dist += Math.abs(current.state[x][y] - goal.state[x][y]);
}
which one is correct for me?
thanks
The first one is assuming that the borders cannot be wrapped around. The second is assuming that if you go to the right of the right edge, you get to the left edge. I have no idea what the third one is doing related to the Manhattan distance. The one that is correct for you depends on what problem you are trying to solve.

Categories