I would like to resolve a problem for my homework. I have to multiply an array by itself using a method in Java that I created. However, my method doesn't work and I don't know why.
public static void initialiser(int mat[][]) {
int i,j;
for (i = 0; i < mat.length; i++) {
for(j = 0; j < mat[0].length; j++) {
mat[i][j] = 0;
}
}
}
public static int[][] produit(int mat1[][], int mat2[][]) {
int i,j,k;
int [][] matProduit = new int[mat1.length][mat2[0].length];
for (i = 0; i < mat1.length; i++) {
for(j = 0; j < mat2[0].length; j++) {
initialiser(matProduit);
for (k = 0; k < mat2.length; k++) {
matProduit[i][j] = mat1[i][k] * mat2[k][j];
}
}
}
return matProduit;
}
This is the result I should get:
0 1 0 0 0 0
0 0 1 0 0 1
0 0 0 0 1 1
0 0 1 0 1 0
0 0 0 0 0 0
0 0 0 0 0 0
This is the result I get:
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
As pointed by Assylias in the comments, you are calling initialiser(matProduit) at each iteration, thus resetting your matrix to zero.
I would advise you to try the debug mode for those kind of problems. It is your top tool for your daily coding.
Please find my own answer on another question, adressing the debug, how to do it, activating it and using it at least correctly.
Related
I am in the process of writing a program that works like Minesweeper. This is done in a 10x10 2d-array, and since I'm working with constraints, I can only write this using a 2d-array. However, I am getting a logical error with my count() method. The count() method returns the number of -1s found in the grid surrounding the input position (input position is what I'd make row and column in main(), for example, (5, 5). It also must not check a position outside the bounds of the 2d array. Here is a visual of what the output of count() should look like.
I also have to use count() with setCounts(). setCounts() goes through the entire 2d array, skips any position that is a -1, and calls the count() method, setting the current position to the value the count() method returns.
public int count(int row, int col)
{
int value = 0;
for(int r = -1; r < 2; r++)
{
for(int c = -1; c < 2; c++)
{
if(c == 0 && r == 0)
continue;
int newR = row + c;
int newC = col + c;
if(newR < 0 || newR >= array.length && newC < 0 || newC >= array[0].length)
continue;
if(array[newR][newC] == -1)
value++;
}
}
return value;
}
public void setCounts()
{
for(int r = 0; r < array.length; r++)
{
for(int c = 0; c < array[r].length; c++)
{
if(array[r][c] != -1)
array[r][c] = count(r, c);
String formatted = String.format("%2d", array[r][c]);
System.out.print(formatted + " ");
}
System.out.println();
}
}
The problem is that:
The count() method is incorrectly counting adjacent -1s surrounding any position I put in main()
setCounts() goes out of bounds after printing a random number of rows
I am certain that it has to do with this block of code:
if(newR < 0 || newR >= array.length && newC < 0 || newC >= array[0].length)
continue;
if(array[newR][newC] == -1)
value++;
When I printed newR and newC in the loop after continue, the loop is randomly adding more numbers to a row/column combo with no direct pattern for the entire output when count() was called in setCounts():
00
11
11
00
11
0 01
12
12
01
12
0 02
13
13
02
13
0 03
14
14
03
14
3 04
15
15
04
15
0 -1 -1 -1 -1 09
09
0
-1 00
...
So taking the print statements out, I get this as an output:
0 -1 -1 0 -1 -1 -1 0 0 0
0 0 0 0 0 0 -1 0 0 0
0 -1 0 -1 0 0 0 0 0 0
0 0 -1 0 0 0 0 0 -1 0
-1 0 0 0 -1 0 0 0 0 0
0 0 0 -1 0 0 0 -1 0 0
0 0 0 0 0 0 -1 0 -1 0
0 0 0 0 -1 -1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
there are 0 -1s
-----------
3 3 0 -1 3 3 0 -1 0 0
/* Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10
at Grid3.count(Grid3.java:44)
at Grid3.setCounts(Grid3.java:58)
at Grid3.main(Grid3.java:86) */
The first array is the array I make with Grid's constructor. The second array that the program is trying to print is being done when setCounts() is called.
I was thinking that changing it to:
if(newR < 0 || newR >= array.length)
continue;
if(newC < 0 || newC >= array[0].length)
continue;
if(array[newR][newC] == -1)
value++;
would work: and it does, but not logically. It gets rid of the ArrayIndexOutOfBoundsException error, but logically does not work since it doesn't count adjacent -1's right. It also seems to be adding more numbers randomly to any row/column combo. I put the position as (5, 5) in main() and one time I ran the code, it counted 6 -1s but there are only 3 -1s in the position I put:
-1 0 0 0 0 -1 0 -1 0 0
0 0 0 0 -1 -1 0 0 0 0
0 -1 0 0 0 0 0 0 0 0
0 -1 0 -1 -1 0 0 -1 -1 0
0 0 0 -1 -1 -1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
-1 0 0 0 0 0 -1 0 0 0
0 -1 0 0 0 -1 0 0 0 0
0 -1 0 0 -1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
there are 6 -1s
And for setCounts(), it printed a full 10x10 2d array but does not count -1s properly either. For the position (0, 0) (in this case, the 3 at the top left corner of the output shown below), that position should actually have a value of 2 since there are only 2 adjacent -1s, but it actually counts 3.
3 0 0 0 0 0 -1 0 0 0
-1 -1 0 3 0 0 0 -1 0 0
-1 3 6 3 -1 0 3 0 3 0
0 3 0 -1 -1 -1 0 -1 0 0
3 0 0 0 -1 3 6 3 3 0
3 -1 0 0 0 3 0 -1 -1 0
-1 -1 3 0 0 0 0 3 3 3
0 6 6 0 3 0 0 0 -1 0
0 0 -1 -1 0 -1 0 0 0 3
0 0 0 3 3 0 3 0 0 0
Here is a full output:
0 0 0 0 0 0 -1 0 0 0
0 -1 0 0 -1 0 0 0 0 0
0 -1 0 0 0 -1 0 0 0 0
0 0 -1 -1 -1 0 0 -1 0 0
0 0 0 0 0 -1 -1 0 -1 0
-1 0 0 -1 0 -1 0 0 0 0
0 0 0 0 0 0 0 0 -1 0
0 -1 0 0 0 0 0 0 -1 0
0 0 0 0 0 0 -1 0 -1 0
0 0 0 0 0 0 0 0 0 0
there are 2 -1's
-----------
3 0 0 3 0 0 -1 0 0 0
3 -1 0 0 -1 0 0 3 0 0
0 -1 6 3 0 -1 3 0 0 0
0 0 -1 -1 -1 3 3 -1 0 0
0 0 3 3 6 -1 -1 0 -1 0
-1 0 0 -1 0 -1 3 6 0 3
3 3 0 0 3 0 3 3 -1 0
0 -1 0 0 0 3 0 3 -1 3
0 0 3 0 0 0 -1 0 -1 3
0 0 0 0 0 0 0 3 0 3
I cannot figure out what I'm doing wrong. I need count() to properly count adjacent -1s given a position. If it doesn't count adjacent -1s properly, then setCounts() will not logically work. What should I change in either or both methods so that it properly and logically works? Here is my code so far.
public class Grid
{
private int [][] array;
private int max;
public Grid(int max)
{
array = new int[10][10];
this.max = max;
setRandom();
}
public void setRandom()
{
int i = 0;
while(i < max)
{
int r = (int)(Math.random() * 9) + 0;
int c = (int)(Math.random() * 9) + 0;
if(array[r][c] != -1)
{
array[r][c] = -1;
i++;
}
}
}
public int count(int row, int col)
{
int value = 0;
for(int r = -1; r < 2; r++)
{
for(int c = -1; c < 2; c++)
{
if(c == 0 && r == 0)
continue;
int newR = row + c;
int newC = col + c;
if(newR < 0 || newR >= array.length && newC < 0 || newC >= array[0].length)
continue;
if(array[newR][newC] == -1)
value++;
}
}
return value;
}
public void setCounts()
{
for(int r = 0; r < array.length; r++)
{
for(int c = 0; c < array[r].length; c++)
{
if(array[r][c] != -1)
array[r][c] = count(r, c);
String formatted = String.format("%2d", array[r][c]);
System.out.print(formatted + " ");
}
System.out.println();
}
}
public void print()
{
for(int r = 0; r < array.length; r++)
{
for(int c = 0; c < array[r].length; c++)
{
System.out.print(array[r][c] + " ");
}
System.out.println();
}
}
public static void main(String[] args) // printing grid
{
Grid first = new Grid(20);
int count = first.count(5, 5);
first.print();
System.out.println("there are " + count + " -1s");
System.out.println("-----------");
first.setCounts();
}
}
It might be easier to not use a 2d-array.
Or at least, you might want to store an object representing each cell rather than just an int. This way, you could implement the logic for figuring out the neighboring cells for a particular cell within the Cell-Class.
Here is an example (using a map instead of an array):
public class Grid {
public final int width, height;
private final Map<Coordinate, Cell> cells;
public Grid(int width, int height) {
this.width = width;
this.height = height;
this.cells = IntStream.range(0, width).boxed()
.flatMap(column ->
IntStream.range(0, height).boxed()
.map(row -> new Coordinate(row, column))
)
.map(Cell::new)
.collect(Collectors.toMap(Cell::getCoordinate, Function.identity()));
}
public Cell get(int row, int col) {
return this.cells.get(new Coordinate(row, col));
}
public class Cell {
private final Coordinate coordinate;
private final boolean isMine;
public Cell(Coordinate coordinate, boolean isMine) {
this.coordinate = coordinate;
this.isMine = isMine;
}
public Cell(Coordinate coordinate) {
this(coordinate, new Random().nextBoolean());
}
public Coordinate getCoordinate() {
return coordinate;
}
public List<Cell> getNeighbours() {
int leftNeighbourColumnIdx = coordinate.column - 1;
int topNeighbourRowIdx = coordinate.row - 1;
return IntStream.range(leftNeighbourColumnIdx, leftNeighbourColumnIdx + 3).boxed()
.flatMap(column -> IntStream.range(topNeighbourRowIdx, topNeighbourRowIdx + 3).boxed().map(row -> new Coordinate(row, column)))
.map(Grid.this.cells::get)
.filter(Objects::nonNull)
.filter(c -> !c.equals(this))
.collect(Collectors.toList());
}
public int countNeighbouringMines() {
return (int) getNeighbours().stream()
.filter(cell -> cell.isMine)
.count();
}
}
public static class Coordinate {
private final int row, column;
public Coordinate(int row, int column) {
this.row = row;
this.column = column;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Coordinate that = (Coordinate) o;
return row == that.row && column == that.column;
}
#Override
public int hashCode() {
return Objects.hash(row, column);
}
}
public static void main(String[] args) {
final var grid = new Grid(10, 10);
for (int row = 0; row < grid.height; row++) {
for (int col = 0; col < grid.width; col++) {
final var cell = grid.get(row, col);
System.out.print(cell.isMine ? "x" : "o");
System.out.print(" ");
}
System.out.println();
}
System.out.printf("mines around (5,5): %d%n", grid.get(5, 5).countNeighbouringMines());
}
}
Edit: same example as above but with a 2d-array instead of a map
public class Grid {
public final int width, height;
private final Cell[][] cells;
public Grid(int width, int height) {
this.width = width;
this.height = height;
cells = new Cell[width][height];
IntStream.range(0, width)
.forEach(column -> IntStream.range(0, height)
.forEach(row -> cells[column][row] = new Cell(column, row))
);
}
public Cell get(int row, int col) {
final var column = col < 0 || col >= this.cells.length ? null : this.cells[col];
return row < 0 || column == null || row >= column.length ? null : column[row];
}
public class Cell {
private final int column, row;
private final boolean isMine;
public Cell(int column, int row, boolean isMine) {
this.column = column;
this.row = row;
this.isMine = isMine;
}
public Cell(int column, int row) {
this(column, row, new Random().nextBoolean());
}
public List<Cell> getNeighbours() {
int leftNeighbourColumnIdx = column - 1;
int topNeighbourRowIdx = row - 1;
return IntStream.range(leftNeighbourColumnIdx, leftNeighbourColumnIdx + 3).boxed()
.flatMap(column -> IntStream.range(topNeighbourRowIdx, topNeighbourRowIdx + 3).boxed()
.map(row -> Grid.this.get(row, column)))
.filter(Objects::nonNull)
.filter(c -> !c.equals(this))
.collect(Collectors.toList());
}
public int countNeighbouringMines() {
return (int) getNeighbours().stream()
.filter(cell -> cell.isMine)
.count();
}
}
public static void main(String[] args) {
final var grid = new Grid(10, 10);
for (int row = 0; row < grid.height; row++) {
for (int col = 0; col < grid.width; col++) {
final var cell = grid.get(row, col);
System.out.print(cell.isMine ? "x" : "o");
System.out.print(" ");
}
System.out.println();
}
System.out.printf("mines around (5,5): %d%n", grid.get(5, 5).countNeighbouringMines());
}
}
The idea is, that the get(int row, int col) method in Grid returns either a Cell object or null if row or cell are invalid -- but it never fails (throws an exception).
Every cell can then use this method to try to get all its neighbours (getNeighbours()).
The cell doesn't need to worry, if the row/column it asks for is valid or not -- this will be handled by get(int row, int col).
It just needs to filter out all null values (those coordinates were invalid) and itself.
With getNeighbours(), you have a list with all the neighboring cells. If you filter out all cells which have no mines - you get a list of neighbours with mines on them -- and then you just need to count them.
I'm trying to do an ArrayList of 2 dimensional arrays.
It is the same 2 dim array that I'm adding to the ArrayList, but it has different values each time.
The problem is : when I add the array to the list, it's auto-updating the other versions of the array in the list.
I tried to clone/copy the array just before adding it to the List, but it has no effect.
import java.util.*;
public class Test {
static ArrayList<int[][]> list = new ArrayList<int[][]>();
public static void main(String[] args) {
Lister L = new Lister();
}
public static void add(int[][] array) {
list.add(array);
printArray();
}
public static void printArray() {
for (int i = 0; i < list.size(); i++) {
System.out.println("Element: " + i);
printDim(list.get(i));
}
System.out.println("--------------------------------");
}
public static void printDim(int[][] array) {
for (int x = 0; x < array.length; x++) {
for (int y = 0; y < array[0].length; y++) {
System.out.print(array[y][x]+" ");
}
System.out.println();
}
System.out.println("-----------");
}
}
class Lister {
Lister() {
int[][] array1 = new int[5][5];
array1[0][4] = 1;
Test.add(array1);
int[][] array2 = array1.clone();
array2[1][2] = 1;
Test.add(array2);
}
}
Output:
Element: 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 0 0 0 0
---------------------
Element: 0
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
1 0 0 0 0
-----------
Element: 1
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
1 0 0 0 0
--------------------
Expected Output:
Element: 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 0 0 0 0
--------------------
Element: 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 0 0 0 0
-----------
Element: 1
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
1 0 0 0 0
---------------------
A 2D array cannot be shallow copied. Since it's an array of arrays, a shallow copy will give you a new outer array holding references to the same inner arrays as the original.
You need to implement a deep copy instead:
int[][] array2 = array1.clone();
for (int i = 0; i < array2.length; i++) {
array2[i] = array1[i].clone();
}
Please not that this only works for primitive arrays. If you have object arrays, you need to copy each object as well (except you're fine with having the same objects referenced).
It's because you're still using the same 'matrix' of type int. This should be fixed by declaring it again after using the first one.
import java.util.*;
class Test {
static ArrayList<int[][]> list = new ArrayList<int[][]>();
public static void main(String[] args) {
int[][] array1 = new int[5][5];
array1[0][4] = 1;
list.add(array1);
array1 = new int[5][5];
array1[1][2] = 1;
list.add(array1);
printArray();
}
public static void printArray() {
for (int i = 0; i < list.size(); i++) {
printDim(list.get(i));
}
}
public static void printDim(int[][] array) {
for (int x = 0; x < array.length; x++) {
for (int y = 0; y < array[0].length; y++) {
System.out.print(array[y][x]+" ");
}
System.out.println();
}
System.out.println("--------");
}
}
I have a 2d array:
0 0 0 0 0 0
0 0 0 0 0 0
1 1 0 0 0 0
0 0 0 0 1 1
1 0 1 1 0 0
1 0 0 0 1 1
All blocks take up two adjacent cells either (cells have value =1) horizontally or vertically. Now, I drop all blocks and I get a new array:
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
1 1 0 0 0 0
1 0 0 0 1 1
1 0 1 1 1 1
Here is my Source Code:
package IOJava;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class ReadFile {
public static int rows, cols;
public static int[][] cells;
public static void main(String[] args) throws IOException {
try {
File file = new File("input.txt");
Scanner input = new Scanner(file);
int rows = 0; // i chinh la so hang
int cols = 0;
int[][] newArr = new int[100][100];
ArrayList string = new ArrayList();
while (input.hasNextLine()) {
String line = input.nextLine();
line = line.trim();
String[] arrLine = line.split(" ");
cols = arrLine.length;
for (int i = 0; i < arrLine.length; i++) {
newArr[rows][i] = Integer.parseInt(arrLine[i]);
}
rows++;
}
int[][] newCopyArr = twoDimensionalArrayClone(newArr);
for (int i = 0; i <rows; i++) {
for (int j = 0; j <cols; j++) {
if(i+1<rows && j+1<cols){
if(newCopyArr[i][j]==1 && newCopyArr[i][j+1]==1){
if(newCopyArr[i+1][j]==0 && newCopyArr[i+1][j+1]==0){
newCopyArr[i][j]=0 ; newCopyArr[i][j+1]=0;
newCopyArr[i+1][j]=1 ; newCopyArr[i+1][j+1]=1;
}
}
if(newCopyArr[i][j]==1 && newCopyArr[i+1][j]==1){
if(i+2<rows){
if(newCopyArr[i+2][j]==0){
newCopyArr[i][j]=0;
newCopyArr[i+2][j]=1;
}
}
}
// if(newCopyArr[i][j]==1 && newCopyArr[i+1][j]==1 && newCopyArr[i+1][j]==1){
//
// }
//
}
}
}
//sysout
for (int k = 0; k < rows; k++) {
for (int h = 0; h < cols; h++) {
System.out.print(" " + newCopyArr[k][h]);
}
System.out.println();
}
input.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static int[][] twoDimensionalArrayClone(int[][] a) {
int[][] b = new int[a.length][];
for (int i = 0; i < a.length; i++) {
b[i] = a[i].clone();
}
return b;
}
}
But, when I try to execute this code with other 2d array[], it is not right.
Example:
0 0 0 0 0 0
0 1 1 0 0 0
1 1 0 0 0 0
0 0 0 0 1 1
1 0 1 1 0 0
1 0 0 0 1 1
The question revolves around Conway's Game of Life and how to implement all the rules at the same time for the new generations. The game follows three rules for new generations, which are: a dead cell with exactly three live neighbors becomes live, a live cell with exactly one live neighbor becomes dead, and a live cell with more than three live neighbors becomes dead. The original generation is random. I think my problem, which is that my new generations are implementing the rules one at a time instead of all at once, is in this method:
public static int[][] nextgeneration(int[][] lastgen){
int[][] nextgen = new int[lastgen.length][lastgen[0].length];
for(int i = 0; i < lastgen.length; i++){
for(int j = 0; j < lastgen[i].length; j++){
if(aliveneighbors(lastgen, i, j) == 3){
nextgen[i][j] = 1;
}
else if(aliveneighbors(lastgen, i, j) == 1){
nextgen[i][j] = 0;
}
else if(aliveneighbors(lastgen, i, j) > 3){
nextgen[i][j] = 0;
}
else nextgen[i][j] = lastgen[i][j];
}
}
return nextgen;
Here's my full code just in case the problem was not in that method:
import java.util.Random;
public class Life {
public static int[][] origin(int a, int b) {
int[][] randomMatrix = new int [a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
Random random = new Random();
int abc = random.nextInt(2);
randomMatrix[i][j] = abc;
}
}
return randomMatrix;
}
public static void print(int[][] a) {
for(int i = 0; i < a.length; i++){
for(int j = 0; j < a.length; j++){
System.out.print(a[i][j] + " ");
}
System.out.println();
}
}
public static void show(int[][] b) {
int N = b.length;
StdDraw.setXscale(0, N-1);
StdDraw.setYscale(0, N-1);
for(int i = 0; i < b.length; i++){
for(int j = 0; j < b.length; j++){
if(b[i][j] == 1){
StdDraw.setPenColor(StdDraw.RED);
StdDraw.filledSquare(j, N-i-1, .5);
}
else if(b[i][j] == 0){
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.filledSquare((double)j, (double)-i, .5);
}
}
}
}
public static int[][] nextgeneration(int[][] lastgen){
int[][] nextgen = new int[lastgen.length][lastgen[0].length];
for(int i = 0; i < lastgen.length; i++){
for(int j = 0; j < lastgen[i].length; j++){
if(aliveneighbors(lastgen, i, j) == 3){
nextgen[i][j] = 1;
}
else if(aliveneighbors(lastgen, i, j) == 1){
nextgen[i][j] = 0;
}
else if(aliveneighbors(lastgen, i, j) > 3){
nextgen[i][j] = 0;
}
else nextgen[i][j] = lastgen[i][j];
}
}
return nextgen;
}
public static int aliveneighbors(int[][] board, int x, int y){
int count = 0;
int up;
int down;
int left;
int right;
{
if(x > 0)
up = x - 1;
else
up = board.length - 1;
if(x < (board.length - 1))
down = x + 1;
else
down = 0;
if(y > 0)
left = y - 1;
else
left = board[x].length - 1;
if(y < (board[x].length - 1))
right = y + 1;
else
right = 0;
//Count the live neighbors
if(board[up][left] == 1)
count++;
if(board[up][y] == 1)
count++;
if(board[up][right] == 1)
count++;
if(board[x][left] == 1)
count++;
if(board[x][right] == 1)
count++;
if(board[down][left] == 1)
count++;
if(board[down][y] == 1)
count++;
if(board[down][right] == 1)
count++;
return count;
}
}
public static void main(String[] args) {
int[][] b = origin(5, 5);
int gens = 5;
for (int i = 0; i < gens; i++) {
System.out.println();
int nextboard[][] = nextgeneration(b);
b = nextboard; //I feel like this could be a problem as well
System.out.println("Generation " + i + ":");
print(nextgeneration(b));
show(nextgeneration(b)); //This line of code seems useless
//print(b); This one also seems useless and makes output confusing
show(b);
}
}
}
Here is what my output is:
Generation 0:
0 1 1 0 0
0 1 1 0 0
0 0 0 1 1
1 1 0 1 1
1 0 0 0 0
Generation 1:
1 0 1 0 0
1 1 0 0 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Generation 2:
1 0 1 0 1
1 1 0 0 0
1 0 0 0 0
0 0 1 1 0
0 0 0 1 1
Generation 3:
0 0 1 0 0
0 0 0 0 0
1 0 1 0 1
0 0 1 1 0
1 1 0 0 0
Generation 4:
0 1 0 0 0
0 1 0 1 0
0 1 1 0 1
0 0 1 1 0
0 1 0 1 0
I expect something like this:
Generation 0:
0 1 1 0 0
0 1 1 0 0
0 0 0 1 1
1 1 0 1 1
1 0 0 0 0
Generation 1:
0 1 1 0 0
0 1 0 0 0
1 0 0 0 1
1 1 1 1 1
1 1 0 0 0
Generation 2:
0 1 1 0 0
1 1 1 0 0
1 0 0 0 1
0 0 1 1 1
1 0 0 1 0
Also on my animation of the game the alive cells stay alive in the animation, which should not be happening. That's not my main problem, but if you know how to fix that it would also be helpful.
Your output looks fine to me. Pay attention, that you actually do "wrap-around" of the borders, so this
Generation 0:
0 1 1 0 0
has this as a upper border:
1 0 0 0 0
and a left border:
0
0
1
1
0
For calculations it looks like:
0 1 0 0 0 0
0 0 1 1 0 0
0 0 1 1 0 0
So this output:
Generation 1:
1 0 1 0 0
1 1 0 0 0
Is correct for the wrap-around.
From the expected result, however, it looks you want to treat it as a actual border. I mean:
010
000
with x=1, y=0, has only 5 neighbours.
In that case you need something like this:
public static int aliveneighbors(int[][] board, int x, int y){
int width = board.length;
int height = board[0].length;
int count = 0;
boolean isNotLower = (y-1) >= 0;
boolean isNotUpper = (y+1) < height;
if (x-1 >= 0) {
if( isNotLower && (board[x-1][y-1] == 1) )
count++;
if(board[x-1][y] == 1)
count++;
if(isNotUpper && (board[x-1][y+1] == 1) )
count++;
}
if (x+1 < width) {
if( isNotLower && (board[x+1][y-1] == 1) )
count++;
if(board[x+1][y] == 1)
count++;
if( isNotUpper && (board[x+1][y+1] == 1) )
count++;
}
if( isNotUpper && (board[x][y+1] == 1) )
count++;
if(isNotLower && (board[x][y-1] == 1) )
count++;
return count;
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am trying to implement Dijkstra Algorithm using priority queue given an adjaceny matrix.
I know the problem is probably at where I add vertices to the priority queue but I can't figure out how to fix it!
static int dijkstra(int[][] g, int i, int j) {
// Get the number of vertices in G
int n = g.length;
int counter = 0;
PriorityQueue<Vertex> q = new PriorityQueue<Vertex>(n, new Comparator<Vertex>() {
public int compare(Vertex a, Vertex b) {
Vertex v1 = (Vertex) a;
Vertex v2 = (Vertex) b;
if (v1.getD() > v2.getD()) {
return 1;
} else if (v1.getD() < v2.getD()) {
return -1;
} else {
return 0;
}
}
});
int[] distance = new int[n];
for (int l = 0; l < n; l++) {
distance[l] = 99999;
}
distance[i] = 0;
for (int l = 0; l < n/2; l++) {
for (int m = 0; m < n; m++) {
if (g[l][m] > 1) {
System.out.printf("%d was added \n", g[l][m]);
q.add(new Vertex(l, g[l][m]));
}
}
}
while (!q.isEmpty()) {
int u = 0;
for (int z = 0; z < n; z++) {
if (distance[z] < distance[u]) {
u = z;
}
}
if (distance[u] == 99999) { break; }
q.remove();
for (int l = 0; l < n; l++) {
if (g[u][l] > 1) {
int alt = distance[u] + g[u][l];
if (alt < distance[l]) {
distance[l] = alt;
q.remove();
q.add(new Vertex(u, distance[l]));
}
}
}
}
for (int k = 0; k < n; k++) {
System.out.printf("==>%d", distance[j]);
}
return distance[j];
}
And:
class Vertex {
int v,d;
public Vertex(int num, int dis) {
v = num;
d = dis;
}
public int getV() {
return v;
}
public int getD() {
return d;
}
}
I am testing with the following matrix:
0 0 0 0 0 0 0 38 0 0 0 0 0 0 0 0
0 0 0 0 65 0 64 0 6 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 6 8 0 0 0 62
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 65 0 0 0 0 0 0 0 6 0 0 0 0 55 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 64 0 0 0 0 0 53 0 0 36 0 45 0 0 0
38 0 0 0 0 0 53 0 0 0 0 91 0 29 0 0
0 6 0 0 0 0 0 0 0 0 0 95 55 0 0 0
0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0
0 0 6 0 0 0 36 0 0 0 0 0 0 0 0 0
0 0 8 0 0 0 0 91 95 0 0 0 60 0 0 0
0 0 0 0 0 0 45 0 55 0 0 60 0 0 0 0
0 0 0 0 0 0 0 29 0 0 0 0 0 0 0 0
0 0 0 0 55 0 0 0 0 0 0 0 0 0 0 0
0 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0
And start is 0, end is n - 1. I should be getting 195 but it seems like none of the distances are being changed!
When you're printing the distances you print the array at j all the time while k is the iterator. The distances appear constant but they are changing.
for (int k = 0; k < n; k++) {
System.out.printf("==>%d", distance[k]);
}
Also, in your algorithm you're removing the top vertex twice which isn't plausible. The algorithm should be something like this instead:
while (!q.isEmpty()) {
int u = q.peek().v;
q.remove();
for (int l = 0; l < n; l++) {
if (g[u][l] > 1) {
int alt = distance[u] + g[u][l];
if (alt < distance[l]) {
distance[l] = alt;
q.add(new Vertex(u, distance[l]));
}
}
}
}