I'm doing a program , it is about an "object" (element) that move in 8way direction based on input.
My questions are : How can I make this element to visit cells of the board (2D Array) only once? How do I make it stay it current position if it can not move according to rules?
Start is position (0,0)
As input it get n-> number of dimension Matrix n x n , direction and t-> seconds. The other thing I don't get how to implement is input seconds, I get input seconds and directions because based on those I have to move the element into this 2D array list.
I've completed mostly of the program. I can give you my code here if you want to check it and give me advice. I'm stuck in it and I need help.
I want to print number of cells that are not visited. My idea is to give a number 0 to all cells that are not visited and the rest that are visited give number 1 as value. Like cell[x][x]=1; And in the end I count all cells that have number 0 as value and print count.
For a valid move in a particular direction, the object must move to a previously unoccupied cell, or else wait until the next direction.
You have defined cell[row][col] to represent the visited state; 0=unvisited, 1=visited. At the end, the number of unvisited cells will be the number of cell elements equal to zero.
To determine if the object should be moved, two checks must be done:
Make sure the next position is a valid matrix position (you are doing this correctly)
Make sure the next position has not yet been visited (will show below)
// Iterate through all k movements
for (i = 0; i < arrTime.length - 1; i++) {
// Move by 1 second until reach next instruction
for (j = arrTime[i]; j < arrTime[i + 1]; j++) {
// South East
if (arrDirection[i].equals("SE")) {
// Check #1 above (a valid matrix position)
if (nCurrRow < n - 1 && nCurrCol < n - 1) {
// Check #2 above (only move into unvisited position)
if (cell[nCurrRow+1][nCurrCol+1] == 0) {
// Move, and record that cell has been visited
nCurrRow++;
nCurrCol++;
cell[nCurrRow][nCurrCol] = 1;
}
}
}
// Other directions following the template for South East
Now to count unvisited cells:
int unVisited=0;
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
if (cell[i][j] == 0) unVisited++;
EDIT: To describe the two issues with the code.
1) The first issue relates to the j loop. The current j loop is
for(j = arrTime[i]; j <= arrTime[i + 1]; j++)
But must be:
for(j = arrTime[i]; j < arrTime[i + 1]; j++)
The way it was moves the object one more time than it should
2) The final movement was not being performed. The original code was:
arrTime[k] = arrTime[k - 1];
But must be:
arrTime[k] = arrTime[k - 1] + n;
Once you make these two changes, both test cases will work.
EDIT #2: A way to reduce the j loop
Previously, the j loop would run each iteration to the next i value. Here, we short circuit and leave the j loop as soon the object is unable to move. In the second test case, this reduced the number of j iterations from 50 to 28.
for (i = 0; i < arrTime.length - 1; i++) {
boolean canMove = true;
for (j = arrTime[i]; j < arrTime[i + 1] && canMove; j++) {
if (arrDirection[i].equals("SE")) {
if (nCurrRow < n - 1 && nCurrCol < n - 1 && cell[nCurrRow + 1][nCurrCol + 1] == 0) {
nCurrRow++;
nCurrCol++;
cell[nCurrRow][nCurrCol] = 1;
} else
canMove = false;
} else if (arrDirection[i].equals("NE")) {
if (nCurrRow > 0 && nCurrCol < n - 1 && cell[nCurrRow - 1][nCurrCol + 1] == 0) {
nCurrRow--;
nCurrCol++;
cell[nCurrRow][nCurrCol] = 1;
} else
canMove = false;
} ...
EDIT: Looking for test cases that will fail
Looking at your new comments, it is legal that the wind changes when t=1000000 (the maximum allowed value for t).
Consider this very simple test case:
3 2 (3x3 matrix, two wind changes)
0 E (wind blows east right away; robot moves to 0,2)
1000000 S (wind blows south at 1000000s, robot should move to 2,2)
Result should be: 4, but your current code will give 6 because it doesn't accept t=1000000.
If you change the line:
if(seconds >=0 && seconds<1000000 && k >=2 && k<1000000) {
to
if(seconds >=0 && seconds<=1000000 && k >=2 && k<=1000000) {
Then you get the expected answer of 4. It is very likely that at least one test case will push all the input boundaries, including when t=1000000.
EDIT: Faster algorithm #2
The current algorithm can be improved by reducing the number of if statements. There are two important improvements:
1) The former code had to use if to check both a) Valid matrix location b) If the location had been previously visited. You can use one 1 if for this, if you create a border around the matrix, and pre-populate with the value 1. Because of the border, the starting position is 1,1 and not 0,0.
2) Inside the j loop, the code unnecessarily looked up the direction. Now the direction is determined prior to the j loop, making the code inside the j loop much faster.
Also the number of unvisited cells is dynamic; no need to count them after the i loop completes. I changed the type to long because when n gets large, then the number of unvisited cells can be up to n*n which requires a type long. This might solve some of the incorrect answers.
If you study the new code, compare it to the older one, you will see many less if statements. This should scale better under larger test cases. Lets see if some of the test cases that were timing out improve.
public class Robot {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int j = 0;
int i = 0;
int n = in.nextInt();
int k = in.nextInt();
int[] arrTime = new int[k + 1];
String[] arrDirection = new String[k];
for (j = 0; j < k; j++) {
int seconds = in.nextInt();
if (seconds >= 0 && seconds <= 1000000) {
arrTime[j] = seconds;
}
String direction = in.next();
arrDirection[j] = direction;
}
arrTime[k] = arrTime[k - 1] + n;
// Add a border around the matrix with values of 1
int N = n + 2;
int[][] cell = new int[N][N];
for (j = 0; j < cell.length; j++) {
cell[0][j] = 1; // Top border
cell[j][0] = 1; // Left border
cell[j][N - 1] = 1; // Right border
cell[N - 1][j] = 1; // Bottom border
}
int nCurrRow = 1;
int nCurrCol = 1;
cell[nCurrRow][nCurrCol] = 1;
long R = n * n - 1; // Number of remaining unvisited cells
for (i = 0; i < arrTime.length - 1; i++) {
boolean canMove = true;
int xDir = 0;
int yDir = 0;
if (arrDirection[i].equals("SE")) {
xDir = 1;
yDir = 1;
} else if (arrDirection[i].equals("NE")) {
xDir = 1;
yDir = -1;
} else if (arrDirection[i].equals("E")) {
xDir = 1;
} else if (arrDirection[i].equals("N")) {
yDir = -1;
} else if (arrDirection[i].equals("NW")) {
xDir = -1;
yDir = -1;
} else if (arrDirection[i].equals("W")) {
xDir = -1;
} else if (arrDirection[i].equals("SW")) {
xDir = -1;
yDir = 1;
} else if (arrDirection[i].equals("S")) {
yDir = 1;
}
for (j = arrTime[i]; j < arrTime[i + 1] && canMove; j++) {
if (cell[nCurrRow + yDir][nCurrCol + xDir] == 0) {
nCurrRow += yDir;
nCurrCol += xDir;
cell[nCurrRow][nCurrCol] = 1;
R--;
} else
canMove = false;
}
}
//printArray(cell);
System.out.println(R);
in.close();
}
static void printArray(int[][] arr) {
for (int row = 0; row < arr.length; row++) {
for (int col = 0; col < arr.length; col++)
System.out.print(arr[row][col]);
System.out.println();
}
}
}
EDIT #3: More efficient memory usage; using BitSet
I suspect that the higher test cases are failing because the value of n is large in those cases. It is simple to test that when n=100000 that the cell array is too large, causing java memory error. So this code make the cell array very compact by using bitset. Lets see how this code does:
public class Robot {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int j = 0;
int i = 0;
int n = in.nextInt();
int k = in.nextInt();
int[] arrTime = new int[k + 1];
String[] arrDirection = new String[k];
for (j = 0; j < k; j++) {
int seconds = in.nextInt();
if (seconds >= 0 && seconds <= 1000000) {
arrTime[j] = seconds;
}
String direction = in.next();
arrDirection[j] = direction;
}
if (k >= 2 && k < 1000000) {
arrTime[k] = arrTime[k - 1] + n;
}
int N = n + 2;
BitSet[] cell = new BitSet[N];
for (j = 0; j < cell.length; j++)
cell[j] = new BitSet(N);
for (j = 0; j < cell.length; j++) {
set(cell, 0, j);
set(cell, j, 0);
set(cell, j, N-1);
set(cell, N-1, j);
}
int nCurrRow = 1;
int nCurrCol = 1;
set(cell,nCurrRow,nCurrCol);
long R = n * n - 1;
for (i = 0; i < arrTime.length - 1; i++) {
boolean canMove = true;
int xDir = 0;
int yDir = 0;
if (arrDirection[i].equals("SE")) {
xDir = 1;
yDir = 1;
} else if (arrDirection[i].equals("NE")) {
xDir = 1;
yDir = -1;
} else if (arrDirection[i].equals("E")) {
xDir = 1;
} else if (arrDirection[i].equals("N")) {
yDir = -1;
} else if (arrDirection[i].equals("NW")) {
xDir = -1;
yDir = -1;
} else if (arrDirection[i].equals("W")) {
xDir = -1;
} else if (arrDirection[i].equals("SW")) {
xDir = -1;
yDir = 1;
} else if (arrDirection[i].equals("S")) {
yDir = 1;
}
for (j = arrTime[i]; j < arrTime[i + 1] && canMove; j++) {
if (!isSet(cell,nCurrRow + yDir, nCurrCol + xDir)) {
nCurrRow += yDir;
nCurrCol += xDir;
set(cell,nCurrRow,nCurrCol);
R--;
} else
canMove = false;
}
}
//System.out.println();
//printArray(cell);
System.out.println(R);
in.close();
}
static boolean isSet(BitSet[] cell, int x, int y) {
BitSet b = cell[x];
return b.get(y);
}
static void set(BitSet[] cell, int x, int y) {
BitSet b = cell[x];
b.set(y);
}
static void printArray(int[][] arr) {
for (int row = 0; row < arr.length; row++) {
for (int col = 0; col < arr.length; col++)
System.out.print(arr[row][col]);
System.out.println();
}
}
}
EDIT: Attempt to read and process at the same time
This technique sometimes helps with large input. Rather than read all the input, then process in a second phase, process it as you read. In this case there is no need to store the data in two arrays (one for arrivalTime and one for direction). Lets see if this helps at all.
public class Robot2 {
static int nCurrRow = 1;
static int nCurrCol = 1;
static long R = 0;
static int[][] cell;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int i = 0;
int n = in.nextInt();
int k = in.nextInt();
// Add a border around the matrix with values of 1
int N = n + 2;
cell = new int[N][N];
for (i = 0; i < cell.length; i++) {
cell[0][i] = 1; // Top border
cell[i][0] = 1; // Left border
cell[i][N - 1] = 1; // Right border
cell[N - 1][i] = 1; // Bottom border
}
cell[nCurrRow][nCurrCol] = 1;
R = (long)n * n - 1; // Number of remaining unvisited cells
int sec1 = in.nextInt();
int sec2 = 0;
String dir1 = in.next();
String dir2;
for (i = 0; i < k - 1; i++) {
sec2 = in.nextInt();
dir2 = in.next();
move(sec2-sec1, dir1);
dir1 = dir2;
sec1 = sec2;
}
move(n, dir1);
System.out.println(R);
in.close();
}
static void move(int t, String dir1) {
boolean canMove = true;
int xDir = 0;
int yDir = 0;
if (dir1.equals("SE")) {
xDir = 1;
yDir = 1;
} else if (dir1.equals("NE")) {
xDir = 1;
yDir = -1;
} else if (dir1.equals("E")) {
xDir = 1;
} else if (dir1.equals("N")) {
yDir = -1;
} else if (dir1.equals("NW")) {
xDir = -1;
yDir = -1;
} else if (dir1.equals("W")) {
xDir = -1;
} else if (dir1.equals("SW")) {
xDir = -1;
yDir = 1;
} else if (dir1.equals("S")) {
yDir = 1;
}
for (int j = 0; j < t && canMove; j++) {
if (cell[nCurrRow + yDir][nCurrCol + xDir] == 0) {
nCurrRow += yDir;
nCurrCol += xDir;
cell[nCurrRow][nCurrCol] = 1;
R--;
} else
canMove = false;
}
}
}
EDIT: Combination of BitSet and one phase processing
public class Robot3 {
static int nCurrRow = 1;
static int nCurrCol = 1;
static long R = 0;
static BitSet[] cell;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int i = 0;
int n = in.nextInt();
int k = in.nextInt();
// Add a border around the matrix with values of 1
int N = n + 2;
cell = new BitSet[N];
for (i = 0; i < cell.length; i++)
cell[i] = new BitSet(N);
for (i = 0; i < cell.length; i++) {
set(cell, 0, i);
set(cell, i, 0);
set(cell, i, N-1);
set(cell, N-1, i);
}
set(cell, nCurrRow, nCurrCol);
R = (long)n * n - 1; // Number of remaining unvisited cells
int sec1 = in.nextInt();
int sec2 = 0;
String dir1 = in.next();
String dir2;
for (i = 0; i < k - 1; i++) {
sec2 = in.nextInt();
dir2 = in.next();
move(sec2-sec1, dir1);
dir1 = dir2;
sec1 = sec2;
}
move(n, dir1);
System.out.println(R);
in.close();
}
static void move(int t, String dir1) {
boolean canMove = true;
int xDir = 0;
int yDir = 0;
if (dir1.equals("SE")) {
xDir = 1;
yDir = 1;
} else if (dir1.equals("NE")) {
xDir = 1;
yDir = -1;
} else if (dir1.equals("E")) {
xDir = 1;
} else if (dir1.equals("N")) {
yDir = -1;
} else if (dir1.equals("NW")) {
xDir = -1;
yDir = -1;
} else if (dir1.equals("W")) {
xDir = -1;
} else if (dir1.equals("SW")) {
xDir = -1;
yDir = 1;
} else if (dir1.equals("S")) {
yDir = 1;
}
for (int j = 0; j < t && canMove; j++) {
if (!isSet(cell,nCurrRow + yDir, nCurrCol + xDir)) {
nCurrRow += yDir;
nCurrCol += xDir;
set(cell, nCurrRow, nCurrCol);
R--;
} else
canMove = false;
}
}
static boolean isSet(BitSet[] cell, int x, int y) {
return cell[x].get(y);
}
static void set(BitSet[] cell, int x, int y) {
cell[x].set(y);
}
}
EDIT: Replacing Scanner with BufferedReader
There is a chance that Scanner is too slow:
https://www.cpe.ku.ac.th/~jim/java-io.html
This may be worth a try:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.BitSet;
import java.util.StringTokenizer;
public class Robot3 {
static int nCurrRow = 1;
static int nCurrCol = 1;
static long R = 0;
static BitSet[] cell;
public static void main(String[] args) throws IOException {
Reader.init(System.in);
//Scanner in = new Scanner(System.in);
int i = 0;
int n = Reader.nextInt();
int k = Reader.nextInt();
// Add a border around the matrix with values of 1
int N = n + 2;
cell = new BitSet[N];
for (i = 0; i < cell.length; i++)
cell[i] = new BitSet(N);
for (i = 0; i < cell.length; i++) {
set(cell, 0, i);
set(cell, i, 0);
set(cell, i, N-1);
set(cell, N-1, i);
}
set(cell, nCurrRow, nCurrCol);
R = (long)n * n - 1; // Number of remaining unvisited cells
int sec1 = Reader.nextInt();
int sec2 = 0;
String dir1 = Reader.next();
String dir2 = "";
for (i = 0; i < k - 1; i++) {
sec2 = Reader.nextInt();
dir2 = Reader.next();
move(sec2-sec1, dir1);
dir1 = dir2;
sec1 = sec2;
}
move(n, dir1);
System.out.println(R);
}
static void move(int t, String dir1) {
boolean canMove = true;
int xDir = 0;
int yDir = 0;
if (dir1.equals("SE")) {
xDir = 1;
yDir = 1;
} else if (dir1.equals("NE")) {
xDir = 1;
yDir = -1;
} else if (dir1.equals("E")) {
xDir = 1;
} else if (dir1.equals("N")) {
yDir = -1;
} else if (dir1.equals("NW")) {
xDir = -1;
yDir = -1;
} else if (dir1.equals("W")) {
xDir = -1;
} else if (dir1.equals("SW")) {
xDir = -1;
yDir = 1;
} else if (dir1.equals("S")) {
yDir = 1;
}
for (int j = 0; j < t && canMove; j++) {
if (!isSet(cell,nCurrRow + yDir, nCurrCol + xDir)) {
nCurrRow += yDir;
nCurrCol += xDir;
set(cell, nCurrRow, nCurrCol);
R--;
} else
canMove = false;
}
}
static boolean isSet(BitSet[] cell, int x, int y) {
return cell[x].get(y);
}
static void set(BitSet[] cell, int x, int y) {
cell[x].set(y);
}
static class Reader {
static BufferedReader reader;
static StringTokenizer tokenizer;
/** call this method to initialize reader for InputStream */
static void init(InputStream input) {
reader = new BufferedReader(
new InputStreamReader(input) );
tokenizer = new StringTokenizer("");
}
/** get next word */
static String next() throws IOException {
while ( ! tokenizer.hasMoreTokens() ) {
//TODO add check for eof if necessary
tokenizer = new StringTokenizer(
reader.readLine() );
}
return tokenizer.nextToken();
}
static int nextInt() throws IOException {
return Integer.parseInt( next() );
}
static double nextDouble() throws IOException {
return Double.parseDouble( next() );
}
}
}
EDIT: Using a Set to store visited cells
It turns out that when n is large, creating BitSets is an expensive process. About 1.4s was taken just to create the array of BitSets. So arrays don't work, and BitSet creation is slow. After some thought, I realized that a regular HashSet<Long> should work to store visited cells, and it doesn't have the same cost to create it.
public class Robot4 {
static int nCurrRow = 1;
static int nCurrCol = 1;
static long R = 0;
static Set<Long> cell;
static long N;
public static void main(String[] args) throws IOException {
Reader.init(System.in);
int i = 0;
int n = Reader.nextInt();
int k = Reader.nextInt();
// Add a border around the matrix with values of 1
N = n + 2L;
cell = new HashSet<Long>(1000000);
for (i = 0; i < N; i++) {
set(0, i);
set(i, 0);
set(i, n+1);
set(n+1, i);
}
set(nCurrRow, nCurrCol);
R = (long)n * n - 1; // Number of remaining unvisited cells
int sec1 = Reader.nextInt();
int sec2 = 0;
String dir1 = Reader.next();
String dir2 = "";
for (i = 0; i < k - 1; i++) {
sec2 = Reader.nextInt();
dir2 = Reader.next();
move(sec2-sec1, dir1);
dir1 = dir2;
sec1 = sec2;
}
move(n, dir1);
System.out.println(R);
}
static void move(int t, String dir1) {
boolean canMove = true;
int xDir = 0;
int yDir = 0;
if (dir1.equals("SE")) {
xDir = 1;
yDir = 1;
} else if (dir1.equals("NE")) {
xDir = 1;
yDir = -1;
} else if (dir1.equals("E")) {
xDir = 1;
} else if (dir1.equals("N")) {
yDir = -1;
} else if (dir1.equals("NW")) {
xDir = -1;
yDir = -1;
} else if (dir1.equals("W")) {
xDir = -1;
} else if (dir1.equals("SW")) {
xDir = -1;
yDir = 1;
} else if (dir1.equals("S")) {
yDir = 1;
}
for (int j = 0; j < t && canMove; j++) {
if (!isSet(nCurrRow + yDir, nCurrCol + xDir)) {
nCurrRow += yDir;
nCurrCol += xDir;
set(nCurrRow, nCurrCol);
R--;
} else
canMove = false;
}
}
static boolean isSet(int x, int y) {
return cell.contains(indexId(x,y));
}
static void set(int x, int y) {
cell.add(indexId(x,y));
}
static long indexId(int x, int y) {
return x*N+y;
}
static class Reader {
static BufferedReader reader;
static StringTokenizer tokenizer;
/** call this method to initialize reader for InputStream */
static void init(InputStream input) {
reader = new BufferedReader(
new InputStreamReader(input) );
tokenizer = new StringTokenizer("");
}
/** get next word */
static String next() throws IOException {
while ( ! tokenizer.hasMoreTokens() ) {
tokenizer = new StringTokenizer(
reader.readLine() );
}
return tokenizer.nextToken();
}
static int nextInt() throws IOException {
return Integer.parseInt( next() );
}
static double nextDouble() throws IOException {
return Double.parseDouble( next() );
}
}
}
I have the current code used to complete one of the Project Euler tasks:
public static void mod(int value){
int[] modValues = {11,12,13,14,15,16,17,18,19,20};
int y = 0;
for(int x = 0; x < 10; x++){
int originalValue = value;
int modSum = value % modValues[x];
if(modSum == 0){
y += 1;
if(y == 10){
System.out.println(originalValue);
break;
}
}
}
}
public static void main(String[] args) {
final long startTime = System.nanoTime(); //<<<ignore//
int x;
for(x = 0; x < Integer.MAX_VALUE; x++){
mod(x);
}
}
Now my question is how can I get the whole program to break once the first value (232792560) is found from the method. My current break at the if(y == 10){ break;} does not do this.
public static int mod(int value){
int[] modValues = {11,12,13,14,15,16,17,18,19,20};
int y = 0;
for(int x = 0; x < 10; x++){
int originalValue = value;
int modSum = value % modValues[x];
if(modSum == 0){
y += 1;
if(y == 10){
System.out.println(originalValue);
return originalValue;
}
}
}
}
public static void main(String[] args) {
final long startTime = System.nanoTime(); //<<<ignore//
int x;
for(x = 0; x < Integer.MAX_VALUE; x++){
if(mod(x)==232792560){
// now it will break so just break it
break;
}
}
}
}
public static void mod(int value)
{
int[] modValues = {11,12,13,14,15,16,17,18,19,20};
int y = 0;
for(int x = 0; x < 10 && y != 10; x++)
{
int originalValue = value;
int modSum = value % modValues[x];
if(modSum == 0)
{
y += 1;
if(y == 10)
{
System.out.println(originalValue);
break;
}
}
}
}
Main Class
package edu.bsu.cs121.mamurphy;
public class GameOfLifeMain {
public static void main(String[] args) {
{
new GameOfLifeGUI();
System.out.println();
}
}
}
Tester Class
package edu.bsu.cs121.mamurphy;
import java.awt.Color;
import java.awt.Graphics;
import java.io.File;
import java.util.Scanner;
import javax.swing.JPanel;
public class tester extends JPanel
{
final static int ROW = 25, COL = 75;
final static char DOT = '.';
static char[][] grid = new char[ROW + 2][COL + 2];
static char[][] nextgrid = new char[ROW + 2][COL + 2];
boolean sameFlag;
boolean blankFlag;
public static void init(char[][] grid, char[][] nextgrid) {
for (int row = 0; row <= ROW + 1; row++) {
for (int col = 0; col <= COL + 1; col++) {
grid[row][col] = DOT;
nextgrid[row][col] = DOT;
}
}
}
public static void pause() {
try {
Thread.currentThread();
Thread.sleep(1000L);
} catch (InterruptedException e) {
}
}
public void begin() {
init(grid, nextgrid);
read(grid);
repaint(); // calls paintComponent
pause();
while (sameFlag == true && blankFlag == false) {
nextGen(grid, nextgrid);
}
}
public static void read(char[][] grid) {
Scanner world = new Scanner(System.in);
System.out.println("Type the file name of the world you'd like to create.");
String fileName = world.nextLine();
{
try {
world = new Scanner(new File(fileName));
} catch (Exception ex) {
System.out.println("Please insert a valid file name.");
}
for (int row = 1; row <= ROW; row++) {
String s = world.next();
for (int col = 1; col <= COL; col++) {
grid[row][col] = s.charAt(col - 1);
}
}
}
}
public void print(Graphics g) {
int x, y;
y = 20;
for (int row = 1; row <= ROW; row++) {
x = 20;
for (int col = 1; col <= COL; col++) {
g.drawString("" + grid[row][col], x, y);
x = x + 7;
}
y = y + 15;
}
}
public static int neighbors(char[][] grid, int r, int c) {
// counts the # of closest neighbors that are X's
int count = 0;
for (int row = r - 1; row <= r + 1; row++) {
for (int col = c - 1; col <= c + 1; col++) {
if (grid[row][col] == 'X') {
count++;
}
}
}
if (grid[r][c] == 'X') {
count = count - 1;
}
return count;
}
public static void nextGen(char[][] grid, char[][] nextgrid) {
for (int row = 1; row <= ROW; row++) {
for (int col = 1; col <= COL; col++) {
if (grid[row][col] == 'X') {
int count = 0;
{
if (grid[row][col - 1] == 'X')
count = count + 1;
if (grid[row][col + 1] == 'X')
count = count + 1;
if (grid[row - 1][col] == 'X')
count = count + 1;
if (grid[row - 1][col - 1] == 'X')
count = count + 1;
if (grid[row - 1][col + 1] == 'X')
count = count + 1;
if (grid[row + 1][col - 1] == 'X')
count = count + 1;
if (grid[row + 1][col] == 'X')
count = count + 1;
if (grid[row + 1][col + 1] == 'X')
count = count + 1;
}
if (count == 2 || count == 3) {
nextgrid[row][col] = 'X';
} else
nextgrid[row][col] = DOT;
}
if (grid[row][col] == DOT) {
int count1 = 0;
{
if (grid[row][col - 1] == 'X')
count1 = count1 + 1;
if (grid[row][col + 1] == 'X')
count1 = count1 + 1;
if (grid[row - 1][col] == 'X')
count1 = count1 + 1;
if (grid[row - 1][col - 1] == 'X')
count1 = count1 + 1;
if (grid[row - 1][col + 1] == 'X')
count1 = count1 + 1;
if (grid[row + 1][col - 1] == 'X')
count1 = count1 + 1;
if (grid[row + 1][col] == 'X')
count1 = count1 + 1;
if (grid[row + 1][col + 1] == 'X')
count1 = count1 + 1;
}
if (count1 == 3)
nextgrid[row][col] = 'X';
}
}
}
}
public static void copy(char[][] grid, char[][] nextgrid) {
for (int i = 0; i < ROW + 1; i++) {
for (int j = 0; j < COL + 1; j++) {
grid[i][j] = nextgrid[i][j];
}
}
}
public static boolean isEmpty(char[][] grid, char[][] nextgrid) {
boolean blankFlag = true;
for (int i = 0; i < ROW + 1; i++) {
for (int j = 0; j < COL + 1; j++) {
if (grid[i][j] != DOT) {
blankFlag = false;
}
}
}
return blankFlag;
}
public static boolean isSame(char[][] grid, char[][] nextgrid) {
boolean sameFlag = false;
for (int i = 0; i < ROW + 1; i++) {
for (int j = 0; j < COL + 1; j++) {
if (grid[i][j] == nextgrid[i][j]) {
sameFlag = true;
break;
}
}
}
return sameFlag;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);// erases panel Contents
g.setColor(Color.black);
if (sameFlag == false && blankFlag == false) {
print(g);
} else {
if (sameFlag == true) {
g.drawString("This worldis the same as the last one.", 10, 250);
}
if (blankFlag == true) {
g.drawString("Everyone died. Good job.", 10, 250);
}
}
}
}
GUI Class
package edu.bsu.cs121.mamurphy;
import javax.swing.*;
import java.awt.*;
//
public class GameOfLifeGUI extends JFrame {
public GameOfLifeGUI() {
super("Game of Life");
setSize(600, 445);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1, 2));
tester test1 = new tester();
test1.setBackground(Color.LIGHT_GRAY);
panel.add(test1);
setContentPane(panel);
setVisible(true);
Temp one = new Temp(test1);
one.start();
}
class Temp extends Thread {
tester anim;
public Temp(tester anim) {
this.anim = anim;
}
public void run()// for each instance of test begin will be executed
{
anim.begin();
}
}
}
Hi stackoverflow. I have been working on this game of life project for the last few days and I have hit one final wall in trying to finish it up. How do I make it proceed to the next generation?
I know for what I am required to do I need to ask the user if they wish to continue to the next generation or not. I know I need to use a scanner and then have a loop that checks to see what the user's input is, as well as a try catch to make sure the program doesn't crash if they type in anything that isn't what the program asks them to.
My only issue is that I do not know where to put this code at in my tester class (if that is actually where it needs to go).
Any help is greatly appreciated.
OK so I have programmed a Sudoku solver.. And when I run the debug to check if its going through everything.. it is.. But it does not seem to work. It will print it out, and it will change the "." to 0's. But thats as far as it goes. It will not change the 0's, to the numbers when it loops over it.
public class SudokuSolver {
int[][] sudoku;
String data;
public SudokuSolver()
{
getPuzzle();
solvePuzzle(0,0);
}
private void getPuzzle()
{
try
{
Scanner in = new Scanner(new File("C:/Users/Ben/workspace/Sudoku Solver/src/puzzle1.txt"));
sudoku = new int[9][9];
for(int y = 0; y<9;y++)
{
for(int x = 0; x<9; x++)
{
data = in.next();
if(data.equals("."))
sudoku[x][y]=0;
else
sudoku[x][y] = Integer.parseInt(data);
}
}
in.close();
}
catch(Exception e)
{
}
for(int y = 0; y<9; y++)
{
for(int x = 0; x<9; x++)
{
System.out.print(sudoku[x][y]);
if(x ==2 || x ==5)
System.out.print(" ");
if(x==8)
{
System.out.print("\n");
}
}
if(y == 2|| y == 5)
{
System.out.println(" ");
}
}
}
private boolean isValid(int x, int y, int num)
{
int xSection = x/3;
int ySection = y/3;
for ( int row = 0; row < sudoku.length; row++ )
{
if(sudoku[row][y] == num)
{
return false;
}
}
for( int col = 0; col < sudoku.length; col++)
{
if(sudoku[x][col] == num)
{
return false;
}
}
for(int box = 3*xSection; box < 3*xSection + 3; box++)
{
for(int boxY = 3*ySection; boxY < 3*ySection + 3; boxY++)
{
if(sudoku[box][boxY] == num)
{
return false;
}
}
}
return true;
}
private int xPosition(int x, int y)
{
if(x<8)
{
return x+1;
}
else
{
return 0;
}
}
private int yPosition(int x, int y)
{
if(x<8)
{
return y;
}
else
{
return y+1;
}
}
private boolean solvePuzzle(int x, int y)
{
if( x >= 9 || y >= 9)
{
return true;
}
else
{
for(int num = 1; num < 10; num++)
{
if(isValid(x,y,num))
{
sudoku[x][y] = num;
if( solvePuzzle(xPosition(x,y), yPosition(x,y)) )
{
return true;
}
else
{
sudoku[x][y] = 0;
}
}
}
return false;
}
}
public static void main(String args[])
{
SudokuSolver solver = new SudokuSolver();
}
}
You're printing the puzzle inside the getPuzzle-method, which is before solvePuzzle has been called. You need to print the puzzle after it has been solved.
A positive number n is consecutive-factored if and only if it has factors, i and j where i > 1, j > 1 and j = i +1. I need a function that returns 1 if its argument is consecutive-factored, otherwise it returns 0.For example, 24=2*3*4 and 3 = 2+1 so it has the function has to return 1 in this case.
I have tried this:
public class ConsecutiveFactor {
public static void main(String[] args) {
// TODO code application logic here
Scanner myscan = new Scanner(System.in);
System.out.print("Please enter a number: ");
int num = myscan.nextInt();
int res = isConsecutiveFactored(num);
System.out.println("Result: " + res);
}
static int isConsecutiveFactored(int number) {
ArrayList al = new ArrayList();
for (int i = 2; i <= number; i++) {
int j = 0;
int temp;
temp = number %i;
if (temp != 0) {
continue;
}
else {
al.add(i);
number = number / i;
j++;
}
}
System.out.println("Factors are: " + al);
int LengthOfList = al.size();
if (LengthOfList >= 2) {
int a =al(0);
int b = al(1);
if ((a + 1) == b) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
}
Can anyone help me with this problem?
First check if its even, then try trial division
if(n%2!=0) return 0;
for(i=2;i<sqrt(n);++i) {
int div=i*(i+1);
if( n % div ==0) { return 1; }
}
return 0;
very inefficient, but fine for small numbers. Beyond that try a factorisation algorithm from http://en.wikipedia.org/wiki/Prime_factorization.
I have solved my problem with the above code. Following is the code.
public class ConsecutiveFactor {
public static void main(String[] args) {
// TODO code application logic here
Scanner myscan = new Scanner(System.in);
System.out.print("Please enter a number: ");
int num = myscan.nextInt();
int res = isConsecutiveFactored(num);
System.out.println("Result: " + res);
}
static int isConsecutiveFactored(int number) {
ArrayList al = new ArrayList();
for (int i = 2; i <= number; i++) {
int j = 0;
int temp;
temp = number % i;
if (temp != 0) {
continue;
}
else {
al.add(i);
number = number / i;
j++;
}
}
Object ia[] = al.toArray();
System.out.println("Factors are: " + al);
int LengthOfList = al.size();
if (LengthOfList >= 2) {
int a = ((Integer) ia[0]).intValue();
int b = ((Integer) ia[1]).intValue();
if ((a + 1) == b) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
}