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'm writing a program based on John Conway's Game of Life. I got it to compile and Even run after days of working on it non stop. However, the result it is printing out is wrong...
This is my code (not including the main method)
//clears the grid
public static void clearGrid ( boolean[][] grid )
{
for(int row = 0; row < 18; row++){
for(int col = 0; col < 18; col++){
grid[row][col]= false;
}
}
//set all index in array to false
}
//generate the next generation
public static void genNextGrid ( boolean[][] grid )
{
int n; //number of neighbors
boolean[][] TempGrid = grid;// a temporary array
for(int row = 0; row < 18; row++)
{
for(int col = 0; col < 18; col++)
{
TempGrid[row][col] = grid[row][col];
n = countNeighbors(grid, row, col);
if(grid[row][col] == true)
{
if(n != 2 && n != 3)
{
TempGrid[row][col] = false;
}
else
TempGrid[row][col] = true;
}
else
{
if(n == 3)
{
TempGrid[row][col] = true;
}
else
TempGrid[row][col] = false;
}
grid[row][col] = TempGrid[row][col];
}
}
}
//count how many neighbors surrounding any speicific cell
public static int countNeighbors ( final boolean[][] grid, final int row, final int col )
{
int n = 0;
for (int TempRow = row - 1; TempRow <= row + 1; TempRow++)
{
if (TempRow >= 0 && TempRow < 18)
{
for (int TempCol = col - 1; TempCol <= col + 1; TempCol++)
{
if (TempCol >= 0 && TempCol < 18 && (TempRow != row || TempCol != col))
{
if (grid[TempRow][TempCol])
{
n++;
}
}
}
}
}
return n;
}
I am pretty sure that the problem is occuring within my genNextGrid method.
The assignment sheet included
public static void genNextGrid (boolean[][] grid);
This method will actually generate the next generation of the simulation.
It should use the two-dimensional array grid that is passed to it as the "current" generation. It should create a second,
temporary two-dimensional array that will hold the "next" generation. You will need to create this temporary matrix to work
with as you can't make changes to the current matrix because you would risk losing all of the information you need in
order to successfully create the next generation."
I created a temporary array
I copied the current array to the temporary
I later copied the temporary back to current array like the instruction said.
so I'm not really sure what I did wrong.
It's nearly 3 a.m, been staring at my Vim screen since noon. Any help would be greatly appriciated.
boolean[][] TempGrid = grid;
will use the same array, just by a different name. You have to allocate some new memory instead. Looking at your code, this should do the trick:
boolean TempGrid = new boolean[18][18];
(It would be much better if you replaced those 18s with a constant though)
The most obvious problem is here:
boolean[][] TempGrid = grid;// a temporary array
TempGrid just points to grid. You need to create a separate array:
boolean[][] TempGrid = new boolean[18][18];
In addition to not really creating a new temp array but just getting a reference to old one, as said in other answers: you copy the tempGrid cell into the grid cell in the same loop where you calculated it. So next loop iteration will use the new calculated value, instead of the current "old" value in grid.
You need to first calculate entire tempGrid, and then copy it over grid. Or better than copying, would be to set grid to point to tempGrid's array, but that might be out of scope of your homework (you would have to return tempGrid from genNextGrid() and assign it to original grid reference).
The whole point of needing a tempGrid instead of just single temp cell is, you need the previous generation in grid during calculation of next generation.
Related
I'm having a problem working with matrices. I have a matrix which will hold 3 columns of data and as a starting point 10 rows of data. Each row is an article in a "cash register software" and each column is in order: {article number, items in stock, article price}.
As I mentioned, the int[][]articles has to start with the size of [10][3], but have the ability to expand with the help of a method "checkFull". The user will be asked how many articles he/she wants to add and the value will be saved into the variable "noOfArticles". The checkFull() method has to check if the value of articles fits into the article[][] matrix or if it has to create another matrix with the right amount of slots, copy the values from articles[][] and return the new matrix.
The following code is my shot at the problem, does anyone got any ideas how to get this method working properly?
public static int[][] checkFull(int[][]articles, int noOfArticles) {
int index = 0;
int i = 0;
while (i < articles.length)
{
if (articles[i][0] == 0)
{
index = i;
break;
}
i++;
}
if ((articles.length - index) < noOfArticles)
{
newmat = new int[noOfArticles + articles.length][3];
for (i = 0; i < articles.length; i++)
{
for (int j = 0; j < articles[i].length; j++)
{
int[][]newmat[i][j] = articles[i][j];
}
}
return newmat;
}
else
{
return articles;
}
}
I'm trying to implement a game where the viable moves are down-left and down-right.
The parameter for the function is for the size of the array, so if you pass 4 it will be a 4 by 4 array.
The starting position is the top row from any column. Every element in the array is a number in the range 1-100, taken from a file. I need to find the resulting value for the most profitable route from any starting column.
My current implementation will compare the right position and left position and move to whichever is higher. The problem is, for example, if the left position is lower in value than the right, but the left position will provide more profit in the long run since it can access higher value elements, my algorithm fails.
Here is a demo:
84 (53) 40 62
*42* 14 [41] 57
76 *47* 80 [95]
If we start at number 53. The numbers enclosed in * are the moves that my algorithm will take, but the numbers enclosed in [] are the moves my algorithm should take.
This is my code:
import java.util.ArrayList;
import java.util.Scanner;
public class bestPathGame{
private int[][] grid;
private int n;
public bestPathGame(int num){
Scanner input = new Scanner(System.in);
n = num;
grid = new int[n][n];
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
grid[i][j] = input.nextInt();
}
}
}
public static void main(String[] args){
bestPathGame obj = new bestPathGame(Integer.parseInt(args[0]));
obj.bestPath();
}
private boolean moveLeftBetter(int r,int c){
if(c <= 0){
return false;
} else if (c >= n -1 ){
return true;
}
return grid[r][c-1] > grid[r][c+1];
}
public void bestPath(){
ArrayList<Integer> allOptions = new ArrayList<>();
for(int k = 0; k < n; k++){
int row = 0;
int col = k;
int collection = grid[row][col];
while(row < n - 1){
row += 1;
if(moveLeftBetter(row,col)){
col-=1;
} else{
col+=1;
}
collection += grid[row][col];
}
allOptions.add(collection);
}
System.out.println(allOptions.stream().reduce((a,b)->Integer.max(a,b)).get());
}
}
Greedy algorithm vs Dynamic programming
There's an issue with the logic of your solution.
Basically, what you are implemented is a called a greedy algorithm. At each step of iteration, you are picking a result that optimal locally, assuming that this choice will lead to the optimal global result. I.e. your code is based on the assumption that by choosing a local maximum between the two columns, you will get the correct global maximum.
As a consequence, your code in the bestPath() method almost at each iteration will discard a branch of paths based on only one next value. This approach might lead to incorrect results, especially with large matrixes.
Greedy algorithms are rarely able to give an accurate output, usually their result is somewhat close but not precise. As an upper-hand, they run fast, typically in O(n) time.
For this problem, you need to use a dynamic programming (DP).
In short, DP is an enhanced brute-force approach which cashes the results and reuses them instead of recalculating the same values multiple times. And as well, as a regular brute-force DP algorithms are always checking all possible combinations.
There are two major approaches in dynamic programming: tabulation and memoization (take a look at this post for more information).
Tabulation
While implementing a tabulation first you need to create an array which then need to be prepopulated (completely or partially). Tabulation is also called the bottom-up approach because calculation start from the elementary edge cases. Every possible outcome is being computed based on the previously obtained values while iterating over this array. The final result will usually be stored in the last cell (in this case in the last row).
To implement the tabulation, we need to create the matrix of the same size, and copy all the values from the given matrix into it. Then row by row every cell will be populated with the maximum possible profit that could be obtained by reaching this cell from the first row.
I.e. every iteration will produce a solution for a 2D-array, that continuously increases by one row at each step. It'll start from the array that consists of only one first row (no changes are needed), then to get the profit for every cell in the second row it's values has to be combined with the best values from the first row (that will be a valid solution for 2D-array of size 2 * n), and so on. That way, solution gradually develops, and the last row will contain the maximum results for every cell.
That how the code will look like:
public static int getMaxProfitTabulation(int[][] matrix) {
int[][] tab = new int[matrix.length][matrix.length];
for (int row = 0; row < tab.length; row++) { // populating the tab to preserve the matrix intact
tab[row] = Arrays.copyOf(matrix[row], matrix[row].length);
}
for (int row = 1; row < tab.length; row++) {
for (int col = 0; col < tab[row].length; col++) {
if (col == 0) { // index on the left is invalid
tab[row][col] += tab[row - 1][col + 1];
} else if (col == matrix[row].length - 1) { // index on the right is invalid
tab[row][col] += tab[row - 1][col - 1];
} else {
tab[row][col] += Math.max(tab[row - 1][col - 1], tab[row - 1][col + 1]); // max between left and right
}
}
}
return getMax(tab);
}
Helper method responsible for extracting the maximum value from the last row (if you want to utilize streams for that, use IntStream.of(tab[tab.length - 1]).max().orElse(-1);).
public static int getMax(int[][] tab) {
int result = -1;
for (int col = 0; col < tab[tab.length - 1].length; col++) {
result = Math.max(tab[tab.length - 1][col], result);
}
return result;
}
Memoization
The second option is to use Memoization, also called the top-down approach.
As I said, DP is an improved brute-force algorithm and memoization is based on the recursive solution that generates all possible outcomes, that is enhanced by adding a HashMap that stores all previously calculated results for every cell (i.e. previously encountered unique combination of row and column).
Recursion starts with the first row and the base-case of recursion (condition that terminates the recursion and is represented by a simple edge-case for which output is known in advance) for this task is when the recursive call hits the last row row == matrix.length - 1.
Otherwise, HashMap will be checked whether it already contains a result. And if it not the case all possible combination will be evaluated and the best result will be placed into the HashMap in order to be reused, and only the then the method returns.
Note that tabulation is usually preferred over memoization, because recursion has significant limitations, especially in Java. But recursive solutions are sometimes easier to came up with, so it's completely OK to use it when you need to test the idea or to prove that an iterative solution is working correctly.
The implementation will look like that.
public static int getMaxProfitMemoization(int[][] matrix) {
int result = 0;
for (int i = 0; i < matrix[0].length; i++) {
result = Math.max(result, maxProfitHelper(matrix, 0, i, new HashMap<>()));
}
return result;
}
public static int maxProfitHelper(int[][] matrix, int row, int col,
Map<String, Integer> memo) {
if (row == matrix.length - 1) { // base case
return matrix[row][col];
}
String key = getKey(row, col);
if (memo.containsKey(key)) { // if cell was already encountered result will be reused
return memo.get(key);
}
int result = matrix[row][col]; // otherwise result needs to be calculated
if (col == matrix[row].length - 1) { // index on the right is invalid
result += maxProfitHelper(matrix, row + 1, col - 1, memo);
} else if (col == 0) { // index on the left is invalid
result += maxProfitHelper(matrix, row + 1, col + 1, memo);
} else {
result += Math.max(maxProfitHelper(matrix, row + 1, col - 1, memo),
maxProfitHelper(matrix, row + 1, col + 1, memo));
}
memo.put(key, result); // placing result in the map
return memo.get(key);
}
public static String getKey(int row, int col) {
return row + " " + col;
}
Method main() and a matrix-generator used for testing purposes.
public static void main(String[] args) {
int[][] matrix = generateMatrix(100, new Random());
System.out.println("Tabulation: " + getMaxProfitTabulation(matrix));
System.out.println("Memoization: " + getMaxProfitMemoization(matrix));
}
public static int[][] generateMatrix(int size, Random random) {
int[][] result = new int[size][size];
for (int row = 0; row < result.length; row++) {
for (int col = 0; col < result[row].length; col++) {
result[row][col] = random.nextInt(1, 101);
}
}
return result;
}
I have a school project, I have to build a Tetris Game.
So I began with the creation of my menu with the different level, when I click on one level i go to my second activity (the game area) and I have also created my custom block.
My problem is a visual issue, indeed I don't know what type of layout I have to use for my surface game (gridlayout, linearlayout, grid etc. ...).
And then how to affect my blocks custom in this surface game, in this layout?
See the result expected.
enter image description here
I'm not sure I understand what you want entirely but ill give it a shot from what i think you mean.
You should use a nested for loop to do it, if your array was int[10,20](not right syntax but i cant be bothered to count the actual size of your array).
you should go:
(pseudocode)
also assume your resolution is 100, 200
For(int i = 1 To 10){
For(int k = 1 To 20){
DrawSquare(i*10, k*10, "block type")
k = k + 1
}
i = i + 1
}
Then it will fill your 100, 200 area with the block type specified. Now if you want to load what block type you want freom the array you can just call the array in the block type.
DrawSquare(i*10, k*10, Array[i,k])
Obviously bear in mind that its all pseudocode to display the logic.
Hope this helps
Building on Valhalla's answer with a Java-specific example, it's still a bit unclear what you're asking, but assuming you want to initialise the grid to begin with you can use this code:
private final int columns = 10;
private final int rows = columns * 2;
private int[][] grid;
private void initialise() {
grid = new int[columns][rows];
for (int i = 0; i < columns; i++) {
for(int j = 0; j < rows; j++) {
grid[i][j] = 0;
}
}
}
And assuming that you have a block that starts at the top, and falls one square with each iteration provided there's nothing underneath, you can try this:
private void blockFall() {
// Start from 1 row above the bottom and parse upwards
// so a block won't drop right to the bottom on a single iteration
for (int i = 0; i < columns; i++) {
for(int j = rows - 2; j >= 0; j--) {
if (grid[i][j] > 0 && grid[i][j+1] == 0) {
grid[i][j+1] = grid[i][j];
grid[i][j] = 0;
}
}
}
}
Hey I'm having trouble getting my code to compare the integers of a given row or column and block to make sure there are no duplicates within those parameters. I don't know if it would be a good idea separating the three contraints in 3 different methods or just trying to attempt to do all at once.
public static rowCheck(int[][] nsudokuBoard) {
for (int i =0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
// (nsudokuBoard)
}
}
}
this is my code im starting. before you guys bash on me for not even being able to compile this im stuck on how to compare all the values of a row of the 2d array.
You can compare all the values of the 2d array as shown in the code below:
void validate(final int[][] nsudokuBoard) {
final int width = nsudokuBoard[0].length;
final int depth = nsudokuBoard.length;
for (int i = 0; i < width; i++) {
int j = i;
int reference = nsudokuBoard[i][j];
do {
if (j < width) {
int current = nsudokuBoard[i][j];
if (current == reference) {
// invalid entry found do something
}
}
if (j < depth) {
// note reversed indexes
int current = nsudokuBoard[j][i];
if (current == reference) {
// invalid entry found do something
}
}
++j;
} while ((j >= width) || (j >= depth));
}
}
I haven't tried to compile this code, but it should give you an idea of how to accomplish your task. I would suggest that rather than passing in int[][] sudokuBoard that you should define a class which encapsulates the concept of a SudokuSquare and pass in SudokuSquare[][] , that way your validate method can return a List<SudokuSquare> containing all the offending entries.
I'll show how you might do it for one row, and then you can figure out the rest. I'm assuming your values are 1 through 9 inclusive, and that you don't have any zeroes or any "unfilled entries."
boolean isRowValid(int[][] grid, int row) {
boolean[] seen = new boolean[9];
int row; // chosen somewhere else
for (int col = 0; col < 9; col++) {
if (seen[grid[row][col] - 1]) { // if we've seen this value before in this row
return false; // there is a duplicate, and this is a bad sudoku
}
seen[grid[row][col] - 1] = true; // mark us as having seen this element
}
return true; // we're all good
}
return true; // this row is fine
make a class Cell with fields row,col,block,value; then make a class Matrix with field cells = cell[], fill matrix.
make a class checker with main method Matrix matrix = init(int[][]) and check(matrix), where init(ยท) fills the matrix.
boolean ok = check(matrix) where check(Matrix) does if(!rowcheck())return false; if(!colcheck()) return false etc;
create some methods like getrows(), getrow(r) and for(Cell cell: matrix.values()) to filter out the ones you want.
a bit tedious but i have done it and it is solid as rock.
As a note, filtering over matrix may seem stupid but computers are fast and the problem is O(1) since it is 9x9.
I'm having issues with my logic solving algorithm. It solves puzzles with a large number of hints very well, it just has issues with puzzles that have less than 45 clues.
This is the algorithm for solving. Immutable is a boolean that determines whether or not that value can be changed. cell[row][col].possibleValues is a LinkedList within a class called SudokuCell that stores the values that are possible for that grid element. grid.sGrid is the main int[][] array of the puzzle. removeFromCells() is a method that removes values from the row, column, and quadrant of the grid. That code is provided further down.
The second for loop is just for checking for a single solution. I decided to avoid recursion because I really can't get my head around it. This method seems to be working well enough for now.
public boolean solve(){
for(int i = 0; i < 81; i++){
for(int row = 0; row < 9; row++){
for(int col = 0; col < 9; col++){
if(!immutable[row][col]){
if(cell[row][col].getSize() == 1){
int value = cell[row][col].possibleValues.get(0);
grid.sGrid[row][col] = value;
immutable[row][col] = true;
removeFromCells(row, col, value);
}
}
}
}
}
int i = 0;
for(int row = 0; row < 9; row++){
for(int col = 0; col < 9; col++){
if(grid.sGrid[row][col] == 0){
i++;
}
}
}
if(i != 0){
return false;
} else{
return true;
}
}
This is the code for removeFromCells()
I think most of the code is pretty self-explanatory. The first for loop removes the value from the row and column of (x, y), and the second loop removes the value from the quadrant.
public void removeFromCells(int x, int y, int value){
/*
* First thing to do, find the quadrant where cell[x][y] belong.
*/
int topLeftCornerRow = 3 * (x / 3) ;
int topLeftCornerCol = 3 * (y / 3) ;
/*
* Remove the values from each row and column including the one
* where the original value to be removed is.
*/
for(int i = 0; i < 9; i++){
cell[i][y].removeValue(value);
cell[x][i].removeValue(value);
}
for(int row = 0; row < 3; row++){
for(int col = 0; col < 3; col++){
cell[topLeftCornerRow + row][topLeftCornerCol + col].removeValue(value);
}
}
}
Another problem spot could be where the possible values are constructed. This is the method I have for that:
The first for loop creates new SudokuCells to avoid the dreaded null pointer exception.
Any null values in sGrid are represented as 0, so the for loop skips those.
The constructor for SudokuBoard calls this method so I know it's being called.
public void constructBoard(){
for(int row = 0; row < 9; row++){
for(int col = 0; col < 9; col++){
cell[row][col] = new SudokuCell();
}
}
immutable = new boolean[9][9];
for(int row = 0; row < 9; row++){
for(int col = 0; col < 9; col++){
immutable[row][col] = false;
if(grid.sGrid[row][col] != 0){
removeFromCells(row, col, grid.sGrid[row][col]);
immutable[row][col] = true;
}
}
}
}
I would post the entire file, but there are a lot of unnecessary methods in there. I posted what I think is causing my problems.
You seem to have built only a simple constraint based solved for now. You need a full backtracking one in order to solve puzzles with less hints. There are some cases that you can't really solve without backtracking.
Alternatively you should try to implement Knuth's algorithm (Dancing Links) for solving this type of problems. It's more complicated to understand and implement than a backtracking algorithm but it's running way better :). See here: http://en.wikipedia.org/wiki/Dancing_Links
It's also an algorithm for a more general problem and it was applied to solving sudoku quite successfully.
On wikipedia there is a link to an article detailing what type of instances are possible to solve using constraints programming: http://4c.ucc.ie/~hsimonis/sudoku.pdf (found from here: http://en.wikipedia.org/wiki/Sudoku_algorithms). The Table 4 is really interesting :).
I used many such rules to develop my sudoku solver. Yet I always ended up forced to use backtracking for very hard sudokus. According to wikipedia, some sudokus are effectively impossible to solve by using only rules.
I implemented a total of 6 rules.
No other value is allowed..
A certain value is allowed in no other square in the same section.
A certain value is allowed in no other square in the same row or column.
A certain value is allowed only on one column or row inside a section, thus we can eliminate this value from that row or column in the other sections.
Naked pairs
Lines
I described the whole algorithm and gave the code in these two blog posts (the initial version only used the first 4 rules).
http://www.byteauthor.com/2010/08/sudoku-solver/
http://www.byteauthor.com/2010/08/sudoku-solver-update/
PS. My algorithm was geered towards performance so it automatically balances backtracking with these rules even though it could sometimes do without any guessing.