Java - Calculating Pi - java

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

Related

How to get rid of multiple if statements in java?

Is there a better way to write this constructor which has multiple if statements and multiple arguments? I'm a noob to programming so any leads would be helpful.
public Latency(final double full, final double cpuOne, final double cpuTwo, final double cpuThree, final double cpuFour) {
if (full > 10.0 || (full <= 0.0)) {
throw new IllegalArgumentException("Must check the values");
}
this.full = full;
if (cpuOne == 0 && cpuTwo == 0 && cpuThree == 0 && cpuFour == 0) {
throw new IllegalArgumentException("not all can be zero");
} else {
if (cpuOne == 0.5) {
this.cpuOne = full;
} else {
this.cpuOne = cpuOne;
}
if (cpuTwo == 0.5) {
this.cpuTwo = full;
} else {
this.cpuTwo = cpuTwo;
}
if (cpuThree == 0.5) {
this.cpuThree = full;
} else {
this.cpuThree = cpuThree;
}
if (cpuFour == 0.5) {
this.cpuFour = full;
} else {
this.cpuFour = cpuFour;
}
}
}
I think this code doesn't need much of context as it is pretty straight forward.
I found out that we can't use switch statements for type double. How to optimize this?
There are a number of possible ways of refactoring the code that you've written, and there are pros and cons of each one. Here are some ideas.
Idea One - use the conditional operator
You could replace the else block with code that looks like this. This is just effectively a shorter way of writing each of the inner if/else blocks. Many people find this kind of form more readable than a bunch of verbose if/else blocks, but it takes some time to get used to it.
this.cpuOne = cpuOne == 0.5 ? full : cpuOne;
this.cpuTwo = cpuTwo == 0.5 ? full : cpuTwo;
this.cpuThree = cpuThree == 0.5 ? full : cpuThree;
this.cpuFour = cpuFour == 0.5 ? full : cpuFour;
Idea Two - move common functionality to its own method
You could have a method something like this
private static double changeHalfToFull(double value, double full) {
if (value == 0.5) {
return full;
} else {
return value;
}
}
then call it within your constructor, something like this.
this.cpuOne = changeHalfToFull(cpuOne);
this.cpuTwo = changeHalfToFull(cpuTwo);
this.cpuThree = changeHalfToFull(cpuThree);
this.cpuFour = changeHalfToFull(cpuFour);
This has the advantage that the key logic is expressed only once, so it's less error prone than repeating code over and over.
Idea Three - use arrays
You could use an array of four elements in the field that stores these values. You could also use an array for the constructor parameter. This has a huge advantage - it indicates that the four CPU values are somehow all "the same". In other words, there's nothing special about cpuOne compared to cpuTwo, for example. That kind of messaging within your code has real value to someone trying to understand this.
public Latency(final double full, final double[] cpuValues) {
// validation conditions go here ...
this.cpuValues = new double[4];
for (int index = 0; index <= 3; index++) {
if (cpuValues[index] == 0.5) {
this.cpuValues[index] = full;
} else {
this.cpuValues[index] = cpuValues[index];
}
}
}
Or a combination
You could use some combination of all these ideas. For example, you might have something like this, which combines all three of the above ideas.
public Latency(final double full, final double[] cpuValues) {
// validation conditions go here ...
this.cpuValues = new double[4];
for (int index = 0; index <= 3; index++) {
this.cpuValues[index] = changeHalfToFull(cpuValues[index]);
}
}
private static double changeHalfToFull(double value, double full) {
return value == 0.5 ? full : value;
}
There are obviously other possibilities. There is no single correct answer to this question. You need to choose what you're comfortable with, and what makes sense in the larger context of your project.
DRY - Don't Repeat Yourself
Each if is essentially the same. Put it in a separate method and call the method once for each cpu* variable.
public class Latency {
private double full;
private double cpuOne;
private double cpuTwo;
private double cpuThree;
private double cpuFour;
public Latency(final double full,
final double cpuOne,
final double cpuTwo,
final double cpuThree,
final double cpuFour) {
if (full > 10.0 || (full <= 0.0)) {
throw new IllegalArgumentException("Must check the values");
}
this.full = full;
if (cpuOne == 0 && cpuTwo == 0 && cpuThree == 0 && cpuFour == 0) {
throw new IllegalArgumentException("not all can be zero");
}
else {
this.cpuOne = initCpu(cpuOne);
this.cpuTwo = initCpu(cpuTwo);
this.cpuThree = initCpu(cpuThree);
this.cpuFour = initCpu(cpuFour);
}
}
private double initCpu(double cpu) {
return cpu == 0.5 ? full : cpu;
}
public static void main(String[] arg) {
new Latency(9.99, 8.0, 7.0, 6.0, 0.5);
}
}

Incorrect output for Project Euler #14 output

I'm trying to implement the algorithm to solve Project Euler Problem #14, which asks to find a number in a given range that outputs the largest Collatz conjecture sequence length. My code is below:
import java.util.ArrayList;
class Collatz {
private static ArrayList<ArrayList<Long>> previousNums = new ArrayList();
public static int seqLen(int x) {
ArrayList<Long> colSeq = new ArrayList();
long val = x;
colSeq.add(val);
while (val > 1) {
if (val%2 == 0) {
val/=2;
if (val < previousNums.size()) /*used to check if index exists*/{
colSeq.addAll(previousNums.get((int)val));
break;
}
else colSeq.add(val);
}
else {
val = 3*val + 1;
if (val < previousNums.size()) {
colSeq.addAll(previousNums.get((int)val));
break;
}
else colSeq.add(val);
}
}
previousNums.add(colSeq);
return colSeq.size();
}
public static void main(String[] args) {
int greatestNum = 0;
long totalVal = 0;
for (int i = 0; i<=1000000; i++) {
int collatz = seqLen(i);
if (collatz > totalVal) {}
greatestNum = i;
totalVal = collatz;
}
System.out.println(greatestNum + " " + totalVal);
}
}
The output I get is
1000000 153
While this is not the correct answer, 153 is the correct sequence length for 1 million. Based off of this, I could assume that my Collatz conjecture algorithm works, but not the comparison part. However, I can't really find anywhere else I could modify the code. Any ideas? Thank you and please pardon the possibility of this being a duplicate (not many other posts had the same problem).
Wow, a mere syntax error was the issue. Looks like I didn't pay attention to:
if (collatz > totalVal) {}
greatestNum = i;
totalVal = collatz;
Yup, didn't enclose the code with the braces.

Algorithm to find `balanced number` - the same number of even and odd dividers

We define balanced number as number which has the same number of even and odd dividers e.g (2 and 6 are balanced numbers). I tried to do task for polish SPOJ however I always exceed time.
The task is to find the smallest balance number bigger than given on input.
There is example input:
2 (amount of data set)
1
2
and output should be:
2
6
This is my code:
import java.math.BigDecimal;
import java.util.Scanner;
public class Main {
private static final BigDecimal TWO = new BigDecimal("2");
public static void main(String[] args) throws java.lang.Exception {
Scanner in = new Scanner(System.in);
int numberOfAttempts = in.nextInt();
for (int i = 0; i < numberOfAttempts; i++) {
BigDecimal fromNumber = in.nextBigDecimal();
findBalancedNumber(fromNumber);
}
}
private static boolean isEven(BigDecimal number){
if(number.remainder(new BigDecimal("2")).compareTo(BigDecimal.ZERO) != 0){
return false;
}
return true;
}
private static void findBalancedNumber(BigDecimal fromNumber) {
BigDecimal potentialBalancedNumber = fromNumber.add(BigDecimal.ONE);
while (true) {
int evenDivider = 0;
int oddDivider = 1; //to not start from 1 as divisor, it's always odd and divide potentialBalancedNumber so can start checking divisors from 2
if (isEven(potentialBalancedNumber)) {
evenDivider = 1;
} else {
oddDivider++;
}
for (BigDecimal divider = TWO; (divider.compareTo(potentialBalancedNumber.divide(TWO)) == -1 || divider.compareTo(potentialBalancedNumber.divide(TWO)) == 0); divider = divider.add(BigDecimal.ONE)) {
boolean isDivisor = potentialBalancedNumber.remainder(divider).compareTo(BigDecimal.ZERO) == 0;
if(isDivisor){
boolean isEven = divider.remainder(new BigDecimal("2")).compareTo(BigDecimal.ZERO) == 0;
boolean isOdd = divider.remainder(new BigDecimal("2")).compareTo(BigDecimal.ZERO) != 0;
if (isDivisor && isEven) {
evenDivider++;
} else if (isDivisor && isOdd) {
oddDivider++;
}
}
}
if (oddDivider == evenDivider) { //found balanced number
System.out.println(potentialBalancedNumber);
break;
}
potentialBalancedNumber = potentialBalancedNumber.add(BigDecimal.ONE);
}
}
}
It seems to work fine but is too slow. Can you please help to find way to optimize it, am I missing something?
As #MarkDickinson suggested, answer is:
private static void findBalancedNumberOptimized(BigDecimal fromNumber) { //2,6,10,14,18,22,26...
if(fromNumber.compareTo(BigDecimal.ONE) == 0){
System.out.println(2);
}
else {
BigDecimal result = fromNumber.divide(new BigDecimal("4")).setScale(0, RoundingMode.HALF_UP).add(BigDecimal.ONE);
result = (TWO.multiply(result).subtract(BigDecimal.ONE)).multiply(TWO); //2(2n-1)
System.out.println(result);
}
}
and it's finally green, thanks Mark!

given int X,find Y such that (X+Y) is pallindrome in binary format.works fine with values upto 12345 not working with values 123456 and above

public class aevi{
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
long num=s.nextLong();
long i=0,j;
while(i<num)
{
long p=1,sum=0,reversesum=0;
j=num+i;
while(j>0)
{
System.out.print(j%2+" ");
sum+=(j%2)*p;
p=p*10;
j=j/2;
}
long r=sum;
System.out.print(r+" ");
while(sum!=0)
{
reversesum=(reversesum*10)+(sum%10);
sum=sum/10;
}
System.out.println(reversesum);
if(reversesum==r)
{System.out.println(i);
break;}
i++;
}
}
}
whats wrong with this code.The program is about " given a number X.find minimium positive integer Y required to make binary representation of
(X+Y) palindrome.for eg:X=6 Y=1".It works fine with values upto 12345 but it is not working with values 123456 and above.
To tell the truth, it is hard to read your code and find problem. I think it is too complicated with such simple problem. I offer you another solution.
E.g. you entered x=6, this is 110 in binary format. Your goal is to find another minimal value y that x+y=<binary palindrome>. For 110, maximum palindrome id 111 which is 7. So, all you need is just find a minimal 0 <= y <= (7-6) where x+y=<binary palindrome>.
Here is the code example. It is pretty easy and simple.
public static long toBinaryPalindrome(long num) {
for (long i = 0, total = allBits(Long.toBinaryString(num).length()) - num; i <= total; i++)
if (isBinaryPalindrome(num + i))
return i;
return -1;
}
private static boolean isBinaryPalindrome(long num) {
String str = Long.toBinaryString(num);
return str.equals(new StringBuilder(str).reverse().toString());
}
private static long allBits(int len) {
long res = 0;
for (int i = 0; i < len; i++)
res |= 1 << i;
return res;
}

trying to break out of for loop but keeps going back into it and performing recursive call

I just discovered the project euler website, I have done challenges 1 and 2 and have just started number 3 in java... here is my code so far:
import java.util.ArrayList;
public class IntegerFactorise {
private static int value = 13195;
private static ArrayList<Integer> primeFactors = new ArrayList<Integer>();
private static int maxPrime = 0;
/**
* Check whether a give number is prime or not
* return boolean
*/
public static boolean isPrimeNumber(double num) {
for(int i = 2; i < num; i++) {
if(num % i == 0) {
return false;
}
}
return true;
}
/*Multiply all of the prime factors in the list of prime factors*/
public static int multiplyPrimeFactors() {
int ans = 1;
for(Integer i : primeFactors) {
ans *= i;
}
return ans;
}
/*Find the maximum prime number in the list of prime numbers*/
public static void findMaxPrime() {
int max = 0;
for(Integer i : primeFactors) {
if(i > max) {
max = i;
}
}
maxPrime = max;;
}
/**
* Find all of the prime factors for a number given the first
* prime factor
*/
public static boolean findPrimeFactors(int num) {
for(int i = 2; i <= num; i++) {
if(isPrimeNumber(i) && num % i == 0 && i == num) {
//could not possibly go further
primeFactors.add(num);
break;
}
else if(isPrimeNumber(i) && num % i == 0) {
primeFactors.add(i);
findPrimeFactors(num / i);
}
}
int sumOfPrimes = multiplyPrimeFactors();
if(sumOfPrimes == value) {
return true;
}
else {
return false;
}
}
/*start here*/
public static void main(String[] args) {
boolean found = false;
for(int i = 2; i < value; i++) {
if(isPrimeNumber(i) && value % i == 0) {
primeFactors.add(i);
found = findPrimeFactors(value / i);
if(found == true) {
findMaxPrime();
System.out.println(maxPrime);
break;
}
}
}
}
}
I am not using the large number they ask me to use yet, I am testing my code with some smaller numbers, with 13195 (their example) i get down to 29 in this bit of my code:
else if(isPrimeNumber(i) && num % i == 0) {
primeFactors.add(i);
findPrimeFactors(num / i);
}
}
int sumOfPrimes = multiplyPrimeFactors();
if(sumOfPrimes == value) {
return true;
}
It gets to the break statement then finally the check and then the return statement.
I am expecting the program to go back to the main method after my return statement, but it jumps up to:
findPrimeFactors(num / i);
and tries to finish the iteration...I guess my understanding is a flawed here, could someone explain to me why it is behaving like this? I can't wait to finish it of :) I'll find a more efficient way of doing it after I know I can get this inefficient one working.
You are using recursion, which means that a function will call itself.
So, if we trace what your function calls are when you call return, we will have something like that:
IntegerFactorise.main()
|-> IntegerFactorise.findPrimeFactors(2639)
|-> IntegerFactorise.findPrimeFactors(377)
|-> IntegerFactorise.findPrimeFactors(29) -> return true;
So, when you return in the last findPrimeFactors(), you will only return from this call, not from all the stack of calls, and the execution of the previous findPrimeFactors() will continue just after the point where you called findPrimeFactors().
If you want to return from all the stack of calls, you have to modify your code to do something like that:
else if(isPrimeNumber(i) && num % i == 0) {
primeFactors.add(i);
return findPrimeFactors(num / i);
}
So that when the last findPrimeFactors() returns, all the previous findPrimeFactors() which called it will return too.
I think the problem is that you are ignoring the return value from your recursive call to findPrimeFactors().
Let's walk through this. We start with the initial call to findPrimeFactors that happens in main. We then enter the for loop as it's the first thing in that method. Now let's say at some point we get into the else statement and thus recursively call frindPrimeFactors(num / i). This will suspend the looping, but as this recursive call starts to run you enter the for loop again (remember, the previous loop is merely paused and not finished looping yet). This time around you encounter the break, which allows this recursive call to finish out, returning true of false. When that happens you are now back to the original loop. At this point the original loop continues even if the recursive call returned true. So, you might try something like this:
if (findPrimeFactors(num / i))
return true;
I'm assuming that you need to continue looping if the recursive call returned false. If you should always finish looping upon return (whether true or false) then try this:
return findPrimeFactors(num / i);

Categories