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;
}
Related
Ok so i need to Create a method in the LogicalOp class, which will receive two number parameters. The method must check which of the two numbers is larger, and execute an increasing count from the smallest to the largest. (Eg: if x is the first parameter and int y is the second, if x is greater than y, then the count is from y to x).
I have tried different methods but they either did not do anything or go for an infinite loop. I don't know how to stop a loop from x to y if the x is smaller then y and from x the count starts to y and then stop there to the biggest number i imputed in console.
public void getForthExercise() {
System.out.println("Give the x parameter and y ");
Scanner in = new Scanner(System.in);
int x = in.nextInt();
int y = in.nextInt();
if (x > y) {
for (int i = x; i >= y; i++)
System.out.println(i);
} else if (x < y) {
for (int i = y; i >= x;i++ )
System.out.println(i);
So if i imput x=25 and y=5 || y
Let's give you a hint how to simplify the problem: you do not need to care about x < y, or y > x for looping.
You only care: about the smaller number of that pair, and the larger number!
In other words: you simply have to loop from min(x, y) to max(x, y).
Think about it: for what needs to be printed, does it really matter whether x is 5 or 25, or whether y is 25 or 5? No, the only thing that matters is: you got 5, and 25. Which one came in first, and which one second, that doesn't change anything about the expected output!
Have a look at this:
int min = Math.min(x, y);
int max = Math.max(x, y);
for(int i = min; i < max; i++) {
System.out.println(i);
}
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.
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.
The code below was my first attempt at a LCM (lowest common multiple) calculator with a user interface (UI code not shown) written months ago. I know there are simpler ways to write this, but I'd like help understanding why sometimes THIS specific code is not finding a common multiple (with most number sets it works fine).
When a user inputs almost any number set, the app spits out the correct LCM. But when the number set 1,234 / 2,345 / 5,432 / 4,321 is used, the app initially was stopping when x hit 536,870,912. This was because the result of x * mult was a number that couldn't be held by the int primitive. After changing x to a double and casting result = (int) (mult * x), the code continues to function as expected but seems to increment x indefinitely.
public static void compare(){
result = 0;
int mult = 0;
double x = 1;
int[] nums = UserInterface.getNums();
// finds highest number in user-input set
for(int i = 0; i < nums.length; i ++){
if (nums[i] > mult) mult = nums[i];
}
// finds lowest common multiple
for(int i = 0; i < nums.length;){
if((mult * x) % nums[i] == 0){
result = (int) (mult * x);
i++;
}
else{
result = 0;
x++;
i = 0;
}
}
}
We know the LCM of your test set must be less than or equal to 67,920,681,416,560.
In java the int datatype has a max value of 2^31-1 = 2,147,483,647 so you are obviously going to get an overflow. You can change your code to use long throughout this has a max value of 2^64-1=18,446,744,073,709,551,615 so it should be sufficient for your calculation. If you need bigger values then look at the BigInteger class.
In javascript things are more complicated. All numbers are floating point so you loose accuracy. This probably mean the condition
if((mult * x) % nums[i] == 0)
is never satisfied so your loop never quits.
Your algorithm is very basic, there are much better algorithms out there, elclanrs has one above and see https://en.wikipedia.org/wiki/Least_common_multiple for some hints.
Also you should change the title of the question. As it stands it make no sense as any set of numbers must have a LCM.
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.