Having trouble with weighted and unweighted quick union finds - java

TLDR at bottom
I've been assigned a programming project at school to build a percolation model and i've come across an issue which has given me quite some confusion. First off, we were supposed to build an api to run a percolation simulation
public class Percolation{
private int grid[][];
public int size;
QuickFindUF unionFind;
//WeightedQuickUnionUF unionFind;
public Percolation(int n)
{
if(n<1){
throw new IllegalArgumentException ("grid must be larger than 0");
}
grid=new int[n][n];
size=n;
unionFind=new QuickFindUF(size*size);
//unionFind=new WeightedQuickUnionUF(size*size);
//initially set all to blocked
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
grid[i][j]=1;
}
}
}
public void open(int x, int y)
{
grid[x][y]=0;
//Check below to see if you can
//if you are not on the bottom row
if(y>0)
{
if(grid[x][y]==0 && grid[x][y-1]==0){unionFind.union(x+y*size,x+(y-1)*size);}
}
//check to see to the right (x->)
if(x<size-1){
if(grid[x][y]==0 && grid[x+1][y]==0){unionFind.union(x+y*size,x+1+y*size);}
}
//check if can union to the left
if(x>0)
{
if(grid[x][y]==0 && grid[x-1][y]==0){unionFind.union(x+y*size,x-1+y*size);}
}
//check for above
if(y<size-1){
if(grid[x][y]==0 && grid[x][y+1]==0){unionFind.union(x+y*size,x+(y+1)*size);}
}
}
public boolean isOpen(int x, int y)
{
if(x>=size || y>=size){return false;}
if(grid[x][y]==0){return true;}
return false;
}
public boolean isFull(int x, int y)
{
if(x>=size || y>=size){return false;}//if input is out of bounds
for(int i=0;i<size;i++){
if(unionFind.connected(x+y*size,i+((size-1)*size)))
return true;
}
return false;
}
public boolean percolates()
{
for(int i=0;i<size;i++){
for(int j=0;j<size;j++){
if(unionFind.connected(i,(size-1)*size+j)){
//System.out.println(i+" "+((size-1)*size+j));
return true;
}
}
}
return false;
}
}
Now, the book kindly provides the quickfindUF and WeightedQuickUnionUF. All the classmates i've talked to have gotten the expected results when timing with a PercolationStats class which we've been instructed to make but my results very greatly. Here's the class
class PercolationStats{
private Percolation perc;
private double[] array;
private int expCount;
public PercolationStats(int gridSize, int numOfExperiments){
if(gridSize <= 0 || numOfExperiments <=0)
throw new IllegalArgumentException("gridSize and numOfExperiments needs to be more than 0");
array=new double[numOfExperiments];
expCount=numOfExperiments;
for(int i=0;i<numOfExperiments;i++){
perc=new Percolation(gridSize);
int count=0;
while(!perc.percolates()){
int x=StdRandom.uniform(gridSize),y=StdRandom.uniform(gridSize);
if(!perc.isOpen(x,y)){
perc.open(x,y);
count++;
}
}
array[i]=(double) count/(gridSize*gridSize);
}
}
public double mean(){
return StdStats.mean(array);
}
public double stddev(){
return StdStats.stddev(array);
}
public double confidenceLo(){
return mean() - ((1.96 * stddev()) / Math.sqrt(expCount));
}
public double confidenceHi(){
return mean()+((1.96 * stddev()) / Math.sqrt(expCount));
}
public static void main(String[] args){
Stopwatch timer=new Stopwatch();
PercolationStats percStats=new PercolationStats(200,100);
System.out.println("mean: "+ percStats.mean() +"stddev: "+percStats.stddev()+" confidence Lo: "+percStats.confidenceLo()+" confidence hi: "+percStats.confidenceHi());
System.out.println(timer.elapsedTime());
percStats=new PercolationStats(200,100);
System.out.println("mean: "+ percStats.mean() +"stddev: "+percStats.stddev()+" confidence Lo: "+percStats.confidenceLo()+" confidence hi: "+percStats.confidenceHi());
percStats=new PercolationStats(2,100000);
System.out.println("mean: "+ percStats.mean() +"stddev: "+percStats.stddev()+" confidence Lo: "+percStats.confidenceLo()+" confidence hi: "+percStats.confidenceHi());
}
}
When I run this with the QuickFindUF, at percStats(200,100), it takes me about 7 seconds, and if I run it at the same 200,100 with WeightedQuickUnionUF, It takes about 50+ seconds?? I was quite certain that the weighted quick union was supposed to be faster, and it's not just a matter of getting unlucky with my horrendous worst case random number generator. I ran it quite a few times and still the results were about the same and I've been staring here at the code for quite a while and can't figure out why my code is so wrong..
TLDR
Correct results, incorrect timing. Slower api is faster for some reason and I can't figure out why. QuickFindUF faster than WeightedQuickUnionUF. (about 7-8 times faster). What am I doing wrong?

Haha I'm dumb. I saw online that others were using a virtual top so I added one and now it works fine :P

Related

How would I write a toString and reduce duplicate outputs?

So, I've created a simple app for moving a bug along a wire. The code works well (for the most part) though, I am having a few issues.
When reaching the end of the wire, the program terminates all well and good but I'm getting a double output that it's fallen off the wire when it reaches the end.
I am supposed to be writing a toString for this, but am having a bit of a hard time grasping why and how I should go about doing this.
If someone could assist with this, I'd greatly appreciate it.
import java.util.Scanner;
public class ClassPracticeMain {
public static void main(String [] args) {
Scanner input = new Scanner(System.in);
int userInput;
Bug bug1 = new Bug();
bug1.setInitialPosition();
bug1.setInitialDirection();
System.out.println("Your starting position is " + bug1.initialPosition
+ " and you are facing " + bug1.getCurrentDirection()
);
while (bug1.getExit(1) != 0) {
System.out.println("Which way would you like to move? 1 for left/ 2 for right or 0 for exit");
userInput = input.nextInt();
bug1.move(userInput);
bug1.getCurrentDirection();
bug1.getCurrentPosition();
System.out.println("You are now at " + bug1.currentPosition + " and you are facing " + bug1.getCurrentDirection());
bug1.getExit(userInput);
}
}
}
public class Bug {
final int WIRELEFTEND=-15;
final int WIRERIGHTEND=15;
int initialPosition=0, currentPosition=0, direction,exit=1;
String currentDirection;
String left = "left";
String right = "right";
public int setInitialPosition(){
return initialPosition;
}
public int setInitialDirection(){
direction=1;
return direction;
}
public int getCurrentPosition(){
return currentPosition;
}
public String getCurrentDirection(){
if (direction== 1){
currentDirection=left;
} else if (direction == 2){
currentDirection=right;
}
return currentDirection;
}
public int move(int move){
if(move==1 && direction==1){
currentPosition=currentPosition-1;
return currentPosition;
} else if (move==1 && direction==2){
direction=1;
return currentPosition;
} else if (move==2 && direction==1){
direction=2;
return currentPosition;
} else if (move==2 && direction ==2){
currentPosition=currentPosition+1;
return currentPosition;
}
return 0;
}
public int getExit(int exit){
if(currentPosition<(WIRELEFTEND)||currentPosition>WIRERIGHTEND){
System.out.println("You've fallen off the wire... Oh no!");
exit=0;
} else{
exit=exit;
}
return 1;
}
}
You probably want to write
public int getExitStatus(){
if(currentPosition<(WIRELEFTEND)||currentPosition>WIRERIGHTEND){
System.out.println("You've fallen off the wire... Oh no!");
return 0;
}
return 1;
}
instead of your current getExist(int) function. It always returns 1, and setting the exit argument doesn't do anything.

How can I make a recursion back-track over itself?

I'm having an issue and I'm not certain if it's recursion-based. I created a GUI maze that solves itself but the curser jumps over any recursion-traveled square instead of re-traveling the square. Even though it ultimately finds the goal, I want to show it's entire path but I can't stop the curser from jumping around.
I'm using Runnable to track the maze in real-time so I can see it bounce but without the recursion-travel keeping it bound, the recursive functions cease to work (it just bounces back and forth which, again, I don't quite understand.) I started java about three months ago in an accelerated program so I'm not sure if the issue is my understanding of recursion, or a simple addition to a method, or if I'll have to rewrite a large portion of code.
I included the whole code just in case but really it's an issue that's within the travel method or the visited method. Would the answer be to write an entirely new method that re-travels the changed "visited" string maze? I've been struggling with this for a bit and I just need some direction toward an answer.
import java.awt.*;
import javax.swing.*;
class extraCreditMaze extends JPanel implements Runnable { //uses Runnable to execute jPanel
private String [][] ratMaze = //string maze
{{"blocked","blocked","blocked","blocked","blocked","blocked","blocked","blocked"},
{"blocked","open","blocked","blocked","blocked","blocked","blocked","blocked"},
{"blocked","open","open","open","open","open","open","blocked"},
{"blocked","blocked","open","blocked","open","blocked","open","blocked"},
{"blocked","blocked","open","blocked","open","blocked","open","goal"},
{"blocked","open","open","open","blocked","open","open","blocked"},
{"blocked","blocked","blocked","open","open","open","blocked","blocked"},
{"blocked","blocked","blocked","blocked","blocked","blocked","blocked","blocked"}};
final private int SquareSize = 15;
final private int BoardSize = 17;
private boolean free = false;
int axisX = 1, axisY = 1;
public void paintComponent(Graphics color) //paint components for char
{
super.paintComponent(color);
for(int row = 0; row < ratMaze.length; row++)
{
for(int col = 0; col< ratMaze.length; col++)
{
if(row==axisX && col==axisY) //traveling curser = blue
{
color.setColor(Color.blue);
color.fillOval(col*15,row*15,15,15);
}
else if(ratMaze[row][col]=="blocked") //empty = black
{
color.setColor(Color.black);
color.fillRect(col*SquareSize,row*SquareSize,BoardSize,BoardSize);
}
else if(ratMaze[row][col]=="goal")
{
color.setColor(Color.red); //goal = red
color.fillOval(col*15,row*15,15,15);
}
else if(ratMaze[row][col]=="visited")
{
color.setColor(Color.green); //path traveled = green
color.fillOval(col*15,row*15,15,15);
}
else
{
color.setColor(Color.white); //empty space = white
color.fillRect(col*SquareSize,row*SquareSize,BoardSize,BoardSize);
}
}
}
}
public void run () //starts run at (1,1)
{
travel(1,1);
}
public boolean goal(int x, int y){ //method to check goal (true/false)
if(ratMaze[x][y]=="goal")
return true;
else
return false;
}
public void changedVisited(int x, int y) //method to change traveled
{
ratMaze[x][y] = "visited";
axisX = x;
axisY = y;
}
public boolean boundaries(int x, int y) //check boundaries
{
if(ratMaze[x][y]=="blocked")
return true;
else
return false;
}
public boolean visited(int x, int y) //check if visited
{
if(ratMaze[x][y]=="visited")
return true;
else
return false;
}
private void travel(int x, int y)
{
if(boundaries(x,y)) //makes sure it's within bounds
return;
if(visited(x,y)) //makes sure it hasn't already been visited
return;
if(goal(x,y)) //checks if it's the goal/changes boolean
{
free = true;
JOptionPane.showMessageDialog(this, "You did it, Dr. Cui!"); //fun message!
}
if(!free) //all recursion functions if free=false
{
changedVisited(x,y); //changes traveled block to "visited"
repaint(); //repaints visited
try {Thread.sleep(300); } catch (Exception e) { }//slows down the traveling curser
//I do not understand catch (Exception e)
travel(x-1,y); //recursive travel functions
travel(x+1,y);
travel(x,y-1);
travel(x,y+1);
}
}
}
public class runExtraCreditMaze {
public static void main (String [] args) { //JFrame panel and perimeters
JFrame output = new JFrame();
output.setSize(115, 150);
output.setTitle("The Rat Maze");
output.setLocationRelativeTo(null);
extraCreditMaze Maze = new extraCreditMaze();
output.setContentPane(Maze);
output.setVisible(true);
Thread runnable = new Thread(Maze); //Creates Runnable thread for Maze object
runnable.start(); //Starts Runnable thread of Maze object
}
}
Problem is, as you wrote with the "visited". You are missing an decision tree on what to do, when there is no valid move and you are not in the goal. You will need to allow your rat to back track itself. You will probably need to "free" the visited cells when returning from no valid move.
I will try to add some code samples when I get to IDE :)
update: this is very badly written, and it is a bit lagging. but it should work. It needs a bit of cleaning and verification... I reused your boolean variable, which is bad .. :) and switched the true/false. I will do a bit of cleaning up tomorrow just to leave a nicer answer, but I think you will manage to understand what is going on.
update2:I have cleaned it a bit. Important lessons here are as follows:
1) backtracking needs to be done when all 4 steps fails. When your rat have nowhere to go, you need to disqualify the cell from your shortest path (ratMaze[x][y]="open")
2) You need to change position of your rat, when you return from recursion call, but before you continue with next step into. You will also need to let your program know that you are returning from recursion (thus the isBacktracking)
private void repaintMaze(int x, int y) {
changedVisited(x, y); //changes traveled block to "visited"
repaint(); //repaints visited
isBacktracking = false;
try {
Thread.sleep(500);
} catch (Exception e) {
}
}
private boolean travel(int x, int y) {
if (goal(x, y)) //checks if it's the goal/changes boolean
{
JOptionPane.showMessageDialog(this, "You did it, Dr. Cui!");//fun message!
return true;
}
if (boundaries(x, y) || visited(x, y)) //makes sure it's within bounds
return false;
repaintMaze(x, y);
boolean result; //recursive travel functions
result = travel(x - 1, y);
if (result) {
return true;
}
if (isBacktracking) {
repaintMaze(x, y);
}
result = travel(x + 1, y);
if (result) {
return true;
}
if (isBacktracking) {
repaintMaze(x, y);
}
result = travel(x, y - 1);
if (result) {
return true;
}
if (isBacktracking) {
repaintMaze(x, y);
}
result = travel(x, y + 1);
if (result) {
return true;
}
if (isBacktracking) {
repaintMaze(x, y);
}
ratMaze[x][y] = "open";
isBacktracking = true;
return false;
}
you should also add exit on close to your JFrame :) It will stop the application once you click the X button on the window itself
output.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

rubiks cube rotation algorithm

I am currently working on an assignment to build a functioning Rubik's cube. The program does not need a GUI. But it must simulate a 3 X 3 cube with rotation behaviors and provide a graphical representation of the cube (I'm going with a flat lettered structure). My code has a class for facets which make a Face (another class) and then there is a cube class which contains the rotation methods.
I am having trouble creating/choosing an algorithm to use that would simulate the cube and all possible rotations accurately. I found a solution on this site referencing a paper proposing 7 different ways to do it (the link in below). But which method is the most intuitive/easy to code? And more importantly, which would best fit the behavior outlined below (in the pseudocode)?
I am having trouble understanding how I could use any method to account for the changes on each face at once especially when taking into account the behavior of the face rotations (as opposed to the rows and columns).
How would you represent a Rubik's Cube in code?
Rotation Pseudocode:
map each cube numbers 1-54, faces 1 – 4 are 1 – 36 while top face is 37 - 45 and bottom is 46 – 54
1 turn: clockwise = +9
1 turn: counterclockwise = -9 loops back to 45
1 turn: up = + 37
1 turn: down = -37 loops back to 46
2 turns: clockwise = +9(2)
2 turns: counterclockwise = -9(2)
2 turns: up = +37(2)
2 turns: down = -37(2)
3 turns: clockwise = +9(3)
3 turns: counterclockwise = -9(3)
3 turns: up = +37(3)
3 turns: down = -37(3)
This pseudocode does not account for the face changes.
Is there a better/easier way to do this, different from the method my pseudocode proposes? How do I account for the face changes?
Example: (front face, 1 turn, clockwise)
123 741
456 852
789 963
Note: I am leaning towards the 54 element vector but am unsure how to manipulate it.
Also, this is my first question so let me know if something is wrong (not enough info, too much, wrong topic, etc.)
Thank you!
Note: This is the code I am working with.
Facet Class:
public class Facets {
public Color color;
public Facets(Color color){
}
public enum Color {
B, G, R, Y, O, P
}
public String getName(){
return this.color.name();
}
}
Face Class:
import java.util.Arrays;
public class Face {
public Facets[] face;
/*public Face(Facets.Color color, Facets.Color[] array){
face = new Facets[9];
for(int i = 0; i < face.length; i++){
face[i] = new Facets(array[i]);
face[i] = new Facets(color);
}
}*/
public Face(Facets.Color color){
face = new Facets[9];
for(int i = 0; i < face.length; i++){
face[i] = new Facets(color);
}
}
public Face(Facets.Color[] array){
face = new Facets[9];
for (int i = 0; i < face.length; i++){
face[i] = new Facets(array[i]);
//face[i] = face[i].toString();
}
}
//Returns a textual representation of Face
public String printFace(){
StringBuilder faceString = new StringBuilder();
for(Facets f: face){
faceString.append(f.getName());
System.out.println(f.toString());
}
return faceString.toString();
}
public static void main(String[] args){
Face face = new Face(Facets.Color.B);
System.out.println(face.toString());
}
}
Cube Class:
public class Cube {
public Cube(Face front, Face right, Face back, Face left, Face top, Face bottom){
}
public Cube createCube(){
}
public Cube rotate(int row, int column, String direction, int turns){
/*Turns must be between 0 - 4
Row must be 1 or 2, column must be 1 or 2, direction must be clockwise, counterclockwise, up or down (0 means no turn, 1 is top row or left column; 2 is bottom row or right column)
*/
}
public int turns(){
}
public Cube row(){
}
public Cube column(){
}
public Cube clockwise(){
}
public Cube counterClockwise(){
}
public Cube up(){
}
public Cube down(){
}
public Cube random(Cube cube){
}
public Cube configuration(Cube cube){
}
}
Rubik's Cube:
public class RubiksCube {
public RubiksCube(Cube cube){
}
public RubiksCube(Face front, Face rightOfFront, Face back, Face leftOfFront, Face top, Face bottom){
}
//calls face and colors and initializes the arrays into a object
//default config: solid color on each side so each array, representing a face, is set to a solid color
public void createNewCube(){
}
public void rotation(Cube cube, int row, int column, String direction, int turns){
}
public Cube configuration(Cube cube){//should return 6 Faces? or cube?
return cube;
}
}
Think about what data structure makes it the easiest for you to conceptualize the cube. The different solutions in the link you provided all have pros and cons. You can have a more terse structure (i.e. the five integer representation) which takes up less memory and optimizes performance. But that representation might be difficult to work with if you are new to the problem. On the other end of the spectrum is an object oriented representation that models the way most people would think about a rubik cube. That might be the best approach for someone new to rubik's cubes.
After you have a data structure that makes sense to you, think about the different operations that can be performed on the cube. You can capture each of these moves in a function that alters the state of the data. If you have a real rubik cube to play with, figure out what all the different turns are and how they change the values of the rubik cube. Then try to model them in their own functions. i.e. a top wise turn would cause five of the six faces to change, right. It would cause four of the faces to receive the top row of their neighbour. And it would cause a shift in the top face as well. The bottom face would be uneffected.
If you are feeling overwhelmed with the complexity try to break your problem down into a smaller one. Maybe you can try to write a representation for a rubik cube that is 2 x 2 rather than 3 x 3. Once you've mastered the smaller problem, return to the larger one.
i just started to write some code to manipulate a cube.
package p;
import java.util.Arrays;
import static p.Facet.*;
enum Facet { // used for face, color, and operations
u(1),d(1),r(2),l(0),f(1),b(3); // maybe FRULBD instead?
Facet(int pad) {
this.pad=pad;
}
// u pad n+1
// l pad 0
// f pad n+1
// r pad 2(n+1)
// b pad 3(n+1) or at the bottom.
// d pad n+1
final int pad; // for formatting
}
class Face {
Face(int n,Facet facet) {
this.n=n;
this.facet=facet;
facets=new Facet[n][n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
facets[i][j]=facet;
}
Face(Face face) {
this.n=face.n;
this.facet=face.facet;
facets=new Facet[n][n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
facets[i][j]=face.facets[i][j];
}
#Override public String toString() {
return toString(0);
}
public String toString(int pad) {
StringBuffer stringBuffer=new StringBuffer();
for(int i=0;i<n;i++) {
stringBuffer.append(pad(pad,n));
for(int j=0;j<n;j++)
stringBuffer.append(facets[i][j]);
stringBuffer.append('\n');
}
return stringBuffer.toString();
}
String pad() {
return pad(facet.pad,n);
}
static String pad(int length) {
StringBuffer stringBuffer=new StringBuffer(length);
for(int i=0;i<length;i++)
stringBuffer.append(" ");
return stringBuffer.toString();
}
static String pad(int length,int n) {
return pad(length*(n+1));
}
#Override public int hashCode() {
final int prime=31;
int result=1;
result=prime*result+((facet==null)?0:facet.hashCode());
result=prime*result+Arrays.deepHashCode(facets);
result=prime*result+n;
return result;
}
#Override public boolean equals(Object obj) {
if(this==obj) return true;
if(obj==null) return false;
if(getClass()!=obj.getClass()) return false;
Face other=(Face)obj;
if(facet!=other.facet) return false;
if(!Arrays.deepEquals(facets,other.facets)) return false;
if(n!=other.n) return false;
return true;
}
static void rotateClockwise(Object[][] objects) {
Object temp;
int n=objects.length;
// For each concentric square around the middle of the matrix to rotate...
// This value will be used as (m, n) offset when moving in.
// Integer division by 2 will skip center if odd length.
for(int i=0;i<n/2;i++)
// for the length of this ring
for(int j=0;j<n-2*i-1;j++) {
temp=objects[i][i+j];
objects[i][i+j]=objects[n-i-j-1][i];
objects[n-i-j-1][i]=objects[n-i-1][n-i-j-1];
objects[n-i-1][n-i-j-1]=objects[i+j][n-i-1];
objects[i+j][n-i-1]=temp;
}
}
static void rotateCounterClockwise(Object[][] objects) {
int n=objects.length;
for(int i=0;i<n/2;i++) {
for(int j=i;j<n-i-1;j++) {
Object temp=objects[i][j];
objects[i][j]=objects[j][n-1-i]; // move values from right to top
objects[j][n-1-i]=objects[n-1-i][n-1-j]; // move values from bottom to right
objects[n-1-i][n-1-j]=objects[n-1-j][i]; // move values from left to bottom
objects[n-1-j][i]=temp;
}
}
}
final int n;
final Facet facet;
final Facet[][] facets;
}
class Cube {
Cube(int n) {
u=new Face(n,Facet.u);
d=new Face(n,Facet.d);
r=new Face(n,Facet.r);
l=new Face(n,Facet.l);
f=new Face(n,Facet.f);
b=new Face(n,Facet.b);
}
void rotatex(Face face,Face old) {
for(int i=0;i<face.n;i++)
for(int j=0;i<face.n;j++)
face.facets[i][j]=old.facets[i][j];
}
void rotateConterClockwise(Face f,Face u,Face l,Face d,Face r) {
for(int i=0;i<3;i++)
rotate(f,u,l,d,r);
}
void rotate(Face f,Face u,Face l,Face d,Face r) {
Face.rotateClockwise(f.facets);
Facet[] top=new Facet[u.n];
for(int i=0;i<u.n;i++)
top[i]=u.facets[u.n-1][i];
for(int i=0;i<u.n;i++) // move left to u
u.facets[u.n-1][i]=l.facets[u.n-i-1][u.n-1];
for(int i=0;i<u.n;i++) // bottom to left
l.facets[u.n-i-1][u.n-1]=d.facets[0][i];
for(int i=0;i<u.n;i++) // right to bottom
d.facets[0][i]=r.facets[i][0];
for(int i=0;i<u.n;i++)
r.facets[i][0]=top[i];
}
void op(Facet facet) {
switch(facet) {
case b:
rotate(b,u,r,d,l);
break;
case d:
rotate(d,f,l,b,r);
break;
case f:
rotate(f,u,l,d,r);
break;
case l:
rotate(l,u,b,d,f);
break;
case r:
rotate(r,u,f,d,b);
break;
case u:
rotate(u,d,l,f,r);
break;
}
}
void opInverse(Facet facet) {
switch(facet) {
case b:
rotateConterClockwise(b,u,r,d,l);
break;
case d:
rotateConterClockwise(d,f,l,b,r);
break;
case f:
rotateConterClockwise(f,u,l,d,r);
break;
case l:
rotateConterClockwise(l,u,b,d,f);
break;
case r:
rotateConterClockwise(r,u,f,d,b);
break;
case u:
rotateConterClockwise(u,d,l,f,r);
break;
}
}
#Override public int hashCode() {
final int prime=31;
int result=1;
result=prime*result+((b==null)?0:b.hashCode());
result=prime*result+((d==null)?0:d.hashCode());
result=prime*result+((f==null)?0:f.hashCode());
result=prime*result+((l==null)?0:l.hashCode());
result=prime*result+((r==null)?0:r.hashCode());
result=prime*result+((u==null)?0:u.hashCode());
return result;
}
#Override public boolean equals(Object obj) {
if(this==obj) return true;
if(obj==null) return false;
if(getClass()!=obj.getClass()) return false;
Cube other=(Cube)obj;
if(b==null) {
if(other.b!=null) return false;
} else if(!b.equals(other.b)) return false;
if(d==null) {
if(other.d!=null) return false;
} else if(!d.equals(other.d)) return false;
if(f==null) {
if(other.f!=null) return false;
} else if(!f.equals(other.f)) return false;
if(l==null) {
if(other.l!=null) return false;
} else if(!l.equals(other.l)) return false;
if(r==null) {
if(other.r!=null) return false;
} else if(!r.equals(other.r)) return false;
if(u==null) {
if(other.u!=null) return false;
} else if(!u.equals(other.u)) return false;
return true;
}
#Override public String toString() { //ulfrbd
StringBuffer stringBuffer=new StringBuffer(3*4*(u.n+1));
for(int i=0;i<u.n;i++) {
stringBuffer.append(u.pad());
for(int j=0;j<u.n;j++)
stringBuffer.append(u.facets[i][j]);
stringBuffer.append('\n');
}
for(int i=0;i<u.n;i++) {
stringBuffer.append(l.pad());
for(int j=0;j<u.n;j++)
stringBuffer.append(l.facets[i][j]);
stringBuffer.append(' ');
for(int j=0;j<u.n;j++)
stringBuffer.append(f.facets[i][j]);
stringBuffer.append(' ');
for(int j=0;j<u.n;j++)
stringBuffer.append(r.facets[i][j]);
stringBuffer.append(' ');
for(int j=0;j<u.n;j++)
stringBuffer.append(b.facets[i][j]);
stringBuffer.append('\n');
}
for(int i=0;i<u.n;i++) {
stringBuffer.append(d.pad());
for(int j=0;j<u.n;j++)
stringBuffer.append(d.facets[i][j]);
stringBuffer.append('\n');
}
return stringBuffer.toString();
}
final Face u,d,r,l,f,b;
}
public class Main {
public static void main(String[] args) {
Cube initial=new Cube(3);
Cube cube=new Cube(3);
System.out.println(cube.u.facets[0][0]);
System.out.println(cube.u);
System.out.println(cube);
for(int i=0;i<4;i++) {
cube.op(Facet.f);
System.out.println(cube);
}
// F' U L' U'
cube=new Cube(3);
int i=0;
do {
fpulpup(cube);
System.out.println(i);
System.out.println(cube);
i++;
} while(!cube.equals(initial));
}
private static void fpulpup(Cube cube) {
cube.opInverse(f);
cube.op(u);
cube.opInverse(l);
cube.opInverse(f);
}
}

Java - Calculating Pi

I've been wanting to calculate pi with the Gregory-Leibniz series, and there's something wrong with it. I'm a bit of a starter to Java, so this may not be a hard question to answer. I don't know what's going on, so can somebody help me please?
Code so far:
package com.waitdev.pi;
public class Pi {
static int pi = 0;
public static void main(String[] args) {
for (int i = 1; i < 51; i++) {
if (isOdd(i)) {
pi = pi+(4/((i*2)-1));
// System.out.println(i);
} else {
pi = pi-(4/(i*2)-1);
// System.out.println(i);
}
}
System.out.println(pi);
}
private static boolean isOdd(int n) {
if (n % 2 == 1) {
return true;
} else {
return false;
}
}
}
FYI: The output for this is 28.
Thanks.
You are missing a parenthesis in your else block, and you need to force float calculation by e.g writing 4.0 instead of 4.
It should read:
if (isOdd(i)) {
pi = pi+(4.0/((i*2)-1));
// System.out.println(i);
} else {
pi = pi-(4.0/((i*2)-1));
// System.out.println(i);
}
You also need to use a float or a double for pi.
Extra - as for your isOdd method, it could be simplified like:
private static boolean isOdd(int n) {
return (n % 2 == 1)
}
But this does not influence the result.
First off: an int is an integer, whole number. you want to change it to:
static double pi = 0;
Otherwise the answer always gets rounded down to a whole number.
Secondly, you are missing parenthesis in your else statement:
} else {
pi = pi-(4/((i*2)-1));
}
If you want to be completely safe, change your integers in the if and else clause to doubles:
if (isOdd(i)) {
pi = pi+(4.0/((i*2.0)-1.0));
// System.out.println(i);
} else {
pi = pi-(4.0/((i*2.0)-1.0));
// System.out.println(i);
}
But that shouldn't be neccessary

StackOverFlowError on Backtracking method

I'm having a little trouble getting this method to work, getting a StackOverFlowError. I'm trying to autosolve the puzzles from this page Puff Ball
public static boolean backtrackingPuffBalls(Board board, int[] steps, int ball,int index){
if(!(checkValidPosition(board))){
if(checkSolution(board)){
numberSolutions++;
solutions[numberSolutions] = steps;
}
else{
return false;
}
}
else{
while(ball<board.getNumObjectives()+1){
puffBall(board, ball);
if(backtrackingPuffBalls(board, steps, ball, index++)){
return true;
}
else{
ball++;
index--;
}
}
}
return false;
}
Could it be passing the board in each call the problem?, it has the next variables:
int[][] board;
int numObjectives;
boolean solvable, solved;
int[] movements;
boolean valid;
Coordinates[] objectives;
Coordinates[] balls;
The code of the envolved methods:
public static boolean checkValidPosition(Board board){
int objectivesInBorder=0;
int ballsInBorder=0;
for(int i=0;i<board.getObjectives().length;i++){
if(board.getObjectives()[i].getX()==0||board.getObjectives()[i].getX()==board.getBoard().length
||board.getObjectives()[i].getY()==0||board.getObjectives()[i].getY()==board.getBoard()[0].length){
objectivesInBorder++;
}
}
for(int i=0;i<board.getBalls().length;i++){
if(board.getBalls()[i].getX()==0||board.getBalls()[i].getX()==board.getBoard().length
||board.getBalls()[i].getY()==0||board.getBalls()[i].getY()==board.getBoard()[0].length){
ballsInBorder++;
}
}
if(ballsInBorder>objectivesInBorder){
board.setValid(false);
return false;
}
board.setValid(true);
return true;
}
public static boolean checkSolution(Board board){
int solved=0;
for(int i=0;i<board.getObjectives().length;i++){
for(int j=0;j<board.getBalls().length;i++){
if(board.getObjectives()[i]==board.getBalls()[j]){
solved++;
}
}
}
if(solved==board.getNumObjectives()){
return true;
}
return false;
}
public static Board puffBall(Board board, int ball){
Coordinates xy=searchCoordinates(board, ball-1);
Coordinates[] balls=board.getBalls();
//Moving from the edges to resolve conflict when 2 balls are touching each other
boolean ballsMoved = false;
//Bottom to Top
for (int i = board.getBoard().length;i==xy.getY();i--){
if( board.getBoard()[xy.getX()][i]==1){
if(checkValidMovement(board.getBoard(), i+1, 1)){
board.getBoard()[xy.getX()][i]=-1;
board.getBoard()[xy.getX()][i+1]=1;
balls[searchBall(board, xy.getX(), i)-1].setY(i+1);
ballsMoved=true;
}
}
}
//Top to Bottom
for (int i = 0; i==xy.getY();i++){
if( board.getBoard()[xy.getX()][i]==1){
if(checkValidMovement(board.getBoard(), i-1, 1)){
board.getBoard()[xy.getX()][i]=-1;
board.getBoard()[xy.getX()][i-1]=1;
balls[searchBall(board, xy.getX(), i)-1].setY(i-1);
ballsMoved=true;
}
}
}
//Right to Left
for (int i = board.getBoard()[0].length; i==xy.getY();i--){
if( board.getBoard()[i][xy.getY()]==1){
if(checkValidMovement(board.getBoard(), i+1, 0)){
board.getBoard()[i][xy.getY()]=-1;
board.getBoard()[i+1][xy.getY()]=1;
balls[searchBall(board, i, xy.getY())-1].setX(i+1);
ballsMoved=true;
}
}
}
//Left to Right
for (int i = 0; i==xy.getY();i++){
if( board.getBoard()[i][xy.getY()]==1){
if(checkValidMovement(board.getBoard(), i-1, 0)){
board.getBoard()[i][xy.getY()]=-1;
board.getBoard()[i-1][xy.getY()]=1;
balls[searchBall(board, i, xy.getY())-1].setX(i-1);
ballsMoved=true;
}
}
}
board.setBalls(balls);
board.setValid(ballsMoved);
return board;
"solutions[]" and "numberSolutions" are global variables
I think i may fix the "board.getBoard()" code but it shouldn't affect the backtracking
The reason you are seeing the StackOverFlowError is that you are making an infinite number of recursive calls to the backtrackingPuffBalls() method. I expect it to be the case that the else condition keeps happening, and each call ends up making another recursive call.
To solve this you need to sort out your logic and make sure that the recursion ends at the appropriate time.
The debugger is your best friend here, and you will learn a lot by stepping through your code to see what is happening.

Categories