I am using a 2D array to count its neighbors and update the current cell given its neighbor count.My count method (lifeCount= countAlive(copy,i,k)) is looking at the updated array instead of the original. I need it to keep looking at the original instead of the copy. I'd appreciate if anyone can help.
public static void UpdateMatrix(boolean original[][]) {
int lifeCount;
boolean[][] copy = (boolean[][]) original.clone(); //copy array
for (int i = 1; i < original.length - 1; i++) {
for (int k = 1; k < original[i].length - 1; k++) {
lifeCount= countAlive(copy,i,k);
System.out.println(lifeCount);
if (original[i][k] == true) {
if (lifeCount < 3 || lifeCount > 8) {
copy[i][k] = false;
}
}
if (original[i][k] == false) {
if (lifeCount >= 3 && lifeCount <= 8) {
copy[i][k] = true;
}
}
} /// matrix has updated
}
}// end findNeighborg
Related
It exists a 2 Dimensional Array for a field of (x,y) length, here for instance 9x6. What I need to do here is to check how many free fields are around the Orange and Red Star. The black (filled) fields represent the occupied fields. In this example for instance I have 7 free fields for Orange, 1 for Red. I know that I can loop through each field and see whether one field is occupied or not, but how could I loop through so that I know that these non-occupied fields are next to the Star or in the Radius of the Star of non-occupied fields? I hope I could elaborate my question well.
Field[][] fields = new Field[9][6];
private void checkEmptyFields(Star star) {
for (int i = 0; i < 9; i++){ // Hardcoded size as an example
for (int j = 0; i < 6; i++) {
if(fields[i][j].isOccupied())
{
//It is occupied, but what now?
}
}
}
}
isOccupied Function:
public boolean isOccupied(){
return occupied;
}
I expect the output to be in this example Orange: 7, Red: 1 (because Red is blocked by the Orange Star and the occupied boxes)
This seems like a problem where breadth-first-search is the appropriate algorithm to use here. Breadth-first-search, or BFS, is when you visit all of a node's, or in this case fields', neighbors first. In your case, "visiting", will just mean checking if it's occupied or not. If it the neighboring field is not occupied and hasn't been visited before, then you can search that field and it's neighbors. The order in which you search is determined by using a Queue-like data structure like so,
private void checkEmptyFields(Star star) {
boolean visited[9][6] = new visited[9][6];
//get the star's coordinates somehow, you may have to change this
int i = star.row;
int j = star.col;
visited[i][j] = true;
int freeFieldCount = 0;
Queue<Field> q = new LinkedList<Field>();
q.add(fields[i][j]);
while(!q.isEmpty()) {
Field current = q.poll();
//get the coordinates from the field, you may have to change this
i = current.row;
j = current.col;
int rowUpperLimit = i + 1;
int rowLowerLimit = i - 1;
int colUpperLimit = j + 1;
int colLowerLimit = j - 1;
if(rowUpperLimit >= 9) {
rowUpperLimit = 8;
}
if(rowLowerLimit < 0) {
rowLowerLimit = 0;
}
if(colUpperLimit >= 6) {
colUpperLimit = 5;
}
if(colLowerLimit < 0) {
colUpperLimit = 0;
}
//check immediate neighbors
for(int m = rowLowerLimit; m <= rowUpperLimit; m++) {
for(int n = colLowerLimit; n <= colUpperLimit; n++) {
if((m != i && n != j) && !visited[m][n] && !fields[m][n].isOccupied()) {
freeFieldCount++;
visited[m][n] = true;
q.add(fields[m][n]);
}
}
}
}
return freeFieldCount;
}
As user #juvian mentioned, this is an 8-neighbor approach. If you want to do a 4-neighbor approach, simply visit only the neighbors immediately to the left, right, above, or below the current field. You can modify the while loop like so,
while(!q.isEmpty()) {
Field current = q.poll();
//get the coordinates from the field, you may have to change this
i = current.row;
j = current.col;
int rowUpperLimit = i + 1;
int rowLowerLimit = i - 1;
int colUpperLimit = j + 1;
int colLowerLimit = j - 1;
if(colLowerLimit > -1) {
//check neighbor to the left
if(!visited[i][colLowerLimit] && !fields[i][colLowerLimit].isOccupied()) {
freeFieldCount++;
visited[i][colLowerLimit] = true;
q.add(fields[i][colLowerLimit]);
}
}
if(colUpperLimit < 6) {
//check neighbor to the right
if(!visited[i][colUpperLimit] && !fields[i][colUpperLimit].isOccupied()) {
freeFieldCount++;
visited[i][colUpperLimit] = true;
q.add(fields[i][colUpperLimit]);
}
}
if(rowLowerLimit > -1) {
//check neighbor below
if(!visited[rowLowerLimit][j] && !fields[rowLowerLimit][j].isOccupied()) {
freeFieldCount++;
visited[rowLowerLimit][j] = true;
q.add(fields[rowLowerLimit][j]);
}
}
if(rowUpperLimit < 9) {
//check neighbor above
if(!visited[rowUpperLimit][j] && !fields[rowUpperLimit][j].isOccupied()) {
freeFieldCount++;
visited[rowUpperLimit][j] = true;
q.add(fields[rowUpperLimit][j]);
}
}
}
}
I am attempting to make a random maze generator using Java and the recursive backtracking algorithm. I am getting stack overflow when I try to run this code. I know some about stack, I don't think this is infinite recursion. My guess is that I have a big logic error. Do I have to allocate more memory?
The stack trace:
Exception in thread "main" java.lang.StackOverflowError
at java.base/java.util.Vector.elementAt(Vector.java:499)
at java.base/java.util.Stack.peek(Stack.java:103)
at java.base/java.util.Stack.pop(Stack.java:84)
at mazeMaker.Maze.generateMaze(Maze.java:115)
at mazeMaker.Maze.generateMaze(Maze.java:115)
...
at mazeMaker.Maze.generateMaze(Maze.java:115)
at mazeMaker.Maze.generateMaze(Maze.java:115)
Main.java
package mazeMaker;
public class Main
{
public static void main(String[] args)
{
Maze mainMaze = new Maze(20, 30);
}
}
Maze.java
package mazeMaker;
import java.util.Random;
import java.util.Stack;
public class Maze
{
public int xSize = 0;
public int ySize = 0;
public int totalDimensions = 0;
Random randomGenerator = new Random();
public Cell[][] cellData;
public Stack<Cell> cellStack = new Stack<Cell>();
Cell tempCell; // Temporary variable used for maze generation
public Maze(int xSize, int ySize)
{
cellData = new Cell[xSize][ySize];
this.xSize = xSize;
this.ySize = ySize;
this.totalDimensions = this.xSize * this.ySize;
// Initialize array objects
for (int i = 0; i < this.xSize; i++)
{
for (int j = 0; j < this.ySize; j++)
{
cellData[i][j] = new Cell();
}
}
// Assign x and y positions
for (int i = 0; i < this.xSize; i++)
{
for (int j = 0; j < this.ySize; j++)
{
cellData[i][j].xPos = i;
cellData[i][j].yPos = j;
}
}
initBoundries();
generateMaze();
}
private void initBoundries()
{
// Initialize the border cells as visited so we don't go out of bounds
int m = this.xSize;
int n = this.ySize;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (i == 0 || j == 0 || i == n - 1 || j == n - 1)
cellData[i][j].hasBeenVisited = true;
}
}
}
private void generateMaze(int x, int y)
{
// Set current cell as visited
cellData[x][y].hasBeenVisited = true;
// While there are unvisited neighbors
while (!cellData[x][y+1].hasBeenVisited || !cellData[x+1][y].hasBeenVisited || !cellData[x][y-1].hasBeenVisited || !cellData[x-1][y].hasBeenVisited)
{
// Select a random neighbor
while (true)
{
int r = randomGenerator.nextInt(4);
if (r == 0 && !cellData[x][y+1].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasNorthWall = false;
cellData[x][y+1].hasSouthWall = false;
generateMaze(x, y + 1);
break;
}
else if (r == 1 && !cellData[x+1][y].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasEastWall = false;
cellData[x+1][y].hasWestWall = false;
generateMaze(x+1, y);
break;
}
else if (r == 2 && !cellData[x][y-1].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasSouthWall = false;
cellData[x][y-1].hasNorthWall = false;
generateMaze(x, y-1);
break;
}
else if (r == 3 && !cellData[x-1][y].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasWestWall = false;
cellData[x-1][y].hasEastWall = false;
generateMaze(x-1, y);
break;
}
}
}
// There are no unvisited neighbors
tempCell = cellStack.pop();
generateMaze(tempCell.xPos, tempCell.yPos);
}
// Begin generating maze at top left corner
private void generateMaze()
{
generateMaze(1,1);
}
}
Cell.java
package mazeMaker;
public class Cell
{
public boolean isCurrentCell;
public boolean hasBeenVisited;
public boolean hasNorthWall;
public boolean hasSouthWall;
public boolean hasEastWall;
public boolean hasWestWall;
public int xPos;
public int yPos;
}
The method generateMaze can never terminate not even by chance for some simple reason:
For terminating the generateMaze method would need to finish it's execution - it has to return.
There are no return statements in this method, therefore it has to pass the while loops and then continue until the execution reaches and finishes the last statement of the method.
However the last statement is generateMaze(tempCell.xPos, tempCell.yPos); which starts a new recursion, therefore your code can never ever terminate!
I tried to run your project on my own environment but unfortunately, I was not able to reproduce your issue.
However, I was facing an IndexOutOfBound exception in the method generateMaze. While I was solving this, I figured out that there was an issue in the initBoudaries method.
Indeed, when you set the boolean hasBeenVisited to true, you do not use the right variable in the IF clause. Here is the version I tried instead :
private void initBoundries()
{
// Initialize the border cells as visited so we don't go out of bounds
for (int i = 0; i < this.xSize; i++)
{
for (int j = 0; j < ySize; j++)
{
if (i == 0 || j == 0 || i == xSize - 1 || j == ySize - 1)
cellData[i][j].hasBeenVisited = true;
}
}
}
Now about the emptyStackException, I think that if this stack is empty, this means that there is no more cell to handle (as you mentioned in your comment) and the program must end. If I am right, just make sure to test if your stack is empty before call the method pop() on it like this :
// There are no unvisited neighbors
if (!cellStack.isEmpty()) {
tempCell = cellStack.pop();
generateMaze(tempCell.xPos, tempCell.yPos);
}
Hope it will help.
I am writing a bin packing program in one dimension. I want only one possible bin. So it does not include a lot of bin its only one. This program is only searching quad groups and explode if quad groups are not equal to the searching number. I want to search every possible group that is bigger than quads.
In example we have 60 60 50 40 45 35 25 15 and we are looking for summing equal to 180 and answer is 60 60 45 15 that's fine but if we search 250 it will not working.
Can you help me?
That's the link for program https://github.com/omerbguclu/BinPacking1D
That's the code for the algorithm o array is the numbers, a array is the location of answers
public BinPacking() {
}
public void binpack(ArrayList<Integer> o, ArrayList<Integer> a, int wanted) {
int sum = 0;
if (wanted > 0) {
control(o, a, wanted);
if (is) {
return;
}
for (int i = 0; i < o.size(); i++) {
sum += o.get(i);
summing(o, a, wanted - sum, i + 1);
if (is) {
a.add(i);
return;
}
for (int j = i; j < o.size(); j++) {
if (i != j) {
sum += o.get(j);
summing(o, a, wanted - sum, j + 1);
if (is) {
a.add(i);
a.add(j);
return;
}
sum -= o.get(j);
}
}
sum -= o.get(i);
// "/////////////*******************////////////////////");
}
if (wanted != sum) {
System.out.println("There is not an answer with quad summing method");
}
}
}
public void summing(ArrayList<Integer> o, ArrayList<Integer> a, int wanted, int loop) {
int sum = 0;
if (loop < o.size() && wanted > 0) {
for (int i = loop; i < o.size(); i++) {
if (wanted == o.get(i)) {
a.add(i);
is = true;
return;
}
for (int j = loop; j < o.size(); j++) {
if (i != j) {
sum = o.get(i) + o.get(j);
if (wanted != sum) {
sum = 0;
} else {
a.add(i);
a.add(j);
is = true;
return;
}
}
// System.out.println("///////////////////////////////////");
}
}
System.out.println("There is not an answer with binary summing method");
}
}
public void control(ArrayList<Integer> o, ArrayList<Integer> a, int wanted) {
for (int i = 0; i < o.size(); i++) {
if (o.get(i) == wanted) {
a.add(i);
is = true;
break;
}
}
}
There is a pretty well established and efficient mechanism for getting every possible combination of a set of objects. Essentially you treat membership of the combination as a BitSet which represents whether each member of the set is in the combination. Then visiting every combination is just visiting every BitSet combination.
Here's how I tend to implement it:
public class Combo<T> implements Iterable<List<T>> {
private final List<T> set;
public Combo(List<T> set) {
this.set = set;
}
public Iterator<List<T>> iterator() {
BitSet combo = new BitSet(set.size());
return new Iterator<List<T>>() {
public boolean hasNext() {
return combo.cardinality() < set.size();
}
public List<T> next() {
int i = 0;
while (combo.get(i))
combo.clear(i++);
combo.set(i);
return combo.stream().mapToObj(set::get).collect(Collectors.toList());
}
};
}
}
So your solution would become:
for (List<Integer> combo: new Combo<>(...)) {
if (combo.size >= 4 && combo.stream.reduce(0, Integer::sum) == total)
....
}
A hackier version of the same idea would be:
for (long l = 0; l < 1 << (input.size() - 1); l++) {
List<Integer> combo = BitSet.valueOf(new long[]{l}).stream()
.mapToObj(input::get).collect(Collectors.toList());
if (combo.stream().mapToInt(n -> n).sum() == total) {
System.out.println(combo);
}
}
I am a 2nd year CS student and trying to fix a simple method. The logic is fairly easy but somehow I still get an error although I don't know what's wrong here.
The problem :
The beginning of the class:
private Integer dt[];
private int size;
IntManager(int k){
dt = new Integer[k];
size = 0;
}
The method inside the class:
public Integer max(){
//return largest value in dt; null if size == 0
if (size == 0) return null;
else{
Integer biggest = dt[0];//trouble here; changing to int won't help & var name also
for (int j = 0; j < size ; j++) {
if (dt[j] < biggest) biggest = dt[j];
}
}
return biggest;
}
Main class:
IntManager num = new IntManager(100);
for (int j = 0; j < 20 ; j++) {
int x = (int)(Math.random()*10);
num.add(x);
}
num.add(57);
System.out.println(num);
System.out.println(num.found(5));//Ignore this
System.out.println(num.max());
Your biggest variable is defined inside the ifelse scope therefore is not visible outside of that segment
declare the Integer as a hole method variable...
Example:
public Integer max(){
Integer biggest=null;
if (size != 0) {
Integer biggest = dt[0];
for (int j = 0; j < size ; j++) {
if (dt[j] < biggest) biggest = dt[j];
}
}
return biggest;
}
The problem is with your blocks
public Integer max(){
//return largest value in dt; null if size == 0
if (size == 0) return null;
else{
Integer biggest = dt[0];//trouble here; changing to int won't help & var name also
for (int j = 0; j < size ; j++) {
if (dt[j] < biggest) biggest = dt[j];
}
}
return biggest;
}
You're declaring biggest within the scope of that else block, so it is not visible when you reach your return statement. To correct it you should have something like:
public Integer max(){
//return largest value in dt; null if size == 0
Integer biggest = dt[0]
if (size == 0) return null;
else{
;//trouble here; changing to int won't help & var name also
for (int j = 0; j < size ; j++) {
if (dt[j] < biggest) biggest = dt[j];
}
}
return biggest;
}
I have two Arrays 1 with strings and another one with ints.
I have to use insertion sorts to print this list in acceding order numerical wise this is my code so far
these are the arrays:
String[]bn={"Cardinals","BlueJays","Albatross","Vultures","Crows","Mockingbirds","Condors","BaldEagles","Pigeons","RedHeadWoodPecker","Hummingbirds","Dodos"};
int[]bq={40,15,1,3,10,2,12,25,7,6,88,15};
public static void SortNumericalOrdernsert (String[] bn,int[] bq){
for(int i=1;i<bq.length;i++){
int next=bq[i];
String y=bn[i];
//find all the insertion location
//Move all the larger elements up
int j=i;
while(j>0 && bq[j-1]>next){
bn[j]=bn[j-1];
bq[j]=bq[j-1];
j--;
}
//insert the element
bq[j]=next;
bn[j]=y;
}
}}
Where am i doing it wrong?
// edited
You want to do like this?
public static void SortNumericalOrdernsert(String[] bn, int[] bq) {
for (int i = 1; i < bq.length; i++) {
int next = bq[i];
// find all the insertion location
// Move all the larger elements up
int j = i;
while (j > 0 && bq[j - 1] > next) {
bq[j] = bq[j - 1];
j--;
}
bq[j] = next;
}
for (int i = 1; i < bn.length; i++) {
String y = bn[i];
int j = i;
while (j > 0 && isBigger(bn[j - 1], y)) {
bn[j] = bn[j - 1];
j--;
}
bn[j] = y;
}
}
private static boolean isBigger(String left, String right) {
return left.compareTo(right) > 0;
}