percolation problem (java -cannot run appropriately) - java

I have a problem relating to the percolation model with the latest version of Java
My project includes three file a illegalargumentexception.java file (use to handle illegal arguments), a percolation.java file (the datatype), and the PercolationStats.java file (use to calculate and generate the statistic)
In my expectation, the code should generate the probability of the percolated model (after a specific time of trials)
And here is my code:
the percolation datatype:
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
public class percolation {
public static boolean[] grid;
public static WeightedQuickUnionUF gridMap ;
public static int openCell;
public static int top = 0;
private static int current_index;
public int bottom;
private int n;
public percolation(int n) {
}
// creates n-by-n grid, with all sites initially blocked
public int Percolation (int n) {
gridMap = new WeightedQuickUnionUF(n*n + 2);
grid = new boolean[n*n + 2];
this.n =n;
openCell = 0;
top = 0;
bottom = n*n +1;
if (n <=0) {
throw new IllegalArgumentException("Grid's number can not negative or equal to zero");
}
return n ;
}
// opens the site (row, col) if it is not open already
public void open( int row, int col) {
current_index = (row-1)*n + (col-1);
grid[percolation.current_index] = true;
percolation.openCell++;
if (row == 1)
gridMap.union(percolation.current_index, top);
if(row == this.n)
gridMap.union(current_index, col);
if (row > this.n || col > this.n)
throw new IllegalArgumentException("Out of bound");
if (row <1 || col <1)
throw new IllegalArgumentException("The index must be greater than zero");
if(row >1 && isOpen(row-1, col)) // above cell
{
assert(current_index > n);
gridMap.union(current_index,current_index-n);
}
if (row < this.n && isOpen(row + 1 , col)) // below cell
{
assert(current_index + n < n * n);
gridMap.union(current_index , current_index + n);
}
if(col > 1 && isOpen(row, col - 1)) //left cell
{
gridMap.union(current_index,current_index- 1);
}
if(col < this.n && isOpen(row, col + 1)) //right cell
{
gridMap.union(current_index,current_index + 1);
}
return ;
}
// is the site (row, col) open?
public boolean isOpen(int row, int col) {
return grid[current_index];
}
// is the site (row, col) full?
public boolean isFull(int row, int col)
{
if(!isOpen(row,col)) return false;
return gridMap.find(current_index) == gridMap.find(top);
}
public int numberOfOpenSites() // returns the number of open sites
{
return percolation.openCell;
}
// does the system percolate?
public boolean percolates() {
return gridMap.find(top) == gridMap.find(bottom);
}
// test client (optional)
public static void main(String[] args) {
}
}
the PercolationStats.java file
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.StdStats;
public class PercolationStats {
public static double[] result;
public static int trials;
// perform independent trials on an n-by-n grid
public PercolationStats(int n, int trials) {
double[] result = new double[trials];
int test_row ;
int test_col ;
for (int i=0; i <trials; i++) {
percolation per = new percolation(n);
while (!per.percolates()) {
test_row = (int)((StdRandom.uniformInt(n)*n) +1 );
test_col = (int)((StdRandom.uniformInt(n)*n) +1 );
if( !per.isOpen(test_row,test_col) )
per.open(test_row,test_col);
}
result[i] = (double)(per.numberOfOpenSites()) / (n * n);
}
if(n <= 0 || trials <= 0) throw new IllegalArgumentException("Must greater than zero");
}
// sample mean of percolation threshold
public double mean() {
return StdStats.mean(result);
}
// sample standard deviation of percolation threshold
public double stddev() {
return StdStats.stddev(result) ;
}
// low endpoint of 95% confidence interval
public double Low_confidence() {
return (mean() - (1.96 * stddev())/ Math.sqrt(trials));
}
// high endpoint of 95% confidence interval
public double High_confidenceHi() {
return mean() + (1.96 * stddev())/ Math.sqrt(trials);
}
// test client (see below)
public static void main(String[] args) {
PercolationStats s = new PercolationStats(50,10000);
System.out.println("Mean:" + s.mean());
System.out.println("Standard Deviation:"+ s.stddev());
System.out.println("High Confidence" + s.High_confidenceHi());
System.out.println("Low Confidence" + s.Low_confidence());
}
}
My expectation is when I compile the PercolationStats file it will generate the result of the percolating probability threshold like this: (the result if you give the input 200 by 200 grid and try the simulation 100 times
~/Desktop/percolation> java-algs4 PercolationStats 200 100
mean = 0.5929934999999997
stddev = 0.00876990421552567
95% confidence interval = [0.5912745987737567, 0.5947124012262428]
but my result is a bunch of errors that:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "edu.princeton.cs.algs4.WeightedQuickUnionUF.find(int)" because "percolation.gridMap" is null
at percolation.percolates(percolation.java:93)
at PercolationStats.<init>(PercolationStats.java:17)
at PercolationStats.main(PercolationStats.java:58)\
I believe this is to be caused by the percolate datatype, and to be more specific is the line:
public boolean percolates() {
return gridMap.find(top) == gridMap.find(bottom);
}
It states that the gridMap variable of Union-Find is null - I don't know why this happens, I speculate this can relate to the scope of the "gridMap" variable, which is not applicable to all methods in the datatype. That is my hypothesis It could be wrong.
Can anyone give me a clue for why this happens and what should I fix for the successful compilation (I means to generate the probability)
Thanks in advance!

You have not set gridMap, though it is mentioned in a method called public int Percolation (int n). Perhaps you intended that Percolation is called from body of the constructor which you declared as public percolation(int n).
The fix should be simple: move the public int Percolation (int n) code into the constructor or make constructor public percolation(int n) call Percolation(n).
The class should follow conventions and renamed to Percolation.

Related

Adding sum of all odd numbers with range JAVA

I have a problem, I have the correct(PART 1) and incorrect code (PART 2). I cant figure out why the incorrect code is incorrect.
the
static int sum = 0
part is the incorrect part of the code in PART 2. If that line of code is moved to the same location at PART 1. The code works.
if the range is from 10 to 20. PART 2 outputs an incorrect sum of 111. The sum should be 75. There are 3 possible combinations to get 111.
18 + 18 + correct sum
17 +19 + correct sum
16 + 20 + correct sum
Im guessing PART 2 passes through 18 + 18? but how?!
PART 1 Correct Code
ublic class SumOddRange {
public static boolean isOdd(int number){
if (number <= 0) {
return false;
}
return number % 2 != 0;
}
public static int sumOdd(int start, int end){
if ( (end < start) || (start < 0) || (end < 0) ){
return -1;
}
int sum = 0;
for (int i = start; i<=end; i++){
if (isOdd(i)){
sum +=i;
}
}
return sum;
}
PART 2 INCORRECT CODE
public class SumOddRange {
public static boolean isOdd(int number) {
if((number > 0) && (number % 2 != 0)) {
return true;
}
else {
return false;
}
}
static int startOne = 0;
static int sum = 0;
public static int sumOdd(int start, int end) {
if ((end >= start) && (end > 0) && (start > 0)) {
for (startOne = start; startOne <= end; startOne++) {
if (isOdd(startOne)) {
sum += startOne;
}
}
return sum;
} else
return -1;
}
The problem is that you are using static variables.
What does static mean?
After creating a class, you can create instances (also called objects) of this class. This is what happens, when you use a command like
SumOddRange a = new SumOddRange();
SumOddRange b = new SumOddRange();
As you probably know, there are methods and variables in a class. These methods and classes can be seperated into
Class methods and variables
Object methods and variables (object variables are most often called attributes)
This means that some methods and variables do belong to the class, so all the instances of this class share this variable or method. This is what static is used for. So if the class in the image above has a static attribute named staticAttributeName, a.staticAttributeName and b.staticAttributeName have to be the same.
If a variable isn't static, this variable is not shared by the instances. All instances have their own instance of this variable. So although their name is the same, the values saved in the variables doen't have to be the same. So if the class in the image above has a non-static attribute named attributeName, a.attributeName and b.attributeName doesn't have to be the same.
An example:
public class Add {
public static int sum = 0;
public static void addOne() {
sum = sum + 1;
}
}
public class Test {
public static void main(String[] args) {
Add a = new Add();
Add b = new Add();
a.addOne();
b.addOne();
System.out.println("a " + a.sum);
System.out.println("b " + b.sum);
}
}
As you can see, the variable sum is static. This means that a.sum and b.sum are the same. In the main-method, we are calling the method addOne two times, so the two outputs are "a 2" and "b 2".
public class Add {
public int sum = 0;
public void addOne() {
sum = sum + 1;
}
}
public class Test {
public static void main(String[] args) {
Add a = new Add();
Add b = new Add();
a.addOne();
b.addOne();
b.addOne();
System.out.println("a " + a.sum);
System.out.println("b " + b.sum);
}
}
We now have a non-static variable sum in the class Add.
a: We are calling the method addOne one time, so the first output is "a 1".
b: The method addOne is called two times, so the output is "b 2".
Solving the problem
public class Test {
public static void main(String[] args) {
SumOddRange s = new SumOddRange(); //Using class given in PART2 of question
SumOddRange t = new SumOddRange();
System.out.println(s.sumOdd(10,20));
System.out.println(s.sumOdd(10,20));
}
}
This class produces the outputs 75 and 150. This is the case, because s and t use the same variable sum, so the first time, the sum is correct, but the second calculation returns 75+sumOdd(10,20) = 75+75 = 150 as the result.
As we now know, the main problem is that the variable(s) are static. This brings up the idea to just use non-static variables, which is the best idea here:
public class SumOddRange {
public boolean isOdd(int number) {
if((number > 0) && (number % 2 != 0)) {
return true;
}
else {
return false;
}
}
int startOne = 0;
int sum = 0;
public int sumOdd(int start, int end) {
sum = 0;
if ((end >= start) && (end > 0) && (start > 0)) {
for (startOne = start; startOne <= end; startOne++) {
if (isOdd(startOne)) {
sum += startOne;
}
}
return sum;
} else {
return -1;
}
}
}
Another option is to just reset the variable sum before actually calculating the sum. The disadvantage of this approach is that you will not be able to access earlier results anymore:
static int startOne = 0;
static int sum = 0;
public static int sumOdd(int start, int end) {
sum = 0;
if ((end >= start) && (end > 0) && (start > 0)) {
for (startOne = start; startOne <= end; startOne++) {
if (isOdd(startOne)) {
sum += startOne;
}
}
return sum;
} else {
return -1;
}
}

While loop in Java :: keep dividing while contion is not met

I have a basic code:
public class experiment {
public static void main(String[] args) {
System.out.println(experiment(80));
}
public static int experiment (int number) {
while (number > 10) {
number = number / 2;
return number;
} return -1;
}
}
It returns me 40.
So it means is not looping on the variable number.
I would like it to keep looping on number (80, 40, 20, 10), till it return 10.
Is there a way to do it without using the for loop?
Move the return out of the loop:
public static int experiment (int number) {
while (number > 10) {
number = number / 2;
}
return number;
}
If you need the -1 for a special case, you should check it before entering the loop:
public static int experiment (int number) {
if (number < 0) { // or some condition
return -1;
}
while (number > 10) {
number = number / 2;
}
return number;
}
BTW, start using a debugger, you can step through this kind of code and find the problem easily.
What wrong is that you put return number inside the while loop it will end the iteration and return the value of 40. So you have to,
public static int experiment (int number) {
while (number > 10) {
number = number / 2;
}
return number;
}
If you want all the numbers the loop has passed to print;
public static void experiment (int number) {
while (number > 10) {
number = number / 2;
System.out.println(number);
}
}
using recursion:
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(test.toTen(80));
}
public static int toTen(int k) {
if (k==10) {
return k;
}
else {
return toTen(k/2);
}
}
}
or simply edit the loop like so
while (k > 10) {
k = k / 2;
}
return k;

Efficiently, get the count of numbers in a sorted array that is less than a given number using binary search

My problem statement is this -
Find the count of numbers in a sorted array that are less than a given number, and this should be done efficiently with respect to time. I wrote a program using binary search that gets the count but time complexity wise it's failing. Need help in achieving this.
import java.util.Arrays;
public class SortedSearch {
public static int countNumbers(int[] sortedArray, int lessThan) {
if(sortedArray.length ==1 || sortedArray.length == 0) {
return singleElement(sortedArray, lessThan);
}
else {
return binarySearch(sortedArray, lessThan);
}
}
public static int singleElement(int[] sortedArray, int searchVal) {
if(sortedArray.length == 0) {
return 0;
}
if(sortedArray[0] < searchVal) {
return 1;
}
return 0;
}
private static int binarySearch(int[] sortedArray, int searchVal) {
int low = 0;
int high = (sortedArray.length)-1;
int mid = (low + high)/2;
if((sortedArray.length == 0) || (sortedArray[0] > searchVal)) {
return 0;
}
if(sortedArray[high] < searchVal) {
return sortedArray.length;
}
if(sortedArray[high] == searchVal) {
return sortedArray.length-1;
}
if(sortedArray[mid] < searchVal) {
int newLow = low;
int newHigh = calculateNewHigh(sortedArray, newLow, 0, searchVal);
int[] newArray = Arrays.copyOfRange(sortedArray, newLow, newHigh+1);
return newArray.length;
}
else {
int newLow = low;
int newHigh = mid;
int[] newArray = Arrays.copyOfRange(sortedArray, newLow, newHigh+1);
return binarySearch(newArray, searchVal);
}
}
private static int calculateNewHigh(int[] sortedArray, int low, int previousHigh, int searchVal) {
int newHigh = previousHigh + (sortedArray.length-low)/2;
if(sortedArray[newHigh] < searchVal) {
newHigh = calculateNewHigh(sortedArray, newHigh, newHigh, searchVal);
}
if(sortedArray[newHigh] == searchVal) {
newHigh--;
}
if(sortedArray[newHigh] > searchVal) {
newHigh--;
}
return newHigh;
}
public static void main(String[] args) {
System.out.println(SortedSearch.countNumbers(new int[] { 1, 3, 5, 7 }, 4));
}
}
Since you're using Arrays anyway, way not use the Arrays.binarySearch(int[] a, int key) method, instead of attempting to write your own?
public static int countNumbers(int[] sortedArray, int lessThan) {
int idx = Arrays.binarySearch(sortedArray, lessThan);
if (idx < 0)
return -idx - 1; // insertion point
while (idx > 0 && sortedArray[idx - 1] == lessThan)
idx--;
return idx; // index of first element with given value
}
The while loop1 is necessary because the javadoc says:
If the array contains multiple elements with the specified value, there is no guarantee which one will be found.
1) This loop is not optimal if e.g. all values are the same, see e.g. Finding multiple entries with binary search

Cool Number Counter

For this lab a cool number is any number that when divided by 3,4,5 & 6 will leave a remainder of 1. I have done the static boolean IsCoolNumber and I made a private int b to use as a counter but I have absolutely no idea where I would put for example a b++. Any help would greatly be appreciated.
Thanks in advance!
import static java.lang.System.*;
public class CoolNumbers
{
private int b=0;
public static boolean isCoolNumber( int num )
{
int x;
x = 6;
for(x = 6; x<num; x++)
{
if ((x%3==1) && (x%4==1) && (x%5 ==1) && (x%6 == 1))
return true;
}
return false;
}
public static int countCoolNumbers( int stop )
{
//add counter
}
public static void main( String[] args )
{
System.out.println( CoolNumbers.countCoolNumbers(250) + " cool numbers between 6 - " + 250);
//add more test cases
}
}
In isCoolNumber you don't need a loop, a single statement will do.
public static boolean isCoolNumber(int x) {
return (x % 3 == 1) && (x % 4 == 1) && (x % 5 == 1) && (x % 6 == 1);
}
To count the "cool numbers" add a simple loop in the currently empty countCoolNumbers( int stop ) method.
for (int i = start; i < stop; i++) {
if (isCoolNumber(i)) {
count++;
}
}
Write your method countCoolNumbersas below and try it...
public static int countCoolNumbers( int stop ){
boolean check=isCoolNumber(stop);
int num=0;
if(check==true){
num=stop;
}
num=0;
return num;
`}
public static void main( String[] args ) {
System.out.println( CoolNumbers.countCoolNumbers(250) + " cool numbers between 6 - " + 250);
//add more test cases
}
Then output will be:
0 cool numbers between 6 - 250

Super Queen Puzzle array exception

I'm trying to implement the N*N queen algorithm with a little twist to it. In this version the queen can also move like a Knight can in chess.
Checking for the diagonals and rows seems to be fine, however when I try to check for a queen in the "L" position away from my current position, I get a "arrayindexoutofboundexception".
I'm not entirely sure if my check_Knight move is right. I can't seem to locate the error causing the issue in my code.
public class QueenGame {
/**
* #param args
*/
static int solution =0;
static boolean check_Queen(int row, int col, int queens[])
{
for(int i =1; i<col; i++)
{
if (queens[col-i] == row ||
queens[col-i] == row-i ||
queens[col-i] == row+i)
{
//flag = false;
return false;
}
}
return true;
}
static boolean check_KnightMove(int row, int col, int queens[])
{
if(queens[col-2] == (row -1) || queens[col-2] == (row+1))
{
return false;
}
return true;
}
static void placement(int col, int queens[], int n){
//int solution =0;
for (int row = 1; row <= n; row++) {
queens[col] = row;
if((check_Queen(row,col,queens)) == true)
{
if((check_KnightMove(row,col,queens)) == true)
{
if(col == n)
{
solution++;
}
else
{
placement(col+1,queens,n);
}
}
}
}
queens[col] = 0;
}
public static void main(String[] args) {
int solution =0;
Scanner scanner=new Scanner(System.in);
//System.out.print("Please enter N");
int n =10;
//int n = scanner.nextInt();// TODO Auto-generated method stub
//System.out.print(n);
int queens[] = new int[n+1];
placement(1,queens,n);
System.out.println("nQueens: solution=" + solution);
}
}
If col is 0 or 1, then you will get an ArrayIndexOutOfBoundsException. Add a check before accessing the array.
if ((col >= 2) && (queens[col-2] == (row-1) || queens[col-2] == (row+1)))

Categories