I am not familiar with coordinate systems or much of the math dealing with these things at all. What I am trying to do is take a Point (x,y), and find its position in a 1 dimensional array such that it follows this:
(0,2)->0 (1,2)->1 (2,2)->2
(0,1)->4 (1,1)->5 (2,1)->6
(0,0)->8 (1,0)->9 (2,0)->10
where the arrows are showing what value the coordinates should map to. Notice that an index is skipped after each row. I'm think it'll end up being a fairly trivial solution, but I can't find any questions similar to this and I haven't had any luck coming up with ideas myself. I do know the width and height of the 2 dimensional array. Thank you for any help!
My question is perhaps ambiguous or using the wrong terminology, my apologies.
I know that the coordinate (0,0) will be the bottom left position. I also know that the top left coordinate should be placed at index 0. Each new row skips an index by 1. The size of the coordinate system varies, but I know the number of rows and number of columns.
First step, flip the values upside down, keep points in tact:
(0,2)->8 (1,2)->9 (2,2)->10
(0,1)->4 (1,1)->5 (2,1)->6
(0,0)->0 (1,0)->1 (2,0)->2
You'll notice that y affects the output by a factor of 4 and x by a factor of 1.
Thus we get a very simple 4y + x.
Now to get back to the original, you'll notice the transformation is (x,y) <- (x,2-y) (that is, if we transform each point above with this transformation, we get the original required mapping).
So, substituting it into the equation, we get (2-y)*4 + x.
Now this is specific to 3x3, but I'm sure you'll be able to generalize it by replacing 2 and 4 by variables.
If you want to reduce the dimension and avoid overlapping you need a space-filling-curve, for example a morton curve. Your example looks like a peano curve because it's a 3x3 matrix. These curves is difficult to calculate but have some nice things. But if you just look for self-avoiding curves you can create your own? Read here: http://www.fractalcurves.com/Root4Square.html.
I was beaten to the formula, here is the bruteforce using a Map.
public class MapPointToIndex {
private Map<Point, Integer> map;
private int index, rowcount;
public MapPointToIndex(int rows, int columns) {
map = new HashMap<Point, Integer>();
for (int i = rows - 1; i >= 0; i--) {
index += rowcount;
for (int j = 0; j < columns; j++) {
Point p = new Point(j, i);
map.put(p, index);
index++;
}
rowcount = 1;
}
}
public int getIndex(Point point){
return map.get(point);
}
public static void main(String[] args) {
MapPointToIndex one = new MapPointToIndex(3, 3);
System.out.println(one.map);
}
}
Out:
{java.awt.Point[x=0,y=0]=8, java.awt.Point[x=2,y=2]=2, java.awt.Point[x=1,y=2]=1, java.awt.Point[x=2,y=1]=6, java.awt.Point[x=1,y=1]=5, java.awt.Point[x=2,y=0]=10, java.awt.Point[x=0,y=2]=0, java.awt.Point[x=1,y=0]=9, java.awt.Point[x=0,y=1]=4}
Related
Let's say we have a 2D-boolean Array as a presentation of a maze, the size of the Array is not fixed and random. The walls are depicted as true:
boolean[][] mazeArray = new boolean[width][height];
The exit of the maze is at a fixed Index. How can I check wether the traversion has reached this certain index or not?
My idea was to create an int[ ] to keep track of the position, it gets updated and overwritten with every step:
int[] location = {1,0};
... But I don't understand why my check in the while-loop doesn't work:
while( location[0] != (maze[0].length-1) && location[1] != (maze[1].length-2) ) {
// traversion with pledge algorithm
}
You're making everything so much harder for yourself. Go easier ways.
Use simpler locations handling
Instead of a location[], simlpy use int destinyX and int destinyY. And as your current position, you should use int positionX and int positionY.
If you'd like the OO-stlye more, or maybe wanna keep the gates open for a solution in 3D or n-D, you could introduce a Location class that has X and Y, and all movement and checks could be handled by that class. Then you'd have Location targetLocation = new Location(x,y); and your current position as Location currentPosition = new Location(x,y);. You then could check with if (currentPosition.equals(targetLocation))...; or in your case while(!currentPosition.equals(targetLocation)) {...}
It seems you have misunderstood the array.length function, or you're using it in an awfully inconvenient way.
At the moment you're blindly shooting at the array lengths of maze[]. This is bad for 2 reasons:
array lengths should not have anything to do with positions inside the array (logical paradox), and
because you could never freely move your destination, it would always stick to the right or bottom outsides of the maze
Use the positioning above, this will clear up that problem.
Suggestion: use a byte[][] or enum[][] for maze
At the moment, you only know if you have a wall at a certain location. If you wanna include other elements, like water, treasure, or the target location, wormholes etc, then you should either:
Use a byte[][] and fill it with values
value 0 could be pathways
value 1 could be walls
value 2 could be the exit
value 3 could be the water etc.
Use constants, like static public final int WATER_CODE = 3;
Or, alternatively, create your own enum:
public enum LocationType {PATH, WALL,EXIT,WATER}
and then have maze be like:
LocationType[][] mazeArray = new LocationType[width][height];
and everything is PATH in the beginning, and you can set up WALLS like this:
mazeArray[x][y] = LocationType.WALL;
or water:
mazeArray[x][y] = LocationType.WATER;
Use class or interface for maze[][]
For the sake of Wormhole or extended functionality, you could also use a class instead of an enum:
abstract class LocationType {}
and then implement certain types, like
class Wall extends LocationType {}
or even
class Wormhole extends LocationType {
public Location leadsTo() { /* */ };
}
and
class Treasure extends LocationType {
public int getAmoundOfGoldCoinsFound() { /* */ };
}
If you implement LocationType as an interface, replace 'extends' by 'implements'
The problem with your code is that you check wrong items in your maze array:
maze[0] is the first "line" of your 2d-array
maze[1] is the second "line" of your 2d-array
Proper way of traversing 2d-array is following (I've replaced your location array with separate x and y variables to better visualize the algorithm).
My algorithm enters the 2d mazeArray line by line and then iterates each line's elements.
public class Maze {
public static void main(String[] args) {
int width = 20;
int height = 20;
boolean[][] mazeArray = new boolean[width][height];
int x = 0;
int y = 0;
while (y < mazeArray.length) {
while (x < mazeArray[y].length) {
System.out.println("Traverse at (" + x + ", " + y + ")");
x += 1;
}
x = 0;
y += 1;
}
}
}
I have an ArrayList of colors and their frequency of appearance. My program should calculate a reordering of those items that maximizes the minimum distance between two equal bricks.
For example, given input consisting of 4*brick 1 (x), 3*brick 2 (y), and 5*brick 3 (z), one correct output would be: z y x z x z y x z x y.
My code does not produce good solutions. In particular, sometimes there are 2 equal bricks at the end, which is the worst case.
import java.util.ArrayList;
import java.util.Collections;
public class Calc {
// private ArrayList<Wimpel> w = new ArrayList<Brick>();
private String bKette = "";
public String bestOrder(ArrayList<Brick> w) {
while (!w.isEmpty()) {
if (w.get(0).getFrequency() > 0) {
bChain += w.get(0).getColor() + "|";
Brick brick = new Wimpel(w.get(0).getVariant(), w.get(0).getFrequency() - 1);
w.remove(0);
w.add(brick);
// bestOrder(w);
} else {
w.remove(0);
}
bestOrder(w);
}
return bOrder;
}
public int Solutions(ArrayList<Wimpel> w) {
ArrayList<Brick> tmp = new ArrayList<Brick>(w);
int l = 1;
int counter = (int) w.stream().filter(c -> Collections.max(tmp).getFrequency() == c.getFrequency()).count();
l = (int) (fakultaet(counter) * fakultaet((tmp.size() - counter)));
return l;
}
public static long fakultaet(int n) {
return n == 0 ? 1 : n * fakultaet(n - 1);
}
}
How can make my code choose an optimal order?
We will not perform your exercise for you, but we will give you some advice.
Consider your current approach: it operates by filling the result string by cycling through the bricks, choosing one item from each brick in turn as long as any items remain in that brick. But this approach is certain to fail when one brick contains at least two items more than any other, because then only that brick remains at the end, and all its remaining items have to be inserted one after the other.
That is, the problem is not that your code is buggy per se, but rather that your whole strategy is incorrect for the problem. You need something different.
Now, consider the problem itself. Which items will appear at the shortest distance apart in a correct ordering? Those having the highest frequency, of course. And you can compute that minimum distance based on the frequency and total number of items.
Suppose you arrange these most-constrained items first, at the known best distance.
What's left to do at this point? Well, you potentially have some more bricks with lesser frequency, and some more slots in which to accommodate their items. If you ignore the occupied slots altogether, you can treat this as a smaller version of the same problem you had before.
I have created a gameboard (5x5) and I now want to decide when a move is legal as fast as possible. For example a piece at (0,0) wants to go to (1,1), is that legal? First I tried to find this out with computations but that seemed bothersome. I would like to hard-code the possible moves based on a position on the board and then iterate through all the possible moves to see if they match the destinations of the piece. I have problems getting this on paper. This is what I would like:
//game piece is at 0,0 now, decide if 1,1 is legal
Point destination = new Point(1,1);
destination.findIn(legalMoves[0][0]);
The first problem I face is that I don't know how to put a list of possible moves in an array at for example index [0][0]. This must be fairly obvious but I am stuck at this for some time. I would like to create an array in which there is a list of Point objects. So in semi-code: legalMoves[0][0] = {Point(1,1),Point(0,1),Point(1,0)}
I am not sure if this is efficient but it makes logically move sense than maybe [[1,1],[0,1],[1,0]] but I am not sold on this.
The second problem I have is that instead of creating the object at every start of the game with an instance variable legalMoves, I would rather have it read from disk. I think that it should be quicker this way? Is the serializable class the way to go?
My 3rd small problem is that for the 25 positions the legal moves are unbalanced. Some have 8 possible legal moves, others have 3. Maybe this is not a problem at all.
You are looking for a structure that will give you the candidate for a given point, i.e. Point -> List<Point>.
Typically, I would go for a Map<Point, List<Point>>.
You can initialise this structure statically at program start or dynamically when needing. For instance, here I use 2 helpers arrays that contains the possible translations from a point, and these will yield the neighbours of the point.
// (-1 1) (0 1) (1 1)
// (-1 0) (----) (1 0)
// (-1 -1) (0 -1) (1 -1)
// from (1 0) anti-clockwise:
static int[] xOffset = {1,1,0,-1,-1,-1,0,1};
static int[] yOffset = {0,1,1,1,0,-1,-1,-1};
The following Map contains the actual neighbours for a Point with a function that compute, store and return these neighbours. You can choose to initialise all neighbours in one pass, but given the small numbers, I would not think this a problem performance wise.
static Map<Point, List<Point>> neighbours = new HashMap<>();
static List<Point> getNeighbours(Point a) {
List<Point> nb = neighbours.get(a);
if (nb == null) {
nb = new ArrayList<>(xOffset.length); // size the list
for (int i=0; i < xOffset.length; i++) {
int x = a.getX() + xOffset[i];
int y = a.getY() + yOffset[i];
if (x>=0 && y>=0 && x < 5 && y < 5) {
nb.add(new Point(x, y));
}
}
neighbours.put(a, nb);
}
return nb;
}
Now checking a legal move is a matter of finding the point in the neighbours:
static boolean isLegalMove(Point from, Point to) {
boolean legal = false;
for (Point p : getNeighbours(from)) {
if (p.equals(to)) {
legal = true;
break;
}
}
return legal;
}
Note: the class Point must define equals() and hashCode() for the map to behave as expected.
The first problem I face is that I don't know how to put a list of possible moves in an array at for example index [0][0]
Since the board is 2D, and the number of legal moves could generally be more than one, you would end up with a 3D data structure:
Point legalMoves[][][] = new legalMoves[5][5][];
legalMoves[0][0] = new Point[] {Point(1,1),Point(0,1),Point(1,0)};
instead of creating the object at every start of the game with an instance variable legalMoves, I would rather have it read from disk. I think that it should be quicker this way? Is the serializable class the way to go?
This cannot be answered without profiling. I cannot imagine that computing legal moves of any kind for a 5x5 board could be so intense computationally as to justify any kind of additional I/O operation.
for the 25 positions the legal moves are unbalanced. Some have 8 possible legal moves, others have 3. Maybe this is not a problem at all.
This can be handled nicely with a 3D "jagged array" described above, so it is not a problem at all.
I have to fit a Gaussian curve to data points where 1 peak is expected. The data points can have an arbitrary offset in the y-direction.
I am using the org.apache.commons.math3 package. However, when creating a GaussianCurveFitter instance, it is only possible to pass the following initial guess values:
Normalization
Mean
Sigma
Right now I have come this far:
import org.apache.commons.math3.fitting.GaussianCurveFitter;
import org.apache.commons.math3.fitting.WeightedObservedPoints;
public void fitGaussian(double[] data) {
WeightedObservedPoints obs = new WeightedObservedPoints();
//add data points
for (int j = 0; j < data.length; j++) {
obs.add(j, data[j]);
}
//fit gaussian curve
double[] parameters = GaussianCurveFitter.create().fit(obs.toList());
}
Here the parameters contain above mentioned values (Normalization, Mean, Sigma).
Does anybody have an idea how I can also include the offset in y-direction as a free optimization parameter? Or maybe how to transform the original data points to suit the optimizer?
Thanks for the help!
Given a matrix filled in with all its values, there's the need of pulling out data randomly in order to create a random matrix (intialized with null values each position). The issue lies while checking if a position (within the randomMatrix) is different from null, as shown below:
public void randomLogic(String[][] givenMatrix){
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
int positioni = this.randInt(0, 1);
int positionj = this.randInt(0, 1);
int x = this.randInt(0, 3);
int y = this.randInt(0, 2);
/*In here lies the reported issue while checking if empty. */
while (!this.randomMatrix[x][y].isEmpty()) {
x = this.randInt(0, 3);
y = this.randInt(0, 2);
this.randomMatrix[x][y] = givenMatrix[positioni][positionj];
}
}
}
}
I've also tried with the following: while(this.randomMatrix[x][y] != null) and the code breaks down right away. All the solving-logic work out as expected (because if I ommit that part it works with flaws but works) the only problem is that validation. Regardless of what position is being evaluated it always stops working.
Is there any other way of checking a matrix position value?
are you trying to pull random values (and consequently, some will be repeated) from a givenMatrix OR do you want to specifically randomize the givenMatrix?
If it's the latter, I would approach it differently.
First of all, gather all values of the givenMatrix in one linear-array or list.
Then, you can randomize this array, and you'll be left with a big array of rows*columns items, with all the values from the original matrix already randomized.
Then, you can systematically fill the new randomized matrix, taking each element of the array in order, till you complete each row and column of the new matrix.
I would choose this approach, because it's easier, and it will finish in a fixed number of steps; rather than filling random positions, because maybe you land 2 times in the same place to fill, and you'll have to randomize until you hit all the spots.
(Also, if you don't care of repeating the values for the new matrix, then instead of taking each element of the randomized array, you can simply pick a random position of this array each time)
Have you declared String[][] randomMatrix as a class level member variable? If you have declared the randomMatrix correctly then the isEmpty() and != null checks should work.