Unable to print values from Java program - java

I'm coding a knights tour program for a project and I have to print out starting coordinates, move count, and ending coordinates but they won't print. The code compiles I just can't get it to print the values at the end. I left out the instance field because it said I'm not allowed to post that much code.
import java.util.Random;
public class NonHeuristic {
public static boolean boundCheck() {
if((randX + x) <= 7 && (randX + x) >= 0)
if((randY + y) <= 7 && (randY + y) >= 0) {
return true;
}
else {
return false;
}
else {
return false;
}
}
public static void moveGenerator() {
Random rand = new Random();
int z = 0;
while(z == 0){
randX = rand.nextInt(5) - 2;
if(randX % 2 == 0 && randX != 0) {
randY = rand.nextInt(3) - 1;
if(randY != 0 && boundCheck() && newMoveCheck()) {
xMove = randX;
yMove = randY;
z = 1;
}//close nested if
}//close if
else if(randX % 2 != 0 && randX != 0) {
randY = rand.nextInt(5) - 2;
if(randY != 0 && Math.abs(randY) > 1 && boundCheck() && newMoveCheck()) {
xMove = randX;
yMove = randY;
z = 1;
}//close nested if
}//close if loop
}//close while loop
}//close moveGenerator
public static void startPoint() {
Random start = new Random();
xStart = start.nextInt(8);
x = xStart;
yStart = start.nextInt(8);
y = yStart;
//System.out.println(xStart + " " + yStart);
}//close startPoint
public static boolean newMoveCheck() {
if(chessboard[randX + x][randY + y] == 0)
return true;
else
return false;
}//close newmoveCheck
public static void firstMove(){
moveCount = 0;
startPoint();
chessboard[x][y] = moveCount;
moveCount ++;
}//close firstMove
public static void move() {
for(int i = 1; i <= 64; i++) {
moveGenerator();
chessboard[x + xMove][y + yMove] = moveCount;
moveCount ++;
x = x + xMove;
y = y + yMove;
}
xEnd = x;
yEnd = y;
}//close move
}
public class NonHeuristicApplication extends NonHeuristic {
public static void main(String[] args) {
for(int j = 1; j < 10; j++) {
firstMove();
move();
System.out.print("[" + xStart + "," + yStart + "]," + moveCount + ",[" + xEnd + "," + yEnd + "]");
}
}
} //close class

I think you do not understand static variable. Your code is not compilable. To print required data, you have to get an instance with these values. It could be given NonHeuristic class.
Remember, that static variables and methods belong to class object but not to the class' instance, therefore all static variables and methods are the same for all instances for given class.
public class NonHeuristic {
private static final int SIZE = 8;
private final int[][] chessboard = new int[SIZE][SIZE];
private final Random random = new Random();
private int xStart;
private int yStart;
private int moveCount;
private int xEnd;
private int yEnd;
private int x;
private int y;
private int randX;
private int randY;
private int xMove;
private int yMove;
public static void main(String... args) {
NonHeuristic obj = new NonHeuristic();
for (int j = 1; j < 10; j++) {
obj.firstMove();
obj.move();
System.out.print("[" + obj.xStart + ',' + obj.yStart + "]," + obj.moveCount + ",[" + obj.xEnd + ',' + obj.yEnd + ']');
}
}
public void firstMove() {
moveCount = 0;
startPoint();
chessboard[x][y] = moveCount;
moveCount++;
}
public void startPoint() {
xStart = random.nextInt(SIZE);
x = xStart;
yStart = random.nextInt(SIZE);
y = yStart;
System.out.println(xStart + " " + yStart);
}
public void move() {
for (int i = 1; i <= SIZE * SIZE; i++) {
moveGenerator();
chessboard[x + xMove][y + yMove] = moveCount;
moveCount++;
x += xMove;
y += yMove;
}
xEnd = x;
yEnd = y;
}
public void moveGenerator() {
int z = 0;
while (z == 0) {
randX = random.nextInt(5) - 2;
if (randX % 2 == 0 && randX != 0) {
randY = random.nextInt(3) - 1;
if (randY != 0 && boundCheck() && newMoveCheck()) {
xMove = randX;
yMove = randY;
z = 1;
}
} else if (randX % 2 != 0) {
randY = random.nextInt(5) - 2;
if (randY != 0 && Math.abs(randY) > 1 && boundCheck() && newMoveCheck()) {
xMove = randX;
yMove = randY;
z = 1;
}
}
}
}
public boolean boundCheck() {
return (randX + x) <= 7 && (randX + x) >= 0 && (randY + y) <= 7 && (randY + y) >= 0;
}
public boolean newMoveCheck() {
return chessboard[randX + x][randY + y] == 0;
}
}

Related

How to write a number as sum of some other numbers' power

Okay firstly I'm sorry I know that I'm not intelligent enough. I'm bad at Math.
I couldn't write an algorithm to this question.
System gives us int x, int y, int boundary and wants us to find which numbers up to boundary satisfy the rule as
some_number = x^i + y^j
Boundary <= 10^6
i and j > = 0
x and y < 100
for example x = 2, y = 3 and boundary= 5,
2 = 2^0 + 3^0
3 = 2^1 + 3^0
4 = 2^0 + 3^1
5 = 2^1 + 3^1
output : 2,3,4,5
import java.util.ArrayList;
public class Main {
public static ArrayList<Integer> find_numbers(int x, int y, int boundary) {
ArrayList<Integer> res = new ArrayList<Integer>();
int num = 0;
int remain_x = 0, remain_y = 0;
int count_x = 0, count_y = 0;
if (boundary >= 2) {
res.add(2);
}
for (int i = 3; i <= boundary; ++i) {
if(i == x+y)
res.add(i);
count_x = 0;
count_y = 0;
num = i;
while (num > 0) {
remain_x = num % x;
if (remain_x == 0) {
count_x++;
} else {
while (num > 0) {
remain_y = num % y;
if (remain_y == 0) {
count_y++;
}
num = num / y;
}
}
num = num / x;
}
System.out.println("i =>" +i);
System.out.println("x=>" + count_x);
System.out.println("y =>" + count_y);
}
return res;
}
public static void main(String[] args) {
ArrayList<Integer> res = new ArrayList<Integer>();
int x = 1 + (int) (Math.random() * 100);
int y = 1 + (int) (Math.random() * 100);
int boundary = 1 + (int) (Math.random() * 1000000);
res = find_numbers(x, y, boundary );
System.out.println(res);
}
}
Edit:
I wrote something after reading Shark's comment thank you so much. it's working.
import java.util.ArrayList;
public class Main {
public static ArrayList<Integer> find_numbers(int x, int y, int boundary) {
ArrayList<Integer> res = new ArrayList<Integer>();
int x_k = 0;
int y_k= 0;
while(Math.pow(x,x_k)< boundary){
x_k++;
}
while(Math.pow(y,y_k)< boundary){
y_k++;
}
for(int k = 2 ; k<= boundary;++k) {
for (int i = 0; i < x_k; ++i) {
for (int j = 0; j < y_k; ++j) {
if(k == (int)Math.pow(x,i)+(int)Math.pow(y,j) && !res.contains(k)){
System.out.println("----------------------------------------");
System.out.println(k +" =>" +x + "^" +i +"+"+y+ "^" +j);
res.add(k);
}
}
}
}
return res;
}
public static void main(String[] args) {
ArrayList<Integer> res = new ArrayList<Integer>();
int x = 1 + (int) (Math.random() * 100);
int y = 1 + (int) (Math.random() * 100);
int boundary = 1 + (int) (Math.random() * 1000000);
res = find_numbers(x, y,boundary);
System.out.println("x:" + x);
System.out.println("y:" + y);
System.out.println("boundary:" + boundary);
System.out.println("Result:" + res);
}
}
I am not sure if this is the most efficient method. Basically, I increment j until x^i + y^j > boundary then increment i.
public static ArrayList<Integer> findNumbers(int x, int y, int boundary) {
Set<Integer> result = new HashSet<>(); // make sure result is unique
int powerX = 0, powerY = 0, total = 0, tempX = 0;
while (true) {
// calculate x^i
tempX = (int) Math.pow(x, powerX);
while (true) {
// calculate x^i + y^j and compare against boundary
if ((total = tempX + (int) Math.pow(y, powerY)) <= boundary) {
// add result to set and increment y
result.add(total);
powerY++;
// break if y <= 1
if (y <= 1)
break;
} else
break;
}
// break if x <= 1 || x^i > boundary
if (tempX > boundary || x <= 1)
break;
// reset j and increment i
powerY = 0;
powerX++;
}
// return sorted result
ArrayList<Integer> arr = new ArrayList<>();
arr.addAll(result);
arr.sort(null);
return arr;
}
You might be able refactor the code for better efficiency.
public class Main {
public static ArrayList<Integer> find_numbers(int x, int y, int boundary) {
ArrayList<Integer> res = new ArrayList<Integer>();
int x_k = 0;
int y_k= 0;
while(Math.pow(x,x_k)< boundary){
x_k++;
}
while(Math.pow(y,y_k)< boundary){
y_k++;
}
for(int k = 2 ; k<= boundary;++k) {
for (int i = 0; i < x_k; ++i) {
for (int j = 0; j < y_k; ++j) {
if(k == (int)Math.pow(x,i)+(int)Math.pow(y,j) && !res.contains(k)){
System.out.println("----------------------------------------");
System.out.println(k +" =>" +x + "^" +i +"+"+y+ "^" +j);
res.add(k);
}
}
}
}
return res;
}
public static void main(String[] args) {
ArrayList<Integer> res = new ArrayList<Integer>();
int x = 1 + (int) (Math.random() * 100);
int y = 1 + (int) (Math.random() * 100);
int boundary = 1 + (int) (Math.random() * 1000000);
res = find_numbers(x, y,boundary);
System.out.println("x:" + x);
System.out.println("y:" + y);
System.out.println("boundary:" + boundary);
System.out.println("Result:" + res);
}
}

Space Invader project

Hi I have been working on a space invader game in processing, I am relatively new to java/coding. What my problem is that I do not really understand how to make the collision actually work, and also my aliens (which are the space ships), they move left to right but do not move down. These are the 2 major problems that I am having a hard time solving. This is my code underneath, any professional advice would be appreciated.
PImage SpaceShip;
PImage Laser;
int TankX = 450;
int TankY = 450;
int SpaceshipX = 20;
int SpaceshipY = 20;
int MoveSpaceShipDown = 5;
int TankSizeX = 200;
int TankSizeY = 90;
int ShipSizeX = 90;
int ShipSizeY = 80;
int Xtankspeed = 2;
int LaserX = 9999;
int LaserY = TankY;
int LasersizeX = 10;
int LasersizeY = 40;
int spaceShipDirection = 5;
int spaceshipxspeed = 2;
int spaceshipSpeed = 5;
//int Xtankspeed2 = -6;
boolean moveRight = false;
boolean moveLeft = false;
boolean ShowLaser = false;
int[] ShipX = new int [15];
int [] ShipY = new int [4];
int gameState = 1;
int StopWatch = 0;
void setup() {
size(1000, 500);
imageMode(CENTER);
SpaceShip = loadImage("Spaceship.png");
SpaceShip.resize( ShipSizeX, ShipSizeY );
Laser = loadImage ("LaserBeam.png");
Laser.resize(LasersizeX, LasersizeY);
Tank = loadImage("Tank.png");
Tank.resize(TankSizeX, TankSizeY);
setSpaceShipPositions();
}
void setSpaceShipPositions() {
for(int j = 0; j < ShipY.length; j++){
for (int i = 0; i < ShipX.length; i++) {
ShipX[i] = 50 + 50*i;
}
ShipY[j] = 50 + 50*j;
}
}
void draw() {
if (gameState == 1) {
IntroScreen();
} else if (gameState == 2) {
startGame();
}
}
void IntroScreen() {
background(#000000);
textMode(CENTER);
textSize(50);
text("Space Defenders", 325, 250);
}
void startGame() {
background (#2f3069);
MakeLaser();
Maketank();
Maketankmove();
checkiftankhitedge();
for (int j = 0; j < ShipY.length; j++) {
for (int i = 0; i < ShipX.length; i++) {
MakeSpaceShip(i,j);
moveSpaceShip();
checkiflaserhitspaceship(i,j);
}
}
Shootlaser();
Makelaserreturentoorignalposition();
//makespaceshipgodown();
}
void keyPressed() {
println(keyCode);
if (keyCode == 39) { //right key
moveRight = true;
}
if (keyCode == 37) { //leftkey
moveLeft = true;
}
if (keyCode == 32 && ShowLaser == false) { //Spacebar
ShowLaser = true;
LaserX = TankX;
LaserY = TankY;
}
if (keyCode == 10) {
gameState = 2;
}
}
void keyReleased() {
if (keyCode == 39) { //right key
moveRight = false;
}
if (keyCode == 37) { //leftkey
moveLeft = false;
}
if (keyCode == 32) { //Spacebar
}
}
void Maketank() {// this is to make the tank
//PImage.resize(0,5);
imageMode(CENTER);
image(Tank, TankX, TankY);
}
void MakeLaser() {
if (ShowLaser) {
image(Laser, LaserX, LaserY);
}
}
void MakeSpaceShip(int i, int j) {
image(SpaceShip, ShipX[i], ShipY[j]);
//for (int i = 0; i < spaceShipX.length; i++){
// image( spaceShipX[i] - 15, ,SpaceshipX, SpaceshipY ); Confused
}
int lastlaptime = 0;
int timesincelastlap = 0;
//void moveSpaceShip(int i, int j) {
/*StopWatch = millis();
timesincelastlap = StopWatch - lastlaptime;
if (timesincelastlap > 500) {
spaceShipX[i] += spaceshipxspeed;
lastlaptime = millis();
// if (spaceShipX[i] > 990) {
// SpaceshipY = SpaceshipY + 30;
//spaceShipDirection = -1*spaceShipDirection;
// }
//if (spaceShipX[i] < 10) {
// SpaceshipY = SpaceshipY + 30;
//spaceShipDirection = -1*spaceShipDirection;
//}
//}
}*/
void moveSpaceShip() {
/*for (int i = 0; i < 15; i++){
if (spaceShipX[40] > 990){
spaceShipDirection = -1*spaceShipDirection;
SpaceshipY = SpaceshipY + 30;
}
if (spaceShipX[1] < 10){
spaceShipDirection = -1*spaceShipDirection;
SpaceshipY = SpaceshipY + 30;
}
}
for (int i = 0; i < 15; i++){
spaceShipX[i] = spaceShipX[i] + spaceShipDirection;
}*/
if (millis() - StopWatch > 1000) {
StopWatch = millis();
checkIfHitEdge();
moveShips();
}
}
void moveShips() {
for (int i = 0; i < 15; i++) {
ShipX[i] = ShipX[i] + spaceShipDirection*spaceshipSpeed;
}
}
void checkIfHitEdge() {
for (int i = 0; i < 15; i++) {
if (ShipX[14] > 990) {
SpaceshipY = SpaceshipY + 5;
spaceShipDirection = -1*spaceShipDirection;
}
if (ShipX[0] < 10) {
spaceShipDirection = -1*spaceShipDirection;
SpaceshipY = SpaceshipY + 5;
}
}
}
//void makespaceshipgodown(){
// if(SpaceshipX + 45 > width){
//SpaceshipY++;
// }
//}
void Maketankmove() {
if (moveLeft == true) {
TankX--; //this makes the tank go left
TankX = TankX - Xtankspeed;//this is for the speed of the tank
}
if (moveRight == true) {
TankX++;//this makes the tank go right
TankX = TankX + Xtankspeed;//the speed of the tank
}
}
void checkiftankhitedge() {
if (TankX > width-50) {
TankX = 950;
moveRight = false;
}
if (TankX-100 < -50) {
TankX = 50;
moveLeft = false;
}
}
void Makelaserreturentoorignalposition() {
//if(TankX++){
if (LaserY == 0) {
LaserY = TankY;
LaserX = 9999;
ShowLaser = false;
}
}
void checkiflaserhitspaceship(int i, int j) {
/* int Lasertop = LasersizeY - 20;
int Laserbottom = LasersizeY + 20;
int LaserLeft= LasersizeX - 5;
int LaserRight = LasersizeX +5;
int SpaceShipBottom = ShipY[j] - 40;
int SpaceShipTop = ShipY[j] + 40;
int SpaceShipleft = spaceShipX[i] - 45;
int SpaceShipright = spaceShipX[i] + 45;
boolean LaserhitSpaceship = Lasertop > SpaceShipBottom &&
Laserbottom < SpaceShipTop &&
LaserLeft < SpaceShipright &&
LaserRight > SpaceShipleft;
if(LaserhitSpaceship == true){
spaceShipX[0] = 90000;
}*/
}
void Shootlaser() {
if (ShowLaser == true) {
LaserY-=5;
}
}```
Here is what I think the issues are. First of all, processing is not the best language to make a game like Space Invaders. You can't have multiple key inputs at once. For example, if I press the left arrow, hold it, then press the right arrow, and let go of the left arrow, processing will ignore the left arrow. Processing has one key input: key. It can only have one value. You can't track multiple inputs at once. You can maybe replace it with your mouse - if the mouse is far to the left, move left. If it is far to the right, move right. In the middle? Stay still.
Aside from that, you want to check for collision. First of all, make the enemy into an object. I am assuming you know how to make objects. If not, look at this tutorial. Now, we need to check for collision. I'd suggest making a collision method inside of the enemy class, and here is what i'd imagine it to be:
boolean collidingWithPlayer() {
return (playerX > enemyX && playerX < enemyX + enemyW
&& playerY > enemyY && playerY < enemyY + enemyH);
}
Use this as you will. Good luck with your game.

Stack Overflow Error in a Self Calling Function in Java (Number of Islands)

I did some research on what causes a stack overflow errors, and I can conclude it is being caused by a recursive function in a program that is supposed to "count the number of islands" in an array. I understand what is causing the issue, but not sure why this is happening, or my main question is what to actually do about it. I found that if I slow down the program by having it repeatedly printing out something to the console, it works, but it takes forever to complete. Is there a way I can keep the program speed without the error, or a better way to solve the problem (search up "number of islands" to find the problem). Also, the array is two dimensional with a size of 1050 by 800.
public class NumOfIslands {
static boolean[][] dotMap = new boolean[1050][800];
static boolean visited[][] = new boolean[1050][800];
static int total = 0;
public static void main(String args[]) {
defineArrays();
run();
}
public static void findObjects(int xCord, int yCord) {
for(int y = yCord - 1; y <= yCord + 1; y++) {
for(int x = xCord - 1; x <= xCord + 1; x++) {
if(x > -1 && y > -1 && x < dotMap[0].length && y < dotMap.length) {
if((x != xCord || y != yCord) && dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
findObjects(x,y);
//System.out.println("test");
}
}
}
}
}
public static void defineArrays() {
for(int y = 0; y < 800; y++) {
for(int x = 0; x < 1050; x++) {
dotMap[x][y] = true;
}
}
}
public static int run() {
//dotMap = DisplayImage.isYellow;
System.out.println(dotMap.length + " " + dotMap[0].length);
int objects = 0;
for(int y = 439; y < 560/*dotMap[0].length*/; y++) {
for(int x = 70; x < 300/*dotMap.length*/; x++) {
if(dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
objects++;
findObjects(x,y);
}
}
}
System.out.println("total" + total);
System.out.println(objects);
return objects;
}
}
StackOverflowError reasons. In your example each call to findObjects adds 2 variables to the stack int x and int y from loops.
One of the fastest solution:
class Solution {
int m, n;
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
m = grid.length;
n = grid[0].length;
int counter = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
visit(grid, i, j);
counter++;
}
}
}
return counter;
}
public void visit(char[][] grid, int i, int j) {
if (i < 0 || i >= m || j < 0 || j >= n) {
return;
}
if (grid[i][j] == '0') {
return;
}
grid[i][j] = '0';
visit(grid, i - 1, j);
visit(grid, i + 1, j);
visit(grid, i, j - 1);
visit(grid, i, j + 1);
}
}
All recursive algorithms can be implemented with loops. One of the example is below. The Solution implements BFS (Breadth-first search) algorithm, more details on wikipedia.
class Solution {
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
int nr = grid.length;
int nc = grid[0].length;
int num_islands = 0;
for (int r = 0; r < nr; ++r) {
for (int c = 0; c < nc; ++c) {
if (grid[r][c] == '1') {
++num_islands;
grid[r][c] = '0'; // mark as visited
Queue<Integer> neighbors = new LinkedList<>();
neighbors.add(r * nc + c);
while (!neighbors.isEmpty()) {
int id = neighbors.remove();
int row = id / nc;
int col = id % nc;
if (row - 1 >= 0 && grid[row-1][col] == '1') {
neighbors.add((row-1) * nc + col);
grid[row-1][col] = '0';
}
if (row + 1 < nr && grid[row+1][col] == '1') {
neighbors.add((row+1) * nc + col);
grid[row+1][col] = '0';
}
if (col - 1 >= 0 && grid[row][col-1] == '1') {
neighbors.add(row * nc + col-1);
grid[row][col-1] = '0';
}
if (col + 1 < nc && grid[row][col+1] == '1') {
neighbors.add(row * nc + col+1);
grid[row][col+1] = '0';
}
}
}
}
}
return num_islands;
}
}
the problem is in this function
public static void findObjects(int xCord, int yCord) {
for(int y = yCord - 1; y <= yCord + 1; y++) {
for(int x = xCord - 1; x <= xCord + 1; x++) {
if(x > -1 && y > -1 && x < dotMap[0].length && y < dotMap.length) {
if((x != xCord || y != yCord) && dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
findObjects(x,y);
//System.out.println("test");
}
}
}
}
}`
at here you are builiding a stack of recursive calls to findobjects and ultimately it has no termination condition so it ends up at infinite stacks of findobjects, so my solution is if you are just checking that if x and y varaibles are not equal and visited[x][y] is not true then there is no need to call for recursion just comment the recursive call, because your loop already do what you want the recursive call to do.
public static void findObjects(int xCord, int yCord) {
for(int y = yCord - 1; y <= yCord + 1; y++) {
for(int x = xCord - 1; x <= xCord + 1; x++) {
if(x > -1 && y > -1 && x < dotMap[0].length && y < dotMap.length) {
if((x != xCord || y != yCord) && dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
//findObjects(x,y);
//System.out.println("test");
}
}
}
}
}

problems occured when solving mazes using DFS

I am doing an assignment which creates a maze and then solves it,
I simulate the maze as an array,
using 1 to represent the wall, 0 -- road, 5 -- start, 9 -- destination
if the road has been used, change its value to 2;
it works well for creating mazes,
In most cases, it can find the path to the destination, but sometimes it still pops error stating "empty stack error", like the picture shows...
[]
I can't find the problem(s), may you help me out?
package MazeDFS;
import java.util.Random;
import java.util.Stack;
public class maze {
public static void main(String[] args) {
//create maze
//and solve it
//define the size as 9*9
int r,c;
r = 9;
c = 9;
int[][] newMaze = mazeGenerator(r,c);
newMaze[1][1] = 5;
mazePrinter(newMaze,r,c);
Stack<Step> path = new Stack<Step>();
Step s0 = new Step(1,1);
path.push(s0);
long startTime = System.nanoTime();
newMaze = solve(newMaze, 1, 1, path);
long endTime = System.nanoTime();
System.out.println("Time length:" + (endTime - startTime));
}
public static int[][] mazeGenerator(int x, int y){
Random randNum = new Random();
/*I simulated the maze as a x*y array
Values of the array represent elements of the maze
0 -- road, 1 -- wall, 5 -- start, 9 -- destination
*/
int[][] maze = new int[x][y];
for(int i = 0; i < x; i++) {
for(int j = 0; j < y; j++) {
//bound of the maze
if(i==0 || j==0 || i==x-1 || j==y-1) {
maze[i][j] = 1;
}
//build walls
if(j%2 == 0) {
maze[i][j] = 1;
}
}
}
//randomly choose a row of every wall and make it a road
for(int i = 1; i < y-1; i++) {
int row = randNum.nextInt(x-2)+1;
maze[row][i] = 0;
}
maze[x-2][y-2] = 9;
return maze;
}
public static void mazePrinter(int[][] maze,int x, int y) {
for(int i=0; i<x; i++) {
for(int j=0; j<y; j++) {
System.out.print(maze[i][j]);
}
System.out.println();
}
}
public static int[][] solve(int[][] newMaze, int x, int y, Stack<Step> path) {
mazePrinter(newMaze, 9,9);
System.out.println();
if(newMaze[x][y] == 9) {
Step s = new Step(x,y);
newMaze[x][y] = 2;
path.push(s);
return newMaze;
}
//going down
int dx = 1;
int dy = 0;
if(newMaze[x+dx][y+dy] == 0 || newMaze[x+dx][y+dy] == 9) {
//if visited mark as 2
if(newMaze[x+dx][y+dy] != 9) {
newMaze[x+dx][y+dy] = 2;
}
Step ss = new Step(x+dx,y+dy);
path.push(ss);
System.out.println("going down");
return solve(newMaze, x+dx, y+dy, path);
}
//going up
dx = -1;
dy = 0;
if(newMaze[x+dx][y+dy] == 0 || newMaze[x+dx][y+dy] == 9) {
//if visited mark as 2
if(newMaze[x+dx][y+dy] != 9) {
newMaze[x+dx][y+dy] = 2;
}
Step ss = new Step(x+dx,y+dy);
path.push(ss);
System.out.println("going up");
return solve(newMaze, x+dx, y+dy, path);
}
//turn right
dx = 0;
dy = 1;
if(newMaze[x+dx][y+dy] == 0 || newMaze[x+dx][y+dy] == 9) {
//if visited mark as 2
if(newMaze[x+dx][y+dy] != 9) {
newMaze[x+dx][y+dy] = 2;
}
Step ss = new Step(x+dx,y+dy);
path.push(ss);
System.out.println("turn right");
return solve(newMaze, x+dx, y+dy, path);
}
//turn left
dx = 0;
dy = -1;
if(newMaze[x+dx][y+dy] == 0 || newMaze[x+dx][y+dy] == 9) {
//if visited mark as 2
if(newMaze[x+dx][y+dy] != 9) {
newMaze[x+dx][y+dy] = 2;
}
Step ss = new Step(x+dx,y+dy);
path.push(ss);
System.out.println("turn left");
return solve(newMaze, x+dx, y+dy, path);
}
//if their is no way to go then turn back to the last step
Step sss = path.pop();
int x1 = sss.getX();
int y1 = sss.getY();
System.out.println("return to:"+"x1:"+x +", y1:"+ y);
return solve(newMaze, x1, y1, path);
}
}
class Step{
private int x;
private int y;
Step(int x, int y){
this.x = x;
this.y = y;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
}

Pseudo Infinite Loop (Optimally Deleting 'missing data' from a matrix)

When I use a random matrix (class Determine), my program runs successfully in 1700 miliseconds. However, when I create a matrix by reading a file through a buffered reader (class Construct) my program experiences a logic error and enters and infinite loop.
Again, it works for a random matrix, but does not work for a 'real' matrix of the same size. I've checked my work and cannot find an error in my reading of the file. Does anyone know what may be causing this logic error? I will append my code with comments if it helps!
Update: OK the problem was from my own silly oversight (see my answer below). This did not occur with random data due to my 'haveIt' method and the probability of getting missing data. As such, my code has been updated to reflect this logic error and I will be happy to explain in detail how this code works if anyone asks:
import java.util.Random;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.*;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.BufferedReader;
class ValMax {
public static int valMax;
}
class Construct {
private static int colEnd;
private static int colStart;
private static int[] colSkip;
public static List<List<Integer>> rFile(String[] args){
if (args.length != 4) {
System.out.println("Format: FileName colStart colEnd colSkipped");
System.exit(0);
}
BufferedReader reader = null;
try {
List<List<Integer>> matrix = new ArrayList<List<Integer>>();
Construct.colEnd = Integer.parseInt(args[2]);
Construct.colStart = Integer.parseInt(args[1]);
String[] colSkipped = args[3].split(",");
Construct.colSkip = new int[colSkipped.length];
for (int x = 0; x < colSkipped.length; x++) {
Construct.colSkip[x] = Integer.parseInt(colSkipped[x]);
}
String line;
reader = new BufferedReader(new FileReader(new File(args[0])));
while ((line = reader.readLine()) != null) {
String[] tokens = line.split(",");
List<Integer> rows = new ArrayList<Integer>(colEnd - colStart + 1 - colSkip.length);
for (int x = 1; x <= tokens.length; x++) {
if (x >= colStart && x <= colEnd && contains(x, colSkip) == false) {
try {
Double.parseDouble(tokens[x - 1]);
} catch (NumberFormatException e3) {
break;
}
if (tokens[x - 1].equals("-999")) { //
rows.add(2);
} else {
rows.add(1);
}
}
}
if (rows.size() == colEnd - colStart + 1 - colSkip.length) {
matrix.add(rows);
}
}
System.out.println(matrix.size() + "\t" + matrix.get(0).size());
return matrix;
} catch (IOException e1) {
System.out.println("IOEXCEPTION!!");
System.exit(0);
} catch (NumberFormatException e2) {
System.out.println("NumberFormatException!!");
System.exit(0);
} finally {
try {
reader.close();
} catch (IOException e5) {
e5.printStackTrace();
}
}
return null;
}
private static boolean contains(int a, int[] colSkip) {
boolean bluejay = false;
for (int skip : colSkip) {
if (a == skip) {
bluejay = true;
}
}
return bluejay;
}
}
class Determine {
private static Integer gen(int a, int b, Random r) {
Integer rand = r.nextInt(a) + b;
return rand;
}
public static List<List<Integer>> rando() {
Random r = new Random();
int k = gen(1, 24, r), l = gen(1, 33, r); //userinput
List<List<Integer>> matrix = new ArrayList<List<Integer>>(k);
for (int x = 1; x <= k; x++) {
List<Integer> row = new ArrayList<Integer>(l);
for (int y = 1; y <= l; y++) {
double bias = Math.random();
if (bias > 0.7) {
row.add(2);
} else {
row.add(1);
}
}
matrix.add(row);
}
return matrix;
}
}
class Search {
public static void finalize(List<List<Integer>> matTan, boolean gumDrop, int minimum) {
final int A = matTan.size();
final int B = matTan.get(0).size();
boolean judge = true;
if (minimum > A && gumDrop == false || minimum > B && gumDrop == true) {
System.out.print("\nMinimum too high\n\n");
System.exit(0);
}
ValMax.valMax = 1; //userinput
int[] rows = new int[2 + A + B];
List<int[]> combination = new ArrayList<int[]>(100);
int threads = Runtime.getRuntime().availableProcessors();
ExecutorService service = Executors.newFixedThreadPool(threads);
List<List<int[]>> ranTime = new ArrayList<List<int[]>>(2 * threads);
for (int x = 0; x < 2 * threads; x++) {
List<int[]> jobs = new ArrayList<int[]>(90);
ranTime.add(jobs);
}
if (gumDrop == false) {
for (int x = 1; x <= minimum; x++) {
rows[x] = 1;
}
} else {
rows[1] = 1;
}
rows[A + 1] = 999;
int y = 0, z = 0;
System.out.println(threads);
while (rows[A + 1] == 999) {
y++;
int[] copy = Arrays.copyOf(rows, rows.length);
if (y == 91) {
z++;
y = 1;
if (z < 2* threads) {
ranTime.get(z).clear();
}
}
if (z == 2 * threads) {
processInputs(ranTime, combination, matTan, minimum, gumDrop, service);
z = 0;
ranTime.get(0).clear();
ranTime.get(0).add(copy);
} else {
ranTime.get(z).add(copy);
}
nextComb(A, rows);
}
if (ranTime.get(0).size() > 0) {
for (int x = 0; x < 2 * threads; x++) {
if (judge == false) {
ranTime.remove(x);
threads--;
x--;
}
if (ranTime.get(x).size() != 90 && judge == true) {
judge = false;
}
}
processInputs(ranTime, combination, matTan, minimum, gumDrop, service);
}
service.shutdown();
try {
service.awaitTermination(60, TimeUnit.SECONDS);
} catch (InterruptedException e6) {
System.out.print("Termination Error!");
}
developed(matTan, combination, gumDrop);
}
private static void processInputs(List<List<int[]>> ranTime, List<int[]> combination, List<List<Integer>> matTan, int minimum, boolean gumDrop, ExecutorService service) {
Collection<StringTask> collection = new ArrayList<StringTask>(ranTime.size());
for (List<int[]> jobs : ranTime) {
StringTask analysis = new StringTask(jobs, combination, matTan, minimum, gumDrop);
collection.add(analysis);
}
try {
List<Future<Integer>> futures = service.invokeAll(collection);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void developed(List<List<Integer>> matTan, List<int[]> combination, boolean gumDrop) {
System.out.print("\n\n\n");
for (int[] e : combination) {
if (e[0] == ValMax.valMax) { // == ValMax.valMax
Optimize10.prin(e);
List<List<Integer>> complete = Multi.reduct1(e, matTan);
if (gumDrop == true) {
System.out.println("Solution Matrix, transposed [above data works on column]");
Optimize10.prin(Multi.transpose(complete)); //The solution matrix, reorientated
} else {
System.out.println("Solution Matrix");
Optimize10.prin(complete); //The solution matrix, reorientated
}
}
}
}
private static void nextComb(int bounds, int[] rows) {
int kappas = findMax(rows);
if (rows[bounds] == 0) {
rows[kappas + 1] = 1;
rows[kappas] = 0;
} else {
int y = 1;
int x = bounds;
while (rows[x] == 1) {
rows[x] = 0;
y++;
x--;
}
kappas = findMax(rows);
if (kappas != -1) {
rows[kappas] = 0;
}
int z = kappas + 1;
while (y > 0) {
rows[z] = 1;
z++;
y--;
}
}
}
private static int findMax(int[] rows) {
int y = 0;
for (int x = rows.length - 1; x >= 0; x--) {
if (rows[x] == 1) {
return x;
}
}
return y;
}
}
class StringTask implements Callable<Integer> {
private List<List<Integer>> matTan;
private List<int[]> combination;
private List<int[]> jobs;
private boolean gumDrop;
private int minimum;
StringTask(List<int[]> a, List<int[]> b, List<List<Integer>> c, int d, boolean e) {
this.combination = b;
this.minimum = d;
this.gumDrop = e;
this.matTan = c;
this.jobs = a;
}
public Integer call() {
for (int[] e : jobs) {
int temp = Multi.reduct2(e, matTan, minimum, gumDrop);
if (temp > ValMax.valMax) { //ValMax.valMax //userinput
ValMax.valMax = e[0]; //userinput
combination.add(e);
System.out.print(ValMax.valMax + " ");
}
}
return null;
}
}
class Multi {
public static int[] inverse;
public static void halveIt(int[] col, List<List<Integer>> matCop) {
int size = matCop.size(), a = 0;
inverse = new int[size];
for (int x = 0; x < size; x++) {
for (int y = 0; y < matCop.get(0).size(); y++) {
if (col[y] == 1 && matCop.get(x).get(y) == 2) {
inverse[x + a] = 1;
matCop.remove(x);
size--;
x--;
a++;
break;
}
}
}
}
public static List<List<Integer>> reduct1(int[] row, List<List<Integer>> matCan) {
List<List<Integer>> matTan = new ArrayList<List<Integer>>(matCan);
int with = matTan.size(), high = inverse.length, a = 0;
final int B = matCan.get(0).size() - 1;
final int A = matCan.size();
for (int x = 0; x < A; x++) {
List<Integer> value = new ArrayList<Integer>(matCan.get(x));
matTan.set(x, value);
}
int y = 0, size = 0;
for (int x = 0; x < high; x++) {
if (x < with) {
if (row[x + a + 1] > 0) {
size = matTan.get(0).size();
for (y = 0; y < size; y++) {
if (matTan.get(x).get(y) == 2) {
for (int z = 0; z < with ; z++) {
matTan.get(z).remove(y);
}
size--;
y--;
}
}
} else {
matTan.remove(x);
with--;
high--;
x--;
a++;
}
}
}
return matTan;
}
public static int reduct2(int[] row, List<List<Integer>> matCan, int minimum, boolean gumDrop) {
int b = 0, c = 0, d = 0, e = 0, g = 0, high = inverse.length;
final int B = matCan.get(0).size() - 1;
final int A = matCan.size();
for (int x = 0; x < high; x++) {
if (x < A) {
if (row[x + 1] > 0) {
b++;
for (int y = 0; y < B + 1; y++) {
if (matCan.get(x).get(y) == 2 && row[2 + A + y] == 0) {
row[2 + A + y] = 1; // 1s mean that a column was deleted, 0 is kept.
d -= e;
} else if (row[2 + A + y] == 0) {
d++;
}
}
e++;
}
}
if (inverse[x] == 0 && x < high || gumDrop == true && x < high) {
if (row[x - c + 1] == 1) {
row[x - c + 1] = 1 + c + g;
g++;
} else {
g++;
}
} else {
c++;
}
}
if (d / b < minimum && gumDrop == true) {
row[0] = 0;
d = 0;
} else {
row[0] = d;
}
return d;
}
public static List<List<Integer>> transpose(List<List<Integer>> matTan) {
int d = matTan.get(0).size();
List<List<Integer>> matFlip = new ArrayList<List<Integer>>(d);
for (int y = 0; y < d; y++) {
List<Integer> row = new ArrayList<Integer>();
for (int x = 0; x < matTan.size(); x++) {
row.add(matTan.get(x).get(y));
}
matFlip.add(row);
}
return matFlip;
}
}
// ########## Main Method Start ##########
public class Optimize10 {
public static void main(String[] args) {
double startTime = System.nanoTime() / 1000000;
List<List<Integer>> matrix = Determine.rando();
// List<List<Integer>> matrix = Construct.rFile(args);
List<List<Integer>> matTan = contract(new int[matrix.get(0).size()], matrix);
int a = matTan.size(), b = matTan.get(0).size();
System.out.println(a + "\t" + b);
boolean gumDrop = false;
int minimum = 40; //userinput
BigInteger aNew = new BigInteger("2");
BigInteger bNew = new BigInteger("2");
aNew = aNew.pow(a);
bNew = bNew.pow(b);
for (int x = 1; x < minimum; x++) {
aNew = aNew.subtract(binomial(a, x));
}
if (aNew.compareTo(bNew) > 0) {
gumDrop = true;
matTan = Multi.transpose(matTan);
}
System.out.println(gumDrop);
prin(matrix);
prin(matTan);
Search.finalize(matTan, gumDrop, minimum);
double endTime = System.nanoTime() / 1000000;
double duration = (endTime - startTime);
System.out.println(duration);
}
// ########## MAIN METHOD END ############
private static BigInteger binomial(final int N, final int K) {
BigInteger ret = BigInteger.ONE;
for (int k = 0; k < K; k++) {
ret = ret.multiply(BigInteger.valueOf(N-k)).divide(BigInteger.valueOf(k+1));
}
return ret;
}
private static List<List<Integer>> contract(int[] col, List<List<Integer>> matrix) {
List<List<Integer>> matCop = new ArrayList<List<Integer>>(matrix);
col[0] = 1; //userinput 1 means don't delete!
col[1] = 1; //userinput
col[2] = 1;
col[12] = 1;
col[14] = 1;
col[22] = 1;
col[28] = 1;
col[29] = 1;
Multi.halveIt(col, matCop);
return matCop;
}
public static void prin(List<List<Integer>> matrix) {
for (int x = 0; x < matrix.size(); x ++) {
System.out.print("[" + matrix.get(x).get(0));
for (int y = 1; y < matrix.get(0).size(); y++) {
System.out.print(" " + matrix.get(x).get(y));
}
System.out.print("]\n");
}
System.out.print("\n\n");
}
public static void prin(int[] a) {
System.out.print("[" + a[0]);
for (int x = 1; x < a.length; x ++) {
System.out.print(" " + a[x]);
}
System.out.print("]\n\n");
}
public static void prin(String[] a) {
System.out.print("[" + a[0]);
for (int x = 1; x < a.length; x ++) {
System.out.print(" " + a[x]);
}
System.out.print("]\n\n");
}
public static void prin2(List<Integer> a) {
System.out.print("[" + a.get(0));
for (int x = 1; x < a.size(); x ++) {
System.out.print(" " + a.get(x));
}
System.out.print("]\n\n");
}
}
OK, so there actually was no infinite loop in this code whatsoever. The problem was with line 466 of my code; specifically, I was basing whether I analyzed the original matrix or its transpose on the number of rows after truncation on the original matrix and subtracting the minimum. This is wrong because, for example,
sum_{i = 40)^{54}(54 choose i) >> 2^32.
My program was taking forever because it was told to traverse through over a trillion combinations instead of 'just' a few billion. Granted it can do 10 billion in about 2 hours, and I can save more time by inverting a few nested for loops (another time).
I Guess it's time to learn profiling to see where my code slows down.

Categories

Resources