Determining whether a number is a Fibonacci number - java

I need to to write a Java code that checks whether the user inputed number is in the Fibonacci sequence.
I have no issue writing the Fibonacci sequence to output, but (probably because its late at night) I'm struggling to think of the sequence of "whether" it is a Fibonacci number. I keep starting over and over again. Its really doing my head in.
What I currently have is the nth.
public static void main(String[] args)
{
ConsoleReader console = new ConsoleReader();
System.out.println("Enter the value for your n: ");
int num = (console.readInt());
System.out.println("\nThe largest nth fibonacci: "+fib(num));
System.out.println();
}
static int fib(int n){
int f = 0;
int g = 1;
int largeNum = -1;
for(int i = 0; i < n; i++)
{
if(i == (n-1))
largeNum = f;
System.out.print(f + " ");
f = f + g;
g = f - g;
}
return largeNum;
}

Read the section titled "recognizing fibonacci numbers" on wikipedia.
Alternatively, a positive integer z is a Fibonacci number if and only if one of 5z^2 + 4 or 5z^2 − 4 is a perfect square.[17]
Alternatively, you can keep generating fibonacci numbers until one becomes equal to your number: if it does, then your number is a fibonacci number, if not, the numbers will eventually become bigger than your number, and you can stop. This is pretty inefficient however.

If I understand correctly, what you need to do (instead of writing out the first n Fibonacci numbers) is to determine whether n is a Fibonacci number.
So you should modify your method to keep generating the Fibonacci sequence until you get a number >= n. If it equals, n is a Fibonacci number, otherwise not.
Update: bugged by #Moron's repeated claims about the formula based algorithm being superior in performance to the simple one above, I actually did a benchmark comparison - concretely between Jacopo's solution as generator algorithm and StevenH's last version as formula based algorithm. For reference, here is the exact code:
public static void main(String[] args) {
measureExecutionTimeForGeneratorAlgorithm(1);
measureExecutionTimeForFormulaAlgorithm(1);
measureExecutionTimeForGeneratorAlgorithm(10);
measureExecutionTimeForFormulaAlgorithm(10);
measureExecutionTimeForGeneratorAlgorithm(100);
measureExecutionTimeForFormulaAlgorithm(100);
measureExecutionTimeForGeneratorAlgorithm(1000);
measureExecutionTimeForFormulaAlgorithm(1000);
measureExecutionTimeForGeneratorAlgorithm(10000);
measureExecutionTimeForFormulaAlgorithm(10000);
measureExecutionTimeForGeneratorAlgorithm(100000);
measureExecutionTimeForFormulaAlgorithm(100000);
measureExecutionTimeForGeneratorAlgorithm(1000000);
measureExecutionTimeForFormulaAlgorithm(1000000);
measureExecutionTimeForGeneratorAlgorithm(10000000);
measureExecutionTimeForFormulaAlgorithm(10000000);
measureExecutionTimeForGeneratorAlgorithm(100000000);
measureExecutionTimeForFormulaAlgorithm(100000000);
measureExecutionTimeForGeneratorAlgorithm(1000000000);
measureExecutionTimeForFormulaAlgorithm(1000000000);
measureExecutionTimeForGeneratorAlgorithm(2000000000);
measureExecutionTimeForFormulaAlgorithm(2000000000);
}
static void measureExecutionTimeForGeneratorAlgorithm(int x) {
final int count = 1000000;
final long start = System.nanoTime();
for (int i = 0; i < count; i++) {
isFibByGeneration(x);
}
final double elapsedTimeInSec = (System.nanoTime() - start) * 1.0e-9;
System.out.println("Running generator algorithm " + count + " times for " + x + " took " +elapsedTimeInSec + " seconds");
}
static void measureExecutionTimeForFormulaAlgorithm(int x) {
final int count = 1000000;
final long start = System.nanoTime();
for (int i = 0; i < count; i++) {
isFibByFormula(x);
}
final double elapsedTimeInSec = (System.nanoTime() - start) * 1.0e-9;
System.out.println("Running formula algorithm " + count + " times for " + x + " took " +elapsedTimeInSec + " seconds");
}
static boolean isFibByGeneration(int x) {
int a=0;
int b=1;
int f=1;
while (b < x){
f = a + b;
a = b;
b = f;
}
return x == f;
}
private static boolean isFibByFormula(int num) {
double first = 5 * Math.pow((num), 2) + 4;
double second = 5 * Math.pow((num), 2) - 4;
return isWholeNumber(Math.sqrt(first)) || isWholeNumber(Math.sqrt(second));
}
private static boolean isWholeNumber(double num) {
return num - Math.round(num) == 0;
}
The results surprised even me:
Running generator algorithm 1000000 times for 1 took 0.007173537000000001 seconds
Running formula algorithm 1000000 times for 1 took 0.223365539 seconds
Running generator algorithm 1000000 times for 10 took 0.017330694 seconds
Running formula algorithm 1000000 times for 10 took 0.279445852 seconds
Running generator algorithm 1000000 times for 100 took 0.030283179 seconds
Running formula algorithm 1000000 times for 100 took 0.27773557800000004 seconds
Running generator algorithm 1000000 times for 1000 took 0.041044322 seconds
Running formula algorithm 1000000 times for 1000 took 0.277931134 seconds
Running generator algorithm 1000000 times for 10000 took 0.051103143000000004 seconds
Running formula algorithm 1000000 times for 10000 took 0.276980175 seconds
Running generator algorithm 1000000 times for 100000 took 0.062019335 seconds
Running formula algorithm 1000000 times for 100000 took 0.276227007 seconds
Running generator algorithm 1000000 times for 1000000 took 0.07422898800000001 seconds
Running formula algorithm 1000000 times for 1000000 took 0.275485013 seconds
Running generator algorithm 1000000 times for 10000000 took 0.085803922 seconds
Running formula algorithm 1000000 times for 10000000 took 0.27701090500000003 seconds
Running generator algorithm 1000000 times for 100000000 took 0.09543419600000001 seconds
Running formula algorithm 1000000 times for 100000000 took 0.274908403 seconds
Running generator algorithm 1000000 times for 1000000000 took 0.10683704200000001 seconds
Running formula algorithm 1000000 times for 1000000000 took 0.27524084800000004 seconds
Running generator algorithm 1000000 times for 2000000000 took 0.13019867100000002 seconds
Running formula algorithm 1000000 times for 2000000000 took 0.274846384 seconds
In short, the generator algorithm way outperforms the formula based solution on all positive int values - even close to the maximum int value it is more than twice as fast!
So much for belief based performance optimization ;-)
For the record, modifying the above code to use long variables instead of int, the generator algorithm becomes slower (as expected, since it has to add up long values now), and cutover point where the formula starts to be faster is around 1000000000000L, i.e. 1012.
Update2: As IVlad and Moron noted, I am not quite an expert in floating point calculations :-) based on their suggestions I improved the formula to this:
private static boolean isFibByFormula(long num)
{
double power = (double)num * (double)num;
double first = 5 * power + 4;
double second = 5 * power - 4;
return isWholeNumber(Math.sqrt(first)) || isWholeNumber(Math.sqrt(second));
}
This brought down the cutover point to approx. 108 (for the long version - the generator with int is still faster for all int values). No doubt that replacing the sqrt calls with something like suggested by #Moron would push down the cutover point further.
My (and IVlad's) point was simply that there will always be a cutover point, below which the generator algorithm is faster. So claims about which one performs better have no meaning in general, only in a context.

Instead of passing the index, n, write a function that takes a limit, and get it to generate the Fibonacci numbers up to and including this limit. Get it to return a Boolean depending on whether it hits or skips over the limit, and you can use this to check whether that value is in the sequence.
Since it's homework, a nudge like this is probably all we should be giving you...

Ok. Since people claimed I am just talking thin air ('facts' vs 'guesses') without any data to back it up, I wrote a benchmark of my own.
Not java, but C# code below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SO
{
class Program
{
static void Main(string[] args)
{
AssertIsFibSqrt(100000000);
MeasureSequential(1);
MeasureSqrt(1);
MeasureSequential(10);
MeasureSqrt(10);
MeasureSequential(50);
MeasureSqrt(50);
MeasureSequential(100);
MeasureSqrt(100);
MeasureSequential(100000);
MeasureSqrt(100000);
MeasureSequential(100000000);
MeasureSqrt(100000000);
}
static void MeasureSequential(long n)
{
int count = 1000000;
DateTime start = DateTime.Now;
for (int i = 0; i < count; i++)
{
IsFibSequential(n);
}
DateTime end = DateTime.Now;
TimeSpan duration = end - start;
Console.WriteLine("Sequential for input = " + n +
" : " + duration.Ticks);
}
static void MeasureSqrt(long n)
{
int count = 1000000;
DateTime start = DateTime.Now;
for (int i = 0; i < count; i++)
{
IsFibSqrt(n);
}
DateTime end = DateTime.Now;
TimeSpan duration = end - start;
Console.WriteLine("Sqrt for input = " + n +
" : " + duration.Ticks);
}
static void AssertIsFibSqrt(long x)
{
Dictionary<long, bool> fibs = new Dictionary<long, bool>();
long a = 0;
long b = 1;
long f = 1;
while (b < x)
{
f = a + b;
a = b;
b = f;
fibs[a] = true;
fibs[b] = true;
}
for (long i = 1; i <= x; i++)
{
bool isFib = fibs.ContainsKey(i);
if (isFib && IsFibSqrt(i))
{
continue;
}
if (!isFib && !IsFibSqrt(i))
{
continue;
}
Console.WriteLine("Sqrt Fib test failed for: " + i);
}
}
static bool IsFibSequential(long x)
{
long a = 0;
long b = 1;
long f = 1;
while (b < x)
{
f = a + b;
a = b;
b = f;
}
return x == f;
}
static bool IsFibSqrt(long x)
{
long y = 5 * x * x + 4;
double doubleS = Math.Sqrt(y);
long s = (long)doubleS;
long sqr = s*s;
return (sqr == y || sqr == (y-8));
}
}
}
And here is the output
Sequential for input = 1 : 110011
Sqrt for input = 1 : 670067
Sequential for input = 10 : 560056
Sqrt for input = 10 : 540054
Sequential for input = 50 : 610061
Sqrt for input = 50 : 540054
Sequential for input = 100 : 730073
Sqrt for input = 100 : 540054
Sequential for input = 100000 : 1490149
Sqrt for input = 100000 : 540054
Sequential for input = 100000000 : 2180218
Sqrt for input = 100000000 : 540054
The sqrt method beats the naive method when n=50 itself, perhaps due to the presence of hardware support on my machine. Even if it was 10^8 (like in Peter's test), there are at most 40 fibonacci numbers under that cutoff, which could easily be put in a lookup table and still beat the naive version for the smaller values.
Also, Peter has a bad implementation of the SqrtVersion. He doesn't really need to compute two square roots or compute powers using Math.Pow. He could have atleast tried to make that better before publishing his benchmark results.
Anyway, I will let these facts speak for themselves, instead of the so called 'guesses'.

A positive integer x is a Fibonacci number if and only if one of 5x^2 + 4 and 5x^2 - 4 is a perfect square

There are a number of methods that can be employed to determine if a given number is in the fibonacci sequence, a selection of which can be seen on wikipedia.
Given what you've done already, however, I'd probably use a more brute-force approach, such as the following:
Generate a fibonacci number
If it's less than the target number, generate the next fibonacci and repeat
If it is the target number, then success
If it's bigger than the target number, then failure.
I'd probably use a recursive method, passing in a current n-value (ie. so it calculates the nth fibonacci number) and the target number.

//Program begins
public class isANumberFibonacci {
public static int fibonacci(int seriesLength) {
if (seriesLength == 1 || seriesLength == 2) {
return 1;
} else {
return fibonacci(seriesLength - 1) + fibonacci(seriesLength - 2);
}
}
public static void main(String args[]) {
int number = 4101;
int i = 1;
while (i > 0) {
int fibnumber = fibonacci(i);
if (fibnumber != number) {
if (fibnumber > number) {
System.out.println("Not fib");
break;
} else {
i++;
}
} else {
System.out.println("The number is fibonacci");
break;
}
}
}
}
//Program ends

If my Java is not too rusty...
static bool isFib(int x) {
int a=0;
int b=1;
int f=1;
while (b < x){
f = a + b;
a = b;
b = f;
}
return x == f;
}

Trying to leverage the code you have already written I would propose the following first, as it is the simplest solution (but not the most efficient):
private static void main(string[] args)
{
//This will determnine which numbers between 1 & 100 are in the fibonacci series
//you can swop in code to read from console rather than 'i' being used from the for loop
for (int i = 0; i < 100; i++)
{
bool result = isFib(1);
if (result)
System.out.println(i + " is in the Fib series.");
System.out.println(result);
}
}
private static bool isFib(int num)
{
int counter = 0;
while (true)
{
if (fib(counter) < num)
{
counter++;
continue;
}
if (fib(counter) == num)
{
return true;
}
if (fib(counter) > num)
{
return false;
}
}
}
I would propose a more elegant solution in the generation of fibonacci numbers which leverages recursion like so:
public static long fib(int n)
{
if (n <= 1)
return n;
else
return fib(n-1) + fib(n-2);
}
For the extra credit read: http://en.wikipedia.org/wiki/Fibonacci_number#Recognizing_Fibonacci_numbers
You will see the that there are a few more efficient ways to test if a number is in the Fibonacci series namely: (5z^2 + 4 or 5z^2 − 4) = a perfect square.
//(5z^2 + 4 or 5z^2 − 4) = a perfect square
//perfect square = an integer that is the square of an integer
private static bool isFib(int num)
{
double first = 5 * Math.pow((num), 2) + 4;
double second = 5 * Math.pow((num), 2) - 4;
return isWholeNumber(Math.sqrt(first)) || isWholeNumber(Math.sqrt(second));
}
private static bool isWholeNumber(double num)
{
return num - Math.round(num) == 0;
}

I don't know if there is an actual formula that you can apply to the user input however, you can generate the fibonacci sequence and check it against the user input until it has become smaller than the last number generated.
int userInput = n;
int a = 1, b = 1;
while (a < n) {
if (a == n)
return true;
int next = a + b;
b = a;
a = next;
}
return false;

You can do this in two ways , the recursive and mathematical.
the recursive way
start generating fibonacci sequence until you hit the number or pass it
the mathematical way nicely described here ...
http://www.physicsforums.com/showthread.php?t=252798
good luck.

Consider the sequence of Fibonacci numbers 1,1,2,3,5,8,13,21, etc. It is desired to build 3 stacks each of capacity 10 containing numbers from the above sequences as follows:
Stack 1: First 10 numbers from the sequence.
Stack 2: First 10 prime numbers from the sequence.
Stack 3: First 10 non-prime numbers from the sequence.
(i) Give an algorithm of the flowchart
(ii) Write a program (in BASIC, C++ or Java) to implement this.
Output:As stack operations take place you should display in any convenient form the 3 stacks together with the values held in them.

Finding out whether a number is Fibonacci based on formula:
public static boolean isNumberFromFibonacciSequence(int num){
if (num == 0 || num == 1){
return true;
}
else {
//5n^2 - 4 OR 5n^2 + 4 should be perfect squares
return isPerfectSquare( 5*num*num - 4) || isPerfectSquare(5*num*num - 4);
}
}
private static boolean isPerfectSquare(int num){
double sqrt = Math.sqrt(num);
return sqrt * sqrt == num;
}

Thought it was simple until i had to rack my head on it a few minutes. Its quite different from generating a fibonacci sequence. This function returns 1 if is Fibonnaci or 0 if not
public static int isFibonacci (int n){
int isFib = 0;
int a = 0, b = 0, c = a + b; // set up the initial values
do
{
a = b;
b = c;
c = a + b;
if (c == n)
isFib = 1;
} while (c<=n && isFin == 0)
return isFib;
}
public static void main(String [] args){
System.out.println(isFibonacci(89));
}

Related

Quick way to find a factorial of a large number

This is my program, but for really large numbers like 100,000, it works very slowly, is there any option to optimize?
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
BigInteger sum = BigInteger.valueOf(1);
for (BigInteger i = BigInteger.valueOf(n);
i.compareTo(BigInteger.ZERO) > 0;
i = i.subtract(BigInteger.ONE)) {
sum = sum.multiply(i);
}
System.out.println(sum);
}
}
Just to illustrate that it sometimes pays to manipulate the expression, I modified the standard multiplication loop that computes 1*2*3*...*n to break it into two parts: one part multiplies the odd integers together (1*3*5*...) and the other multiplies the evens together (2*4*6*...). The evens product is further broken down by multiplying the evens that are 0 mod 2 but not 0 mod 4 (e.g. 2*6*10*...), then the evens that are 0 mod 4 but not 0 mod 8 (e.g. 4*12*20*28*...) and so on, but the power of 2 is shifted out of the number first. The powers of two are counted up, and the product is then shifted left all at once at the end. This takes advantage of the how the Java 8 BigInteger is implemented to make large left shifts fairly efficient.
private static BigInteger fac4(int n) {
BigInteger evens = multiplyEvens(n);
BigInteger odds = multiplyOdds(n);
BigInteger product = evens.multiply(odds);
return product;
}
private static BigInteger multiplyOdds(int n) {
BigInteger odds = BigInteger.ONE;
for (long i=1; i<=n; i+=2) {
odds = odds.multiply(BigInteger.valueOf(i));
}
return odds;
}
private static BigInteger multiplyEvens(int n) {
BigInteger evens = BigInteger.ONE;
long pow2 = 1;
int shiftAmount = 0;
while ((1 << pow2) <= n) {
for (long i = (1<<pow2); i <= n; i += (1 << (pow2 + 1))) {
shiftAmount += pow2;
evens = evens.multiply(BigInteger.valueOf(i >> pow2));
}
++pow2;
}
return evens.shiftLeft(shiftAmount);
}
public static void main(String[] args) {
// Print out some small factorials to verify things are working
for (int i = 0; i < 10; i++) {
System.out.printf("%d! = %d%n", i, fac4(i));
}
Scanner in = new Scanner(System.in);
int n = in.nextInt();
long start = System.currentTimeMillis();
BigInteger fac = fac4(n);
long end = System.currentTimeMillis();
float total = end - start;
System.out.printf("%d! is %d bits long, took %f seconds to compute", n, fac.bitLength(), total / 1000);
}
Here is the input/output log for one run of n=100000:
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
100000
100000! is 1516705 bits long, took 1.758000 seconds to compute
For comparison, my implementation of the straightforward multiple loop took about 3 seconds.
EDIT:
Here is another implementation I tried that was even faster. The idea is to take advantage of the fact that Java 8+ BigInteger includes asymptotically faster than O(n2) algorithms when the operands of multiply get big enough to provide an advantage. However, the naive method always multiplies a single 'limb' integer by a rapidly growing accumulated product. This approach is not amenable to the faster algorithms. However, if we multiply approximately equal operands then the faster algorithms are possible.
private static final int SIMPLE_THRESHOLD = 10;
private static BigInteger fac6(int n) {
return subfac(1, n);
}
/**
* compute a * (a+1) * ... *(b-1) * b
* The interval [a,b] includes the endpoints a and b.
*
* #param a the interval start.
* #param b the interval end, inclusive.
* #return the product.
*/
private static BigInteger subfac(int a, int b) {
if ((b-a) < SIMPLE_THRESHOLD) {
BigInteger result = BigInteger.ONE;
for (int i=a; i<=b; i++) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
} else {
int mid = a + (b-a) / 2;
return subfac(a, mid).multiply(subfac(mid+1, b));
}
}
And the output using the same main() method as above was:
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
100000
100000! is 1516705 bits long, took 0.243000 seconds to compute
So fac6() is almost 10 times faster than fac4(). A few experiments suggest that the value of SIMPLE_THRESHOLD has very little effect on the speed, presumably because the overhead of function call is dwarfed by the cost of the BigInteger multiplication.
All these experiments were run on a Mac OS X High Sierra laptop using JDK 1.8.0_181.
This is my first obvious implementation:
public static void main(String[] args) {
long start = System.currentTimeMillis();
int n = 100000;
BigInteger bigInteger = BigInteger.ONE;
for (int i = 1; i < n; i++) {
bigInteger = bigInteger.multiply(BigInteger.valueOf(i));
}
System.out.println(bigInteger);
long end = System.currentTimeMillis();
float total = end - start;
System.out.println(total);
}
Factorial of 100000 is a number with 456569 digits (so I can't print it here), and my solution takes 3.5 seconds, more or less.
If that's not assumible for you, you must design a multi-thread based solution. For instance, one thread multiply first half of n and another thread does the same but for the second half. Then, multiply those two numbers.

Represent an Integer as a sum of Consecutive positive integers

I am writing code for counting the number of ways an integer can be represented as a sum of the consecutive integers. For Example
15=(7+8),(1+2+3+4+5),(4+5+6). So the number of ways equals 3 for 15.
Now the input size can be <=10^12. My program is working fine till 10^7(i think so, but not sure as i didnt check it on any online judge. Feel free to check the code for that)
but as soon as the i give it 10^8 or higher integer as input. it throws many runtime exceptions(it doesnt show what runtime error). Thanks in advance.
import java.io.*;
//sum needs to contain atleast 2 elements
public class IntegerRepresentedAsSumOfConsecutivePositiveIntegers
{
public static long count = 0;
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long num = Long.parseLong(br.readLine()); //Enter a number( <=10^12)
driver(num);
System.out.println("count = " + count);
}
public static void driver(long num)
{
long limit = num / 2;
for(long i = 1 ; i <= limit ; i++)
{
func(i,num);
}
}
public static void func(long i,long num)
{
if(i < num)
{
func(i + 1,num - i);
}
else if(i > num)
{
return;
}
else
{
count++;
}
}
}
Use some math: if arithmetic progression with difference 1 starts with a0 and contains n items, then its sum is
S = (2 * a0 + (n-1))/2 * n = a0 * n + n * (n-1) / 2
note that the second summand rises as quadratic function. So instead of checking all a0 in range S/2, we can check all n is smaller range
nmax = Ceil((-1 + Sqrt(1 + 8 * S)) / 2)
(I used some higher approximation).
Just test whether next expression gives integer positive result
a0 = (S - n * (n - 1) / 2) / n
Recursive function isn't suitable when you have big input size like your case.
The maximum depth of the java call stack is about 8900 calls and sometimes only after 7700 calls stack overflow occurs so it really depends on your program input size.
Try this algorithm I think it worked for your problem:
it will work fine until 10^9 after that it will take much more time to finish running the program.
long sum = 0;
int count = 0;
long size;
Scanner in = new Scanner(System.in);
System.out.print("Enter a number <=10^12: ");
long n = in.nextLong();
if(n % 2 != 0){
size = n / 2 + 1;
}
else{
size = n / 2;
}
for(int i = 1; i <= size; i++){
for(int j = i; j <= size; j++){
sum = sum + j;
if(sum == n){
sum = 0;
count++;
break;
}
else if(sum > n){
sum = 0;
break;
}
}
}
System.out.println(count);
Output:
Enter a number <=10^12: 15
3
Enter a number <=10^12: 1000000000
9
BUILD SUCCESSFUL (total time: 10 seconds)
There's a really excellent proof that the answer can be determined by solving for the unique odd factors (Reference). Essentially, for every odd factor of a target value, there exists either an odd series of numbers of that factor multiplied by its average to produce the target value, or an odd average equal to that factor that can be multiplied by double an even-sized series to reach the target value.
public static int countUniqueOddFactors(long n) {
if (n==1) return 1;
Map<Long, Integer> countFactors=new HashMap<>();
while ((n&1)==0) n>>>=1; // Eliminate even factors
long divisor=3;
long max=(long) Math.sqrt(n);
while (divisor <= max) {
if (n % divisor==0) {
if (countFactors.containsKey(divisor)) {
countFactors.put(divisor, countFactors.get(divisor)+1);
} else {
countFactors.put(divisor, 1);
}
n /= divisor;
} else {
divisor+=2;
}
}
int factors=1;
for (Integer factorCt : countFactors.values()) {
factors*=(factorCt+1);
}
return factors;
}
As #MBo noted, if a number S can be partitioned into n consecutive parts, then S - T(n) must be divisible by n, where T(n) is the n'th triangular number, and so you can count the number of partitions in O(sqrt(S)) time.
// number of integer partitions into (at least 2) consecutive parts
static int numberOfTrapezoidalPartitions(final long sum) {
assert sum > 0: sum;
int n = 2;
int numberOfPartitions = 0;
long triangularNumber = n * (n + 1) / 2;
while (sum - triangularNumber >= 0) {
long difference = sum - triangularNumber;
if (difference == 0 || difference % n == 0)
numberOfPartitions++;
n++;
triangularNumber += n;
}
return numberOfPartitions;
}
A bit more math yields an even simpler way. Wikipedia says:
The politeness of a positive number is defined as the number of ways it can be expressed as the sum of consecutive integers. For every x, the politeness of x equals the number of odd divisors of x that are greater than one.
Also see: OEIS A069283
So a simple solution with lots of room for optimization is:
// number of odd divisors greater than one
static int politeness(long x) {
assert x > 0: x;
int p = 0;
for (int d = 3; d <= x; d += 2)
if (x % d == 0)
p++;
return p;
}

Alternative to long in order to avoid overflowing Fibonacci Numbers

New to Stackoverflow so please point out anything I can do to improve the quality of my question.
So what my code does (or rather hopes to do) is calculate huge fibonacci numbers modulo a pretty huge m. To make the algorithm more efficient, I employ the use of pisano periods. In essence, I calculate the pisano period of m and then make the calculation of the remainder easier by using the following relation:
The remainder of the n th Fibonacci number (modulo m) is equal to the remainder of the k th Fibonacci number (modulo m) such that k = n % p where p is the pisano period of m.
In order to calculate the pisano period, I use the following property:
If the current Fib % m = 0 and the sum of all Fib's until now % m = 0, then the index of the current Fib is the pisano period of m. (Note the index must be greater than 0)
However I run into a problem in this endeavour: To calculate the pisano period, I have to calculate consecutive Fibonacci numbers. The issue arises when the number of Fibonacci numbers that have to be calculate becomes very large, say 100 000. Then the data type long overflows.
To my knowledge, any endeavour to calculate pisano periods will require the calculation of fibonacci's, so the only solution seems to be to replace long with something else. If anyone has any suggestions as to what this replacement might be, I would greatly appreciate it.
import java.util.*;
public class FibHuge {
public static void main (String [] args) {
Scanner in = new Scanner (System.in);
long num = in.nextLong ();
long mod = in.nextLong();
System.out.println ( getMod(num, mod));
}
private static int getMod (long num, long mod) {
Period per = new Period();
long period = per.getPeriod (mod);
int newFibNum = (int)(num % period);
num = (num % mod);
Integer ia[] = new Integer [per.al.size()];
ia = per.al.toArray (ia);
return ia[newFibNum];
}
}
class Period {
ArrayList <Long> al;
long FNum;
long SNum;
Period () {
al = new ArrayList <Long> ();
FNum = 0;
SNum = 1;
}
private long getFib (long first, long second){
return first + second;
}
long getPeriod (long mod){
boolean bool = true;
long fibcount = 0;
long currentmod = 0;
long fib = 0;
long sum = 0;
while (bool){
if (fibcount <= 1){
currentmod = fibcount % mod;
al.add (currentmod);
sum += fibcount;
}
else {
fib = getFib (FNum, SNum);
FNum = SNum;
SNum = fib;
currentmod = (fib % mod);
al.add (currentmod);
sum += fib;
}
if ( (currentmod == 0 & (sum % mod) == 0) & fibcount > 0){
return fibcount;
}
fibcount++;
}
return mod; //essentially just to satisfy the return condition
}
}
Use BigInteger, but take note that it will be much slower, but with infinite size.
You don't need to use BigInteger unless your modulus is too large to fit into a long in which case I suspect you will run out of memory trying to find the solution.
Instead of calculating the n-th Fibonacci number and then performing a modulus, you can calculate the n-th Fibonacci after modulus using this property
(a + b) % n = (a % n + b % n) % n;
In other words you only need to keep adding the modulus of the number in each iteration. You can save all the modulus values in a Set and when you get a repeated result, you have a period. You can store the iteration number with the result and use this to calculate the period.
In fact modulus is kind of expensive but since you will only ever sum a number which is less than 2 * modulus you can simply do
long c = a + b; // Fibonacci
if (c >= modulus) c -= modulus; // the only real change you need for modulus.
As Java uses a condition move rather than an actual branch this is much faster than using %
I can't think of much more details you need to know without writing the code for you.

Big numbers calculations in Java?

I have this Java code for computing some numbers
import java.math.BigInteger;
class Challenge {
final static BigInteger THOUSAND = new BigInteger("1000");
private static BigInteger compute(long n) {
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
for (long i = 0; i < n; i++) {
BigInteger next = b.multiply(b).add(a);
a = b;
b = next;
}
return b.mod(THOUSAND);
}
public static void main(String args[]) {
for (long n : new long[] { 1L, 2L, 5L, 10L, 20L, Long.MAX_VALUE }) {
System.out.print(n + " ---> ");
System.out.println(compute(n));
}
}
}
The code iterates several times according to given long numbers (1, 2, 5, etc), starting with a=1 and b=1:
next = (b*b)+a
a = b
b = next
It then returns b mod 1000, which it gives the last 3 digits of the calculation.
So far the codes returns:
1 ---> 2
2 ---> 5
5 ---> 783
10 ---> 968
20 ---> 351
9223372036854775807 --->
On the last one the code keeps working but the number if iterations is so big it takes forever so it never finishes.
Is there a way to do this kind of calculations faster, or to get the desired value (mod 1000 of the calculation done that many times) in a better way?
It would be a lot faster if you use an int for your calculations. However you will get a better speed up from realising that in each iteration there is only 1,000,000 possible starting values for a and b which means the longest possible sequence of values and results for a and b without repeating is one million. i.e. you can n % 1,000,000 Most likely there is a shorter repeating sequences.
The reason I say only the lower three digits of a and b matter is that you mod 1000 the result, so not matter what the upper digits of a and b are they are ignored so all you care about are the values 0 to 999
You can memorizes all possible results starting at 1,1 and it will just be a lookup.
private static long compute(long n) {
int a = 1;
int b = 1;
for (int i = 0, max = (int) (n % 1000000); i < max; i++) {
int next = b * b + a;
a = b;
b = next % 1000;
}
return b % 1000;
}
Yes, keep the running moludo for each calculation. You don't need to calculate all the digits since you are only interested in the last 3 ones.
A first improvement is to have the following:
private static BigInteger compute(long n) {
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
for (long i = 0; i < n; i++) {
BigInteger next = b.multiply(b).add(a);
a = b;
b = next.mod(THOUSAND); // <-- only keep the modulo each time so as not calculate all digits
}
return b.mod(THOUSAND);
}
By doing this, you can realize that you don't need BigInteger to begin with. The numbers concerned become of value low enough that they hold into a primitive datatype. As such, use a long (or even an int): it will be a lot more performant since you don't have the overhead of using a BigInteger.
private static long compute(long n) {
int a = 1;
int b = 1;
for (long i = 0; i < n; i++) {
int next = b*b + a;
a = b;
b = next % 1000;
}
return b % 1000;
}
Note that this code still won't give you the result for 9223372036854775807 as input. It is simply not possible to loop 9223372036854775807 times. However, this produces the correct result for 100 million in under 5 seconds on my old machine.
The number is to big. It's normal to take so long to process this function.
You can try to check using this:
long startTime = System.currentTimeMillis();
.....your program....
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println(totalTime);
the estimate time to finish it.

Is there a method that calculates a factorial in Java? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 7 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I didn't find it, yet. Did I miss something?
I know a factorial method is a common example program for beginners. But wouldn't it be useful to have a standard implementation for this one to reuse?
I could use such a method with standard types (Eg. int, long...) and with BigInteger / BigDecimal, too.
Apache Commons Math has a few factorial methods in the MathUtils class.
public class UsefulMethods {
public static long factorial(int number) {
long result = 1;
for (int factor = 2; factor <= number; factor++) {
result *= factor;
}
return result;
}
}
Big Numbers version by HoldOffHunger:
public static BigInteger factorial(BigInteger number) {
BigInteger result = BigInteger.valueOf(1);
for (long factor = 2; factor <= number.longValue(); factor++) {
result = result.multiply(BigInteger.valueOf(factor));
}
return result;
}
I don't think it would be useful to have a library function for factorial. There is a good deal of research into efficient factorial implementations. Here is a handful of implementations.
Bare naked factorials are rarely needed in practice. Most often you will need one of the following:
1) divide one factorial by another, or
2) approximated floating-point answer.
In both cases, you'd be better with simple custom solutions.
In case (1), say, if x = 90! / 85!, then you'll calculate the result just as x = 86 * 87 * 88 * 89 * 90, without a need to hold 90! in memory :)
In case (2), google for "Stirling's approximation".
Use Guava's BigIntegerMath as follows:
BigInteger factorial = BigIntegerMath.factorial(n);
(Similar functionality for int and long is available in IntMath and LongMath respectively.)
Although factorials make a nice exercise for the beginning programmer, they're not very useful in most cases, and everyone knows how to write a factorial function, so they're typically not in the average library.
i believe this would be the fastest way, by a lookup table:
private static final long[] FACTORIAL_TABLE = initFactorialTable();
private static long[] initFactorialTable() {
final long[] factorialTable = new long[21];
factorialTable[0] = 1;
for (int i=1; i<factorialTable.length; i++)
factorialTable[i] = factorialTable[i-1] * i;
return factorialTable;
}
/**
* Actually, even for {#code long}, it works only until 20 inclusively.
*/
public static long factorial(final int n) {
if ((n < 0) || (n > 20))
throw new OutOfRangeException("n", 0, 20);
return FACTORIAL_TABLE[n];
}
For the native type long (8 bytes), it can only hold up to 20!
20! = 2432902008176640000(10) = 0x 21C3 677C 82B4 0000
Obviously, 21! will cause overflow.
Therefore, for native type long, only a maximum of 20! is allowed, meaningful, and correct.
Because factorial grows so quickly, stack overflow is not an issue if you use recursion. In fact, the value of 20! is the largest one can represent in a Java long. So the following method will either calculate factorial(n) or throw an IllegalArgumentException if n is too big.
public long factorial(int n) {
if (n > 20) throw new IllegalArgumentException(n + " is out of range");
return (1 > n) ? 1 : n * factorial(n - 1);
}
Another (cooler) way to do the same stuff is to use Java 8's stream library like this:
public long factorial(int n) {
if (n > 20) throw new IllegalArgumentException(n + " is out of range");
return LongStream.rangeClosed(1, n).reduce(1, (a, b) -> a * b);
}
Read more on Factorials using Java 8's streams
Apache Commons Math package has a factorial method, I think you could use that.
Short answer is: use recursion.
You can create one method and call that method right inside the same method recursively:
public class factorial {
public static void main(String[] args) {
System.out.println(calc(10));
}
public static long calc(long n) {
if (n <= 1)
return 1;
else
return n * calc(n - 1);
}
}
Try this
public static BigInteger factorial(int value){
if(value < 0){
throw new IllegalArgumentException("Value must be positive");
}
BigInteger result = BigInteger.ONE;
for (int i = 2; i <= value; i++) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
You can use recursion.
public static int factorial(int n){
if (n == 0)
return 1;
else
return(n * factorial(n-1));
}
and then after you create the method(function) above:
System.out.println(factorial(number of your choice));
//direct example
System.out.println(factorial(3));
I found an amazing trick to find factorials in just half the actual multiplications.
Please be patient as this is a little bit of a long post.
For Even Numbers:
To halve the multiplication with even numbers, you will end up with n/2 factors. The first factor will be the number you are taking the factorial of, then the next will be that number plus that number minus two. The next number will be the previous number plus the lasted added number minus two. You are done when the last number you added was two (i.e. 2). That probably didn't make much sense, so let me give you an example.
8! = 8 * (8 + 6 = 14) * (14 + 4 = 18) * (18 + 2 = 20)
8! = 8 * 14 * 18 * 20 which is **40320**
Note that I started with 8, then the first number I added was 6, then 4, then 2, each number added being two less then the number added before it. This method is equivalent to multiplying the least numbers with the greatest numbers, just with less multiplication, like so:
8! = 1 * 2 * 3 * 4 * 5 * 6 * 7 *
8! = (1 * 8) * (2 * 7) * (3 * 6) * (4 * 5)
8! = 8 * 14 * 18 * 20
Simple isn't it :)
Now For Odd Numbers: If the number is odd, the adding is the same, as in you subtract two each time, but you stop at three. The number of factors however changes. If you divide the number by two, you will end up with some number ending in .5. The reason is that if we multiply the ends together, that we are left with the middle number. Basically, this can all be solved by solving for a number of factors equal to the number divided by two, rounded up. This probably didn't make much sense either to minds without a mathematical background, so let me do an example:
9! = 9 * (9 + 7 = 16) * (16 + 5 = 21) * (21 + 3 = 24) * (roundUp(9/2) = 5)
9! = 9 * 16 * 21 * 24 * 5 = **362880**
Note: If you don't like this method, you could also just take the factorial of the even number before the odd (eight in this case) and multiply it by the odd number (i.e. 9! = 8! * 9).
Now let's implement it in Java:
public static int getFactorial(int num)
{
int factorial=1;
int diffrennceFromActualNum=0;
int previousSum=num;
if(num==0) //Returning 1 as factorial if number is 0
return 1;
if(num%2==0)// Checking if Number is odd or even
{
while(num-diffrennceFromActualNum>=2)
{
if(!isFirst)
{
previousSum=previousSum+(num-diffrennceFromActualNum);
}
isFirst=false;
factorial*=previousSum;
diffrennceFromActualNum+=2;
}
}
else // In Odd Case (Number * getFactorial(Number-1))
{
factorial=num*getFactorial(num-1);
}
return factorial;
}
isFirst is a boolean variable declared as static; it is used for the 1st case where we do not want to change the previous sum.
Try with even as well as for odd numbers.
The only business use for a factorial that I can think of is the Erlang B and Erlang C formulas, and not everyone works in a call center or for the phone company. A feature's usefulness for business seems to often dictate what shows up in a language - look at all the data handling, XML, and web functions in the major languages.
It is easy to keep a factorial snippet or library function for something like this around.
A very simple method to calculate factorials:
private double FACT(double n) {
double num = n;
double total = 1;
if(num != 0 | num != 1){
total = num;
}else if(num == 1 | num == 0){
total = 1;
}
double num2;
while(num > 1){
num2 = num - 1;
total = total * num2;
num = num - 1;
}
return total;
}
I have used double because they can hold massive numbers, but you can use any other type like int, long, float, etc.
P.S. This might not be the best solution but I am new to coding and it took me ages to find a simple code that could calculate factorials so I had to write the method myself but I am putting this on here so it helps other people like me.
You can use recursion version as well.
static int myFactorial(int i) {
if(i == 1)
return;
else
System.out.prinln(i * (myFactorial(--i)));
}
Recursion is usually less efficient because of having to push and pop recursions, so iteration is quicker. On the other hand, recursive versions use fewer or no local variables which is advantage.
We need to implement iteratively. If we implement recursively, it will causes StackOverflow if input becomes very big (i.e. 2 billions). And we need to use unbound size number such as BigInteger to avoid an arithmatic overflow when a factorial number becomes bigger than maximum number of a given type (i.e. 2 billion for int). You can use int for maximum 14 of factorial and long for maximum 20
of factorial before the overflow.
public BigInteger getFactorialIteratively(BigInteger input) {
if (input.compareTo(BigInteger.ZERO) <= 0) {
throw new IllegalArgumentException("zero or negatives are not allowed");
}
BigInteger result = BigInteger.ONE;
for (BigInteger i = BigInteger.ONE; i.compareTo(input) <= 0; i = i.add(BigInteger.ONE)) {
result = result.multiply(i);
}
return result;
}
If you can't use BigInteger, add an error checking.
public long getFactorialIteratively(long input) {
if (input <= 0) {
throw new IllegalArgumentException("zero or negatives are not allowed");
} else if (input == 1) {
return 1;
}
long prev = 1;
long result = 0;
for (long i = 2; i <= input; i++) {
result = prev * i;
if (result / prev != i) { // check if result holds the definition of factorial
// arithmatic overflow, error out
throw new RuntimeException("value "+i+" is too big to calculate a factorial, prev:"+prev+", current:"+result);
}
prev = result;
}
return result;
}
Factorial is highly increasing discrete function.So I think using BigInteger is better than using int.
I have implemented following code for calculation of factorial of non-negative integers.I have used recursion in place of using a loop.
public BigInteger factorial(BigInteger x){
if(x.compareTo(new BigInteger("1"))==0||x.compareTo(new BigInteger("0"))==0)
return new BigInteger("1");
else return x.multiply(factorial(x.subtract(new BigInteger("1"))));
}
Here the range of big integer is
-2^Integer.MAX_VALUE (exclusive) to +2^Integer.MAX_VALUE,
where Integer.MAX_VALUE=2^31.
However the range of the factorial method given above can be extended up to twice by using unsigned BigInteger.
We have a single line to calculate it:
Long factorialNumber = LongStream.rangeClosed(2, N).reduce(1, Math::multiplyExact);
A fairly simple method
for ( int i = 1; i < n ; i++ )
{
answer = answer * i;
}
/**
import java liberary class
*/
import java.util.Scanner;
/* class to find factorial of a number
*/
public class factorial
{
public static void main(String[] args)
{
// scanner method for read keayboard values
Scanner factor= new Scanner(System.in);
int n;
double total = 1;
double sum= 1;
System.out.println("\nPlease enter an integer: ");
n = factor.nextInt();
// evaluvate the integer is greater than zero and calculate factorial
if(n==0)
{
System.out.println(" Factorial of 0 is 1");
}
else if (n>0)
{
System.out.println("\nThe factorial of " + n + " is " );
System.out.print(n);
for(int i=1;i<n;i++)
{
do // do while loop for display each integer in the factorial
{
System.out.print("*"+(n-i) );
}
while ( n == 1);
total = total * i;
}
// calculate factorial
sum= total * n;
// display sum of factorial
System.out.println("\n\nThe "+ n +" Factorial is : "+" "+ sum);
}
// display invalid entry, if enter a value less than zero
else
{
System.out.println("\nInvalid entry!!");
}System.exit(0);
}
}
public static int fact(int i){
if(i==0)
return 0;
if(i>1){
i = i * fact(--i);
}
return i;
}
public int factorial(int num) {
if (num == 1) return 1;
return num * factorial(num - 1);
}
while loop (for small numbers)
public class factorial {
public static void main(String[] args) {
int counter=1, sum=1;
while (counter<=10) {
sum=sum*counter;
counter++;
}
System.out.println("Factorial of 10 is " +sum);
}
}
I got this from EDX use it! its called recursion
public static int factorial(int n) {
if (n == 1) {
return 1;
} else {
return n * factorial(n-1);
}
}
with recursion:
public static int factorial(int n)
{
if(n == 1)
{
return 1;
}
return n * factorial(n-1);
}
with while loop:
public static int factorial1(int n)
{
int fact=1;
while(n>=1)
{
fact=fact*n;
n--;
}
return fact;
}
using recursion is the simplest method. if we want to find the factorial of
N, we have to consider the two cases where N = 1 and N>1 since in factorial
we keep multiplying N,N-1, N-2,,,,, until 1. if we go to N= 0 we will get 0
for the answer. in order to stop the factorial reaching zero, the following
recursive method is used. Inside the factorial function,while N>1, the return
value is multiplied with another initiation of the factorial function. this
will keep the code recursively calling the factorial() until it reaches the
N= 1. for the N=1 case, it returns N(=1) itself and all the previously built
up result of multiplied return N s gets multiplied with N=1. Thus gives the
factorial result.
static int factorial(int N) {
if(N > 1) {
return n * factorial(N - 1);
}
// Base Case N = 1
else {
return N;
}
public static long factorial(int number) {
if (number < 0) {
throw new ArithmeticException(number + " is negative");
}
long fact = 1;
for (int i = 1; i <= number; ++i) {
fact *= i;
}
return fact;
}
using recursion.
public static long factorial(int number) {
if (number < 0) {
throw new ArithmeticException(number + " is negative");
}
return number == 0 || number == 1 ? 1 : number * factorial(number - 1);
}
source
Using Java 9+, you can use this solution. This uses BigInteger, ideal for holding large numbers.
...
import java.math.BigInteger;
import java.util.stream.Stream;
...
String getFactorial(int n) {
return Stream.iterate(BigInteger.ONE, i -> i.add(BigInteger.ONE)).parallel()
.limit(n).reduce(BigInteger.ONE, BigInteger::multiply).toString();
}
USING DYNAMIC PROGRAMMING IS EFFICIENT
if you want to use it to calculate again and again (like caching)
Java code:
int fact[]=new int[n+1]; //n is the required number you want to find factorial for.
int factorial(int num)
{
if(num==0){
fact[num]=1;
return fact[num];
}
else
fact[num]=(num)*factorial(num-1);
return fact[num];
}

Categories

Resources