Trouble with multidimensional arrays - java

For my homework, I need to represents cells in a universe where ' * ' indicates a live cell and an empty space (' ') a dead cell. The following rules are used to determine the status of a particular cell in the next generations:
Any live cell with fewer than two live neighbors dies, as if caused by under population.
Any live cell with two or three live neighbors lives on to the next generation.
Any live cell with more than three live neighbors dies, as if caused by overpopulation.
Any dead cell with exactly three live neighbors becomes a live cell, as if caused by reproduction.
For example, considering the following arrays:
int[][] beehive = {{0,0,0,0,0,0}, {0,0,1,1,0,0}, {0,1,0,0,1,0},
{0,0,1,1,0,0}, {0,0,0,0,0,0}};
int[][] toad = {{0,0,0,0,0,0}, {0,0,1,1,1,0}, {0,1,1,1,0,0}, {0,0,0,0,0,0}};
getNextGenCell(beehive, 1, 3) returns 1, while getNextGenCell(beehive, 3, 1)
returns 0.
getNextGenCell(toad, 0, 3) returns 1, while getNextGenCell(toad, 2, 3)
returns 0.
I am confused on how to proceed with this code. Any suggestion?
My code has to have the following header where int x represents a sub-array and int y represents an element inside that sub-array. The code returns 1 if the cell is alive in the next generation or 0, otherwise.
// A method that gets the cell from the next generation
public static int getNextGenCell(int[][] validUniverse, int x, int y) {
}

You first must determine how you want the logic of your program to flow. In this case, you know there are 8 different cases when traversing the 2D array. These include:
The upper left-hand corner
The upper right-hand corner
The rest of the first row
The lower left-hand corner
The lower right-hand corner
The rest of the last row
The left and right-hand sides of the array
The rest of the array
You will need if statements for each of these cases. The following is an an example of the code for "the rest of the array" case:
if(x!=0&&y!=0&&x!=bees.length-1&&y!=bees[x].length-1&&bees[x][y+1]==1||bees[x][y-1]==1||bees[x+1][y]==1||bees[x-1][y]==1)
Now just finish the other 7 cases, count the amount of "alive" or "dead" cells and modify the array accordingly. Let me know if you have any questions.

Related

How do I find the optimal path through a grid?

Overview of the problem: You are a truffle collector, and are given a grid of numbers representing plots of land with truffles on them. Each plot has a certain number of truffles on it. You must find the optimal path from the top of the grid to the bottom (the one that collects the most truffles). Importantly, you can start from any cell in the top row. When you are at a cell, you can move diagonally down to the left, directly down, or diagonally down to the right. A truffle field might look like this:
The truffle fields also do not have to be square. They can have any dimensions.
So, I have created an iterative algorithm for this problem. Essentially, what I have done is iterate through each cell in the top row, finding the greedy path emanating from each and choosing the one with the largest truffle yield. To elaborate, the greedy path is one in which at every step, the largest value that can be reached in the next row from the current cell is chosen.
This algorithm yields the correct result for some truffle fields, like the one above, but it fails on fields like this:
This is because when the algorithm hits the 100 in the third column, it will go directly down to the 3 because it is the largest immediate value it can move to, but it does not consider that moving to the 2 to the left of it will enable it to reach another 100. The optimal path through this field obviously involves both cells with a value of 100, but the greedy algorithm I have now will never yield this path.
So, I have a hunch that the correct algorithm for this problem involves recursion, likely recursive backtracking in particular, but I am not sure how to approach creating a recursive algorithm to solve it. I have always struggled with recursion and find it difficult to come up with algorithms using it. I would really appreciate any ideas you all could provide.
Here is the code. My algorithm is being executed in the findPath method: https://github.com/jhould007/Programming-Assignment-3/blob/master/Truffle.java.
You could use recursion, but there's a simple iterative fix to your approach as well.
Instead of the top row, start with the bottom one. Create a 1D array values and initialise it with the values of the bottom row.
Start iterating curr_row from row max_row-1 to 0. For each iteration, create a temporary array temp and initialise it with 0's.
For a row curr_row in the iteration, value[i] represents the max value that you can get if you start from row curr_row+1 (basically the next row) and column i.
To update temp in each iteration, we just need to pick the best path from the next row, which can be fetched from values array.
for column in range [0, max_column]:
temp[column] = truffle_value[column] + max(value[column], value[column+1], value[column-1])
// since temp holds the values for the next iteration in our loop
value = temp
In the end, the answer will simply be max(values).

Noise generation: 'Room Noise'

Last weeks I was developing a world generator (for a Minecraft mod). However, I wasn't looking for just Perlin noise, but rather something based on cell noise. I want to generate a sort of underground lab, existing of several rooms of different sizes.
To explain the problem I use 2D examples.
The noise generator takes a grid cell position (int x, int y), and returns an object with this stucture:
boolean top;
boolean right;
boolean down;
boolean left;
int roomType;
The 4 booleans represent the walls which are enabled or disabled:
The roomType represents the type of the room respectively.
The final result should be something like this:
Here, the background checkerboard pattern represents the base grid, and the black lines represent the walls. This is just a simple example that could generate, but in the real case, the grid is infinite in both x and y directions.
The problem I'm getting now is that the noise generator only takes in an x and y coordinate, which is the coordinate of the grid cell it should generate. There is a seed of which I can generate more random seeds for hash functions:
long seed = 0x75fd239de48;
Random r = new Random(seed);
int seed1 = r.nextInt();
int seed2 = r.nextInt();
// etc.
I could use a hash function: Hash.hash2D(int seed, int x, int y), which returns a random double for a coordinate, according to a seed.
That will give the ability to generate information for the surrounding cells.
To easily generate larger rooms, you could set a max size for a room, and check an area for rooms that try to be larger than 1x1. If they are there, and will span to the current room, the room will be an extension of another room. However, checking if a room will extend requires a check if it isn't already extending (otherwise, unwanted room extensions appear to room bases that extend another), which runs into an infinite loop.
In my case, there is a given table of room types, their sizes and their weights. Example:
name: size [weight]
room-1: 1x1 [128]
room-2: 1x1 [128]
room-3: 2x1 [16]
room-4: 1x2 [16]
room-5: 2x2 [8]
room-6: 3x1 [4]
room-7: 1x3 [4]
There are many others, coming with sizes up to 5x5, but I use this example list for my question. The max size in this example is 3x3 (just max-width by max-height).
Here I have an example class of some basic setup in Java:
public class RoomNoise {
private final long seed;
private final Random rand;
public RoomNoise( long seed ) {
this.seed = seed;
this.rand = new Random( seed );
}
public enum RoomTypes {
ROOM1( 1, 1, 128 ),
ROOM2( 1, 1, 128 ),
ROOM3( 2, 1, 16 ),
ROOM4( 1, 2, 16 ),
ROOM5( 2, 2, 8 ),
ROOM6( 1, 3, 4 ),
ROOM7( 3, 1, 4 );
public final int width;
public final int height;
public final int weight;
private RoomTypes( int w, int h, int weight ) {
width = w;
height = h;
this.weight = weight;
}
}
public static class Output {
public final RoomTypes roomType;
public final boolean upWall;
public final boolean rightWall;
public final boolean downWall;
public final boolean leftWall;
public Output( RoomTypes type, boolean u, boolean r, boolean d, boolean l ) {
roomType = type;
upWall = u;
rightWall = r;
downWall = d;
leftWall = l;
}
}
public Output generate( int x, int y ) {
// What should be here
}
}
I'm looking for the content of the generate method, for which I've tried many things, but every time I turned into an infinite loop or it didn't work.
Is there any way to generate this noise in O(N) with N less than infinity? And if there is a way, which way is that and how could I implement it? I've searched the internet and tried many things (for 3 weeks now) and still haven't found a solution.
I use Java 1.8, but I prefer any C-style language.
Again, I have this hash function:
Hash.hash2D( int seed, int x, int y );
Edit:
Expected result:
Blue lines are corridors, which are generated later on. Just forget them.
Note:
I'm not able to load and delete chunks (grid cells) manually, the base API (Minecraft) is doing that for me. It only gives me the coordinate (which depends on the player interaction) and I should give back a (part of a) room that fits the chunk at that coordinate. I also know that once a chunk is generated, it isn't generated again.
I'm not sure I perfectly understand the problem you're trying to solve, so please feel free to comment if this is short of the mark:
If you want to be able to generate an infinite grid, you're only going to be able to approximate infinite. I think you have two options:
Generate a "big enough" grid. This might be time / space intensive, but if there's an upper bound on how much you could need, and it's feasible to do it all at once, it's the simplest option. E.g. if the user couldn't possibly make it more than 1000 squares away from the center, generate 2000x2000.
OR:
Use lazy evaluation. This means, don't generate anything until you need it. If the user gets close to an area that has not yet been generated, generate it then. The flip side to this is you can also throw away old parts that the user isn't likely to return to, if you need to free up resources. For example: cut your area into squares (e.g. 20x20 or 1000x1000), and generate additional, adjacent squares, as the player gets close to them, or the map pans over in that direction, etc., as needed.
Ok, I think I've solved it myself.
This is the grid, not infinite here but it could be.
In this grid you have some cells that want to extend. This is directly defined by the hash function:
However, some extensions do overlap others. This is something we don't know actually.
Take for each cell a priority. You could do that in several ways:
Just use the hash function to give them a random priority
Give each possible room type / size a priority (e.g. larger rooms have higher priority).
The priority is only important on cells that want to extend. In my example, the bigger cells have higher priority.
Then we have the input coordinate, which is the blue cell:
Ok, knowing this, you have to do some steps. We know the maximum size is 3x3.
If the input cell doesn't want to extend
Check in the area of the maximum size if there is any cell that tries to extend to this cell:In this case it exists.
Knowing this, we need to check if one of the found cells could extend to this cell. To check that, check if this wants this cell to be an extension, then do the steps below and take the check cell as input coordinate. In the example, the extending cell is able to extend. We also know the extending cell will extend the input cell so the input cell is an extension.
Now we could easily check which walls exist and which not. In this case, every wall is gone because it is the center of this extending room:
Some other examples:
Input coordinates. None of them wants extension:
Check regions:
As you can see, one cell found an extension room, but that extension room doesn't extend that input cell. That makes all those rooms a 1x1 room:
If the input cell wants to extend
And how to check if a cell can extend
Do a hard check. The hard check checks the area of the extension (3x3 in this case) size right below the input cell for other cells trying to extend. If there is one, check if that one could extend. If it could, the input cell couldn't extend and go on with the steps for non-extending cells on your input cell. To save memory and time, you could skip checking if the found cells could extend (maybe this will run into an infinite loop), and just take an 1x1 cell directly (non-extending cell steps are not necessary then).
This is the extension area / hard check area in this case. There is no extending cell here so the cell could extend.
Now do a soft check. The soft check checks for extending cells in the maximum size area left below, and right above the cell:
Also here, you could check if they do extend, but that takes much memory and time.
For each found cell, check in their extension area right below them if they will extend to any of the extension cells the input cell will extend. This check if the two extension areas overlap. If they don't, your cell is able to extend and you could skip step 3 and go to step 4. If they do, go to step 3. In this case an overlap is found:
Here, the yellow cell with red outline is a found overlap.
You've found an overlap. Here the priority is going to play a role. Take the priority of the extension cell which area does overlap the input cell area. Also take the priority of the input cell itself. Compare them. If the priority of the input cell is larger that the other priority, the input cell can extend and you could go to step 4. If the input cell has lower priority, it couldn't extend and you could make it a 1x1 room (or you could do the non-extending cell steps, which is necessary if you validate found cells in the hard check). If the priorities are equal, take the cell with the highest X or Y coordinate, or something.
In my example, the input cell has the highest priority, because it is bigger.
The final step. The cell is guaranteed to extend. You could calculate which walls exist. Notice that the left and the top wall always exist, as the extension cells are always in the top left corner.
Our cell could extend and we get this result:
Another example
The input cell:
Do the hard check:
Oh, it found one, so it couldn't extend and turns into a 1x1 room:
That's it, actually. I hope I've been clear enough. Rather than using squares, you could use rectangles too, or more complex shapes like L-shaped rooms.
And this is the final result of my example:

Find shape within rows of characters-Java

I came across to problem on thinking how to get the shape from the rows of characters, for example given this input:
AAAAAAAA
ABBBAABA
ABABABBB
ABBBAAAA
AAAABBAA
ABBABBAA
ABBABBAA
ABAABBAA
Task:
Calculate how many shapes are there formed by horizontally or vertically adjacent 'B' letters.
In this example there are 4 such shapes.
It might be easier to see if I remove the 'A's:
BBB B
B B BBB
BBB
BB
BB BB
BB BB
B BB
Additional task:
How many 'B' characters are in each shape?
In this example: 8, 4, 5, 8 (not in any particular order).
I am still new to Java, so I want to ask is there is any java function that can check the same occurrence that near to each other in order to count the shape appears? Hope you can give me some pointer on how to construct this algorithm.
(I have thought of taking each index of 'B' and check whether they are near to other 'B' but I get stuck)
I am still new to Java, so I want to ask is there is any java function that can check the same occurrence that near to each other in order to count the shape appears?
No, there is no built-in functionality to make this very easy.
And that's the point of the exercise.
Here are some example approaches you could use to solve this problem:
Flood fill:
Convert the input to a matrix. It could be a boolean[][] where you set true where the input is B.
Iterate over the values in the matrix, skipping false values.
When you find a true value, initiate the flood fill:
Increment the count of shapes (you found a new shape)
Recursively replace all adjacent true values with false, incrementing shapeSize count as you go
When all true neighbors (and neighbors of neighbors, and so on) are replaced with false, the shape is fully explored
Continue the iteration where you left off, until you find another true value
Graph theory: find connected components
Convert the input to an undirected graph:
The index of each character can be the vertex id
Create a connection for adjacent pairs of B in the input
Iterate over the vertices of the graph
If a vertex doesn't have yet a component id, use depth-first search to find all the vertices connected to it, assign to all vertices the next component id, incrementing the componentSize count as you go
When there are no more connected vertices, the shape is fully explored
Continue the iteration where you left off, until you find another vertex with no component id
Union find: this is similar to finding the connected components
Method indexof(int ch) returns first index of apearing character in a String. you should cut each string after getting index of first B.
Or you can use indexOf(int ch, int fromIndex) that returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.
int indexCount = 0;
ArrayList<Integer> list = new ArrayList<Integer>();
for(int a = 0; a < count; a++) {
indexCount = array[a].indexOf('B');
list.add(indexCount);
}
System.out.println(list);

efficient algorithm to check if there exists a row and a column with same values?

I am trying to solve this problem using the least running time.
If we're given a 2D array, we need to return x if there exists a row where all values equal x, and there is a column where all values equal x.
For example, for the following 2d array,
0 3 1
2 3 1
1 1 1
we are supposed to return 1 since the last row and last column are all of same value 1. If no such number exists, we can return -1.
I know there are many ways to solve the problem and most of them are of O(n^2), I'm wondering if there is an efficient way(i.e O(n)) to find such value. (where n represents the number of cells in this array)
Ok, you clarified that you consider O(n) to be the number of values in the 2D array.
I'll outline the approach in pseudo-code, which you can translate to either Java or C++, whichever is your preference. Your question is tagged with both, and the pseudocode is trivial enough to be directly translatable into either C++ or Java. Or Perl. Or Python...
Part 1
Let's start with the first, easy step, how to check whether there's any row that contains the same value. The pseudocode for this is elementary:
start with the 0th row, n=0
check if matrix[n][0] through [n][m-1] (where m is the number of columns in the matrix) contain the same value. If so, you found it.
otherwise, increment n, to go to the next row, until you reach the bottom of the matrix.
You should be able to understand that. This is basic, elementary "Computer Science 101" stuff.
Part 2
Now, let's modify this pseudocode to simultaneously check the columns as well. Modify the above pseudocode as follows.
Create two one-dimensional vectors, call the first one top_values, or something, whose size is m, the number of columns in your matrix. Call the second one flags, it's a vector of boolean flags, also their size is m.
When you scan the 0th row, in the pseudocode given in the first part, copy the values from the 0th row, into top_values. That is, copy matrix[0][x] into top_values[x]. Also set flags[x] to true (you can initialize all flags to true even before you scan the 0th row, it doesn't matter).
When you scan each one of the remaining rows, using the pseudocode given in Part 1, compare matrix[y][x] (where y is the row# you're scanning) against top_values[x]. If they are not the same, set flags[x] to false.
At the end of the pseudocode from part 1, check your flags vector. If any value in it is still true, there's a column in your matrix whose values are the same.
Your homework assignment is to make a slight tweak to the above pseudocode to also tell you which value is the same, in some row or column.

Find available "number" in a 2d array

I have this problem that I need to solve in the most effecient way.
I have a 2d array that contains the following:
Everything that is a 1 is a "wall" which means you cannot go through it. 2 is the entrance where you "enter" the array or map if you like. 3 are the things we need to find. Here is an example of a map:
1111111
1 3131
2 11111
1 31
1111111
This could be an example of an array that i need to look in. As you can see there is a 3 that is "unreachable, since it's surrounded by a wall "1". Which means that there are two available numbers in this array.
First we need to find the entrance. Since the entrance can be anywhere I need to search the entire array. I have done the following:
int treasureAmount = 0;
Point entrance = new Point(0,0);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; i++){
if(map[i][j] == 2){
entrance.x =i;
entrance.y =j;
}
}
This takes O(n^2) time, and i don't really see another way to do this, since the entrance can be anywhere.
However i'm not really sure how to find the available numbers effectivly and fast. I thought about while searching the arrays for the entrance i will at the same time find the all the number 3 in the array even though some might not be accessible, and after that i'm not really sure how to effectivly find which are accessible.
You cannot do it better that O(n^2). It will take that much time just to read the array. But then you could do a depth first search to find the reachable 3's in the array. Here is the pseudo code.
main()
{
read array and mark the entrance as ent.x and ent.y and also an array threex[] and threey[] that stores all the exit position.
boolean visited[][]; //stores whether array[i][j] is reachable or not.
dfs(ent.x,ent.y);
for each element in three arrays
{
if(visited[threex[i]][threey[i]]) print ("Reachable");
else print("not reachable", threex[i], threey[i]);
}
}
int dx[]={1,0,-1,0},dy[]={0,1,0,-1}; // dx[i], dy[i] tells whether to move in E,N,W,S respectively.
dfs(int x,int y)
{
visited[x][y]=true;
for(i=0;i<4;i++)//move in all directions
{
int newx=x+dx[i],newy=y+dy[i];
//check if this is within the array boundary
if(newx>=0&&newx<N && newy>=0&&newy<N)
if(!visited[newx][newy] && array[newx][newy]!=1) // check if the node is unvisited and that it is pemissible
dfs(newx,newy);
}
}
Since each array element is taken up not more than once in the dfs function the complexity of the code is O(n^2).
When creating the array, you can keep a list of coordinates of that have the value of 2. You can traverse that list in O(n).
Since both entrance and target items can be anywhere in the array you don't have much choice, but to search everything. So, your entrance search is as efficient as it can be, and regarding the target items I recommend the maze flood fill algorithm.
However, the linked version of the algorithm favorizes one direction (like it is filling it with water, it floods "down"). To be as efficient as it can, you should make it expand in all directions (like you're filling it with gas), e.g.:
2
1 212
0 101 21012
1 212
2
The numbers represent the iterations of expansion. The expansion is made in four directions: left, right, up and down. When you reach the target item, you can find the shortest route simply by backtracking to the adjacent cell neighbour whose iteration index is lesser by one, until you return to the 0 iteration index - the entrance.

Categories

Resources