So I am not very good at it yet at all (understatement). I am trying to solve problems in the Euler project, and I am already stuck on 2.
Each new term in the Fibonacci sequence is generated by adding the previous 2 terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
Here is my code which I have repeatedly tried to fix:
(I think there is something wrong with the for loop logic.)
public class tesy {
public static void main(String args[]) {
int fib = 0;
int tot = 0;
int total = 0;
for (fib = 0; tot < 4000000; fib++) {
tot = fib + (fib + 1);
if (tot % 2 == 0) {
total = tot + total;
}
}
System.out.println(total);
}
}
Your logic is erroneous in couple of ways,
tot = fib + (fib + 1); /** This will always be `(2*fib + 1)` and `fib` is getting
incremented by 1 each time. You have no reference to the previous two terms of the
sequence. **/
Try the below logic instead.
class Fibonacci
{
public static void main (String[] args)
{
int fiboFirst = 1;
int fiboSecond =2;
int fib = 0;
int sum = 0;
while(fiboSecond < 4000000)
{
// This will calculate the current term of the sequence
fib = fiboFirst + fiboSecond;
// Below two lines will update fib[i] and fib[i - 1] terms
// for the next loop iteration.
fiboFirst = fiboSecond; // fib[i]
fiboSecond = fib; // fib[i -1]
if (fib % 2 == 0)
{
sum = sum + fib;
}
}
System.out.println(sum+2);
}
}
Explanation
Here fiboFirst is equivalent to F[n] and fiboSecond is equivalent
to F[n - 1] in the Fibonacci sequence definition. In each iteration,
those two values should be replaced, in order to be used in the next
iteration. That is why I have these two lines,
fiboFirst = fiboSecond; // fib[i]
fiboSecond = fib; // fib[i -1]
HERE is the execution of the above program
You don't seem to be following the actual equation used to generate a fibonacci sequence, therefore there is no (obvious) way of fixing your code.
int fibA = 1, fibB = 2, total = 0;
while(fibB <= 4000000) {
// Add to the total, set fibA to fibB and get the next value in the sequence.
if(fibB % 2 == 0) total += fibB;
int temp = fibA;
fibA = fibB;
fibB = fibB + temp;
}
The above code should find the sum of all values less than or equal to 4000000
Here is a solution that uses BigInteger. Please verify the results.
public class Fibonacci{
public static void main(String[] args) {
BigInteger r = fibonacciEvenSum();
System.out.println(r);
}
public static BigInteger fibonacciEvenSum(){
int f = 1;
int s = 2;
int mn4 = 4000000;
BigInteger sum = BigInteger.valueOf(0);
while(s <= mn4){
if(s % 2 == 0){
sum = sum.add(BigInteger.valueOf(s));
}
f = f + s;
s = s + f;
}
return sum;
}
}
Before writing a program like this, you should first think of what's underlying this program. You should first understand how to generate a Fibonacci series before graduating on to doing something with the series. I'll give you my solution so that you can understand.
class euler2 {
public static void main(String[] args) {
int a = 0, b = 1; /* the first elements of Fibonacci series are generally
thought to be 0 and 1. Therefore the series is 0, 1, 1, 2, 3... .
I've initialized first and second elements such */
double sum = 0; // The initial sum is zero of course.
while (b < 4000000) /* since b is the second term, it will be our control variable.
This wouldn't let us consider values above 4M. */
{
int ob = b; // to swap the values of a and b.
b = a + b; // generating next in the series.
a = ob; // a is now the older value of b since b is now a + b.
if (b % 2 == 0) // if b is even
sum += b; // we add it to the sum
}
System.out.println(sum); // and now we just print the sum
}
}
Hope this helped!
Related
I am having a hard time figuring out the solution to this problem. I need to write an iterative (can't use recursion) solution to a problem in which a user inputs a number via scanner (for example, 10) and it prints 2 "previous" Fib numbers.
For the input "10" example, it would be:
5
8
As they're the "biggest" two Fib numbers prior to 10.
If the input is 13, it would print:
8
13
As 13 is a Fib number itself, it prints only 1 number prior, and then itself.
Now I know how to iteratevely find the "n-th" Fib number but I can't get my mind around a solution to run til a given number (rather than the n-th Fib number) and somehow print only the last 2 before it (or, if the given number is a Fib number by itself, count that as one too).
Now I'm aware of the formula that uses the perfect square - but unfortunately, can't use that...
Edit as it made some people confused:
I do not ask for a code, nor do I want anyone to solve this for me. I just genuinely want to understand how to approach such questions.
Edit #2:
Here's a code I wrote:
int a = 0;
int b = 1;
while (a < num) {
int temp = a;
a = a + b;
b = temp;
}
System.out.println(b);
System.out.println(a);
The problem I'm having is that if the num input is indeed a Fib num - it will work as intended, otherwise, it prints 1 prior Fib num and the next one, so for input "10" it prints 8 and 13.
Explanation
You said that you already have a method that computes the n-th Fibonacci number iterative. Since Fibonacci numbers are usually defined based on the last two Fibonacci elements, you should also already have them at hand, see the definition from Wikipedia:
The only thing you need to do is to run your iterative method until you reach the input. And then output the current memorized values for F_(n - 1) and F_(n - 2) (or F_n if equal to input).
Example
Suppose you have a Fibonacci method like (which I grabbed from the first google result)
public static long fib(int n) {
if (n <= 2) {
return (n > 0) ? 1 : 0;
}
long fib1 = 0;
long fib2 = 1;
for (int i = 1; i < n; i++) {
final long newFib = fib1 + fib2;
fib1 = fib2;
fib2 = newFib;
}
return fib2;
}
You need to modify it to accept the input and return both last Fibonacci numbers fib1 and fib2. Replace the loop to n by an infinite loop from which you break once exceeding input:
public static long[] fib(long input) {
// Special cases
if (input == 1) {
return new long[] { 1l, 1l };
}
if (input == 0) {
return new long[] { 0l };
}
if (input < 0) {
return null;
}
// Seed values
long fib1 = 0;
long fib2 = 1;
// Repeat until return
while (true) {
long newFib = fib1 + fib2;
// Reached the end
if (newFib >= input) {
// Push 'newFib' to the results
if (newFib == input) {
fib1 = fib2;
fib2 = newFib;
}
return new long[] { fib1, fib2 };
}
// Prepare next round
fib1 = fib2;
fib2 = newFib;
}
}
The method now returns at [0] the second to nearest Fibonacci and at [1] the nearest Fibonacci number to input.
You can easily adjust your own method likewise using this example.
Usage:
public static void main(String[] args) {
long[] results = fib(20L);
// Prints "8, 13"
System.out.println(results[0] + ", " + results[1]);
results = fib(21L);
// Prints "13, 21"
System.out.println(results[0] + ", " + results[1]);
}
Another example
A different view to the same problem can be obtained by using some kind of nextFib method. Then you can repeatedly pick until exceeding input. Therefore, we build some class like
public class FibonacciCalculator {
private long fib1 = 0;
private long fib2 = 1;
private int n = 0;
public long nextFib() {
// Special cases
if (n <= 2) {
long result = (n > 0) ? 1 : 0;
// Increase the index
n++;
return result;
}
// Compute current and push
long newFib = fib1 + fib2;
fib1 = fib2;
fib2 = newFib;
return newFib;
}
}
And then we just call it until we exceed input, always memorizing the last two values:
public static long[] fib(long input) {
FibonacciCalculator calc = new FibonacciCalculator();
long lastFib = 0L;
long secondToLastFib = 0L;
while (true) {
long curFib = calc.nextFib();
if (curFib > input) {
return new long[] { secondToLastFib, lastFib };
} else if (curFib == input) {
return new long[] { lastFib, curFib };
}
secondToLastFib = lastFib;
lastFib = curFib;
}
}
I have this problem in front of me and I can't figure out how to solve it.
It's about the series 0,1,1,2,5,29,866... (Every number besides the first two is the sum of the squares of the previous two numbers (2^2+5^2=29)).
In the first part I had to write an algorithm (Not a native speaker so I don't really know the terminology) that would receive a place in the series and return it's value (6 returned 29)
This is how I wrote it:
public static int mod(int n)
{
if (n==1)
return 0;
if (n==2)
return 1;
else
return (int)(Math.pow(mod(n-1), 2))+(int)(Math.pow(mod(n-2), 2));
}
However, now I need that the algorithm will receive a number and return the total sum up to it in the series (6- 29+5+2+1+1+0=38)
I have no idea how to do this, I am trying but I am really unable to understand recursion so far, even if I wrote something right, how can I check it to be sure? And how generally to reach the right algorithm?
Using any extra parameters is forbidden.
Thanks in advance!
We want:
mod(1) = 0
mod(2) = 0+1
mod(3) = 0+1+1
mod(4) = 0+1+1+2
mod(5) = 0+1+1+2+5
mod(6) = 0+1+1+2+5+29
and we know that each term is defined as something like:
2^2+5^2=29
So to work out mod(7) we need to add the next term in the sequence x to mod(6).
Now we can work out the term using mod:
x = term(5)^2 + term(6)^2
term(5) = mod(5) - mod(4)
term(6) = mod(6) - mod(5)
x = (mod(5)-mod(4))^2 + (mod(6)-mod(5))^2
So we can work out mod(7) by evaluating mod(4),mod(5),mod(6) and combining the results.
Of course, this is going to be incredibly inefficient unless you memoize the function!
Example Python code:
def f(n):
if n<=0:
return 0
if n==1:
return 1
a=f(n-1)
b=f(n-2)
c=f(n-3)
return a+(a-b)**2+(b-c)**2
for n in range(10):
print f(n)
prints:
0
1
2
4
9
38
904
751701
563697636866
317754178345850590849300
How about this? :)
class Main {
public static void main(String[] args) {
final int N = 6; // Your number here.
System.out.println(result(N));
}
private static long result(final int n) {
if (n == 0) {
return 0;
} else {
return element(n) + result(n - 1);
}
}
private static long element(final int n) {
if (n == 1) {
return 0L;
} else if (n == 2) {
return 1L;
} else {
return sqr(element(n - 2)) + sqr(element(n - 1));
}
}
private static long sqr(final long x) {
return x * x;
}
}
Here is the idea that separate function (element) is responsible for finding n-th element in the sequence, and result is responsible for summing them up. Most probably there is a more efficient solution though. However, there is only one parameter.
I can think of a way of doing this with the constraints in your comments but it's a total hack. You need one method to do two things: find the current value and add previous values. One option is to use negative numbers to flag one of those function:
int f(int n) {
if (n > 0)
return f(-n) + f(n-1);
else if (n > -2)
return 0;
else if (n == -2)
return 1;
else
return f(n+1)*f(n+1)+f(n+2)*f(n+2);
}
The first 8 numbers output (before overflow) are:
0
1
2
4
9
38
904
751701
I don't recommend this solution but it does meet your constraints of being a single recursive method with a single argument.
Here is my proposal.
We know that:
f(n) = 0; n < 2
f(n) = 1; 2 >= n <= 3
f(n) = f(n-1)^2 + f(n-2)^2; n>3
So:
f(0)= 0
f(1)= 0
f(2)= f(1) + f(0) = 1
f(3)= f(2) + f(1) = 1
f(4)= f(3) + f(2) = 2
f(5)= f(4) + f(3) = 5
and so on
According with this behaivor we must implement a recursive function to return:
Total = sum f(n); n= 0:k; where k>0
I read you can use a static method but not use more than one parameter into the function. So, i used a static variable with the static method, just for control the execution of loop:
class Dummy
{
public static void main (String[] args) throws InterruptedException {
int n=10;
for(int i=1; i<=n; i++)
{
System.out.println("--------------------------");
System.out.println("Total for n:" + i +" = " + Dummy.f(i));
}
}
private static int counter = 0;
public static long f(int n)
{
counter++;
if(counter == 1)
{
long total = 0;
while(n>=0)
{
total += f(n);
n--;
}
counter--;
return total;
}
long result = 0;
long n1=0,n2=0;
if(n >= 2 && n <=3)
result++; //Increase 1
else if(n>3)
{
n1 = f(n-1);
n2 = f(n-2);
result = n1*n1 + n2*n2;
}
counter--;
return result;
}
}
the output:
--------------------------
Total for n:1 = 0
--------------------------
Total for n:2 = 1
--------------------------
Total for n:3 = 2
--------------------------
Total for n:4 = 4
--------------------------
Total for n:5 = 9
--------------------------
Total for n:6 = 38
--------------------------
Total for n:7 = 904
--------------------------
Total for n:8 = 751701
--------------------------
Total for n:9 = 563697636866
--------------------------
Total for n:10 = 9011676203564263700
I hope it helps you.
UPDATE: Here is another version without a static method and has the same output:
class Dummy
{
public static void main (String[] args) throws InterruptedException {
Dummy app = new Dummy();
int n=10;
for(int i=1; i<=n; i++)
{
System.out.println("--------------------------");
System.out.println("Total for n:" + i +" = " + app.mod(i));
}
}
private static int counter = 0;
public long mod(int n)
{
Dummy.counter++;
if(counter == 1)
{
long total = 0;
while(n>=0)
{
total += mod(n);
n--;
}
Dummy.counter--;
return total;
}
long result = 0;
long n1=0,n2=0;
if(n >= 2 && n <=3)
result++; //Increase 1
else if(n>3)
{
n1 = mod(n-1);
n2 = mod(n-2);
result = n1*n1 + n2*n2;
}
Dummy.counter--;
return result;
}
}
Non-recursive|Memoized
You should not use recursion since it will not be good in performance.
Use memoization instead.
def FibonacciModified(n):
fib = [0]*n
fib[0],fib[1]=0,1
for idx in range(2,n):
fib[idx] = fib[idx-1]**2 + fib[idx-2]**2
return fib
if __name__ == '__main__':
fib = FibonacciModified(8)
for x in fib:
print x
Output:
0
1
1
2
5
29
866
750797
The above will calculate every number in the series once[not more than that].
While in recursion an element in the series will be calculated multiple times irrespective of the fact that the number was calculated before.
http://www.geeksforgeeks.org/program-for-nth-fibonacci-number/
The motto is to find the sum of all the multiples of 3 or 5 below N.
Here's my code:
public class Solution
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int t = in.nextInt();
long n=0;
long sum=0;
for(int a0 = 0; a0 < t; a0++)
{
n = in.nextInt();
sum=0;
for(long i=1;i<n;i++)
{
if(i%3==0 || i%5==0)
sum = sum + i;
}
System.out.println(sum);
}
}
}
It's taking more than 1sec to execute for some of the test cases. Can anyone please help me out so as to reduce the time complexity?
We can find the sum of all multiples of number d that are below N as a sum of an arithmetic progression (their sum is equal to d + 2*d + 3*d + ...).
long multiplesSum(long N, long d) {
long highestMultiple = (N-1) / d * d;
long numberOfMultiples = highestMultiple / d;
return (d + highestMultiple) * numberOfMultiples / 2;
}
Then the result will be equal to:
long resultSum(long N) {
return multiplesSum(N, 3) + multiplesSum(N, 5) - multiplesSum(N, 3*5);
}
We need to subtract multiplesSum(N, 15) because there are numbers that are multiples of both 3 and 5 and we added them twice.
Complexity: O(1)
You can't reduce the time complexity in this case as there are still O(N) of each set of numbers. However you can reduce the constant multiplier by using integer division:
static int findMultiples(int N, int s)
{
int c = N / s, sum = 0;
for (int i = 0, k = s; i < c; i++, k += s)
sum += k;
return sum;
}
This way you only loop through the multiples themselves instead of the whole range [0, N].
Note that you will need to do findMultiples(N, 3) + findMultiples(N, 5) - findMultiples(N, 15), to remove the duplicated multiples of both 3 and 5. The number of loops is therefore N/3 + N/5 + N/15 = 0.6N instead of N.
EDIT: in general the solution for an arbitrary number of divisors is sum(findMultiples(N,divisor_i) - findMultiples(N,LCM(all_divisors)); however it is only worth doing this if sum(1/divisor_i) + 1/LCM(all_divisors) < 1, otherwise there will be more loops. Luckily this will never be true for 2 divisors.
The sum of all numbers from 1 to (including) N is known to be N(N+1)/2 (no need for iteration).
So, the sum of all multiples of K, from K to KM is K times the above formula, giving KM(M+1)/2.
Combine this with #meowgoesthedog's findMultiples(N, 3) + findMultiples(N, 5) - findMultiples(N, 15) idea, and you have a constant-time solution.
A solution for your problem.Fastest method for solving your problem.
import java.util.*;
class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
while(t!=0)
{
long a=in.nextLong();
long q=a-1;
long aa=q/3;
long bb=q/5;
long cc=q/15;
long aaa=((aa*(aa+1))/2)*3;
long bbb=((bb*(bb+1))/2)*5;
long ccc=((cc*(cc+1))/2)*15;
System.out.println(aaa+bbb-ccc);
t-=1;}
}
}
I am stuck on the coin denomination problem.
I am trying to find the lowest number of coins used to make up $5.70 (or 570 cents). For example, if the coin array is {100,5,2,5,1} (100 x 10c coins, 5 x 20c, 2 x 50c, 5 x $1, and 1 x $2 coin), then the result should be {0,1,1,3,1}
At the moment the coin array will consist of the same denominations ( $2, $1, 50c, 20c, 10c)
public static int[] makeChange(int change, int[] coins) {
// while you have coins of that denomination left and the total
// remaining amount exceeds that denomination, take a coin of that
// denomination (i.e add it to your result array, subtract it from the
// number of available coins, and update the total remainder). –
for(int i= 0; i< coins.length; i++){
while (coins[i] > 0) {
if (coins[i] > 0 & change - 200 >= 0) {
coins[4] = coins[4]--;
change = change - 200;
} else
if (coins[i] > 0 & change - 100 >= 0) {
coins[3] = coins[3]--;
change = change - 100;
} else
if (coins[i] > 0 & change - 50 >= 0) {
coins[2] = coins[2]--;
change = change - 50;
} else
if (coins[i] > 0 & change - 20 >= 0) {
coins[1] = coins[1]--;
change = change - 20;
} else
if (coins[i] > 0 & change - 10 >= 0) {
coins[0] = coins[0]--;
change = change - 10;
}
}
}
return coins;
}
I am stuck on how to deduct the values from coins array and return it.
EDIT: New code
The brute force solution is to try up to the available number of coins of the highest denomination (stopping when you run out or the amount would become negative) and for each of these recurse on solving the remaining amount with a shorter list that excludes that denomination, and pick the minimum of these. If the base case is 1c the problem can always be solved, and the base case is return n otherwise it is n/d0 (d0 representing the lowest denomination), but care must be taken to return a large value when not evenly divisible so the optimization can pick a different branch. Memoization is possible, and parameterized by the remaining amount and the next denomination to try. So the memo table size would be is O(n*d), where n is the starting amount and d is the number of denominations.
So the problem can be solved in pseudo-polynomial time.
The wikipedia link is sparse on details on how to decide if a greedy algorithm such as yours will work. A better reference is linked in this CS StackExchange question. Essentially, if the coin system is canonical, a greedy algorithm will provide an optimal solution. So, is [1, 2, 5, 10, 20] canonical? (using 10s of cents for units, so that the sequence starts in 1)
According to this article, a 5-coin system is non-canonical if and only if it satisfies exactly one of the following conditions:
[1, c2, c3] is non-canonical (false for [1, 2, 5])
it cannot be written as [1, 2, c3, c3+1, 2*c3] (true for [1, 2, 5, 10, 20])
the greedyAnswerSize((k+1) * c4) > k+1 with k*c4 < c5 < (k+1) * c4; in this case, this would require a k*10 < 20 < (k+1)*10; there is no integer k in that range, so this is false for [1, 2, 5, 10, 20].
Therefore, since the greedy algorithm will not provide optimal answers (and even if it did, I doubt that it would work with limited coins), you should try dynamic programming or some enlightened backtracking:
import java.util.HashSet;
import java.util.PriorityQueue;
public class Main {
public static class Answer implements Comparable<Answer> {
public static final int coins[] = {1, 2, 5, 10, 20};
private int availableCoins[] = new int[coins.length];
private int totalAvailable;
private int totalRemaining;
private int coinsUsed;
public Answer(int availableCoins[], int totalRemaining) {
for (int i=0; i<coins.length; i++) {
this.availableCoins[i] = availableCoins[i];
totalAvailable += coins[i] * availableCoins[i];
}
this.totalRemaining = totalRemaining;
}
public boolean hasCoin(int coinIndex) {
return availableCoins[coinIndex] > 0;
}
public boolean isPossibleBest(Answer oldBest) {
boolean r = totalRemaining >= 0
&& totalAvailable >= totalRemaining
&& (oldBest == null || oldBest.coinsUsed > coinsUsed);
return r;
}
public boolean isAnswer() {
return totalRemaining == 0;
}
public Answer useCoin(int coinIndex) {
Answer a = new Answer(availableCoins, totalRemaining - coins[coinIndex]);
a.availableCoins[coinIndex]--;
a.totalAvailable = totalAvailable - coins[coinIndex];
a.coinsUsed = coinsUsed+1;
return a;
}
public int getCoinsUsed() {
return coinsUsed;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder("{");
for (int c : availableCoins) sb.append(c + ",");
sb.setCharAt(sb.length()-1, '}');
return sb.toString();
}
// try to be greedy first
#Override
public int compareTo(Answer a) {
int r = totalRemaining - a.totalRemaining;
return (r==0) ? coinsUsed - a.coinsUsed : r;
}
}
// returns an minimal set of coins to solve
public static int makeChange(int change, int[] availableCoins) {
PriorityQueue<Answer> queue = new PriorityQueue<Answer>();
queue.add(new Answer(availableCoins, change));
HashSet<String> known = new HashSet<String>();
Answer best = null;
int expansions = 0;
while ( ! queue.isEmpty()) {
Answer current = queue.remove();
expansions ++;
String s = current.toString();
if (current.isPossibleBest(best) && ! known.contains(s)) {
known.add(s);
if (current.isAnswer()) {
best = current;
} else {
for (int i=0; i<Answer.coins.length; i++) {
if (current.hasCoin(i)) {
queue.add(current.useCoin(i));
}
}
}
}
}
// debug
System.out.println("After " + expansions + " expansions");
return (best != null) ? best.getCoinsUsed() : -1;
}
public static void main(String[] args) {
for (int i=0; i<100; i++) {
System.out.println("Solving for " + i + ":"
+ makeChange(i, new int[]{100,5,2,5,1}));
}
}
}
You are in wrong direction. This program will not give you an optimal solution. To get optimal solution go with dynamic algorithms implemented and discussed here. Please visit these few links:
link 1
link 2
link 3
I'm trying to count trailing zeros of numbers that are resulted from factorials (meaning that the numbers get quite large). Following code takes a number, compute the factorial of the number, and count the trailing zeros. However, when the number is about as large as 25!, numZeros don't work.
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
double fact;
int answer;
try {
int number = Integer.parseInt(br.readLine());
fact = factorial(number);
answer = numZeros(fact);
}
catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static double factorial (int num) {
double total = 1;
for (int i = 1; i <= num; i++) {
total *= i;
}
return total;
}
public static int numZeros (double num) {
int count = 0;
int last = 0;
while (last == 0) {
last = (int) (num % 10);
num = num / 10;
count++;
}
return count-1;
}
I am not worrying about the efficiency of this code, and I know that there are multiple ways to make the efficiency of this code BETTER. What I'm trying to figure out is why the counting trailing zeros of numbers that are greater than 25! is not working.
Any ideas?
Your task is not to compute the factorial but the number of zeroes. A good solution uses the formula from http://en.wikipedia.org/wiki/Trailing_zeros (which you can try to prove)
def zeroes(n):
i = 1
result = 0
while n >= i:
i *= 5
result += n/i # (taking floor, just like Python or Java does)
return result
Hope you can translate this to Java. This simply computes [n / 5] + [n / 25] + [n / 125] + [n / 625] + ... and stops when the divisor gets larger than n.
DON'T use BigIntegers. This is a bozosort. Such solutions require seconds of time for large numbers.
You only really need to know how many 2s and 5s there are in the product. If you're counting trailing zeroes, then you're actually counting "How many times does ten divide this number?". if you represent n! as q*(2^a)*(5^b) where q is not divisible by 2 or 5. Then just taking the minimum of a and b in the second expression will give you how many times 10 divides the number. Actually doing the multiplication is overkill.
Edit: Counting the twos is also overkill, so you only really need the fives.
And for some python, I think this should work:
def countFives(n):
fives = 0
m = 5
while m <= n:
fives = fives + (n/m)
m = m*5
return fives
The double type has limited precision, so if the numbers you are working with get too big the double will be only an approximation. To work around this you can use something like BigInteger to make it work for arbitrarily large integers.
You can use a DecimalFormat to format big numbers. If you format your number this way you get the number in scientific notation then every number will be like 1.4567E7 this will make your work much easier. Because the number after the E - the number of characters behind the . are the number of trailing zeros I think.
I don't know if this is the exact pattern needed. You can see how to form the patterns here
DecimalFormat formater = new DecimalFormat("0.###E0");
My 2 cents: avoid to work with double since they are error-prone. A better datatype in this case is BigInteger, and here there is a small method that will help you:
public class CountTrailingZeroes {
public int countTrailingZeroes(double number) {
return countTrailingZeroes(String.format("%.0f", number));
}
public int countTrailingZeroes(String number) {
int c = 0;
int i = number.length() - 1;
while (number.charAt(i) == '0') {
i--;
c++;
}
return c;
}
#Test
public void $128() {
assertEquals(0, countTrailingZeroes("128"));
}
#Test
public void $120() {
assertEquals(1, countTrailingZeroes("120"));
}
#Test
public void $1200() {
assertEquals(2, countTrailingZeroes("1200"));
}
#Test
public void $12000() {
assertEquals(3, countTrailingZeroes("12000"));
}
#Test
public void $120000() {
assertEquals(4, countTrailingZeroes("120000"));
}
#Test
public void $102350000() {
assertEquals(4, countTrailingZeroes("102350000"));
}
#Test
public void $1023500000() {
assertEquals(5, countTrailingZeroes(1023500000.0));
}
}
This is how I made it, but with bigger > 25 factorial the long capacity is not enough and should be used the class Biginteger, with witch I am not familiar yet:)
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.print("Please enter a number : ");
long number = in.nextLong();
long numFactorial = 1;
for(long i = 1; i <= number; i++) {
numFactorial *= i;
}
long result = 0;
int divider = 5;
for( divider =5; (numFactorial % divider) == 0; divider*=5) {
result += 1;
}
System.out.println("Factorial of n is: " + numFactorial);
System.out.println("The number contains " + result + " zeroes at its end.");
in.close();
}
}
The best with logarithmic time complexity is the following:
public int trailingZeroes(int n) {
if (n < 0)
return -1;
int count = 0;
for (long i = 5; n / i >= 1; i *= 5) {
count += n / i;
}
return count;
}
shamelessly copied from http://www.programcreek.com/2014/04/leetcode-factorial-trailing-zeroes-java/
I had the same issue to solve in Javascript, and I solved it like:
var number = 1000010000;
var str = (number + '').split(''); //convert to string
var i = str.length - 1; // start from the right side of the array
var count = 0; //var where to leave result
for (;i>0 && str[i] === '0';i--){
count++;
}
console.log(count) // console shows 4
This solution gives you the number of trailing zeros.
var number = 1000010000;
var str = (number + '').split(''); //convert to string
var i = str.length - 1; // start from the right side of the array
var count = 0; //var where to leave result
for (;i>0 && str[i] === '0';i--){
count++;
}
console.log(count)
Java's doubles max out at a bit over 9 * 10 ^ 18 where as 25! is 1.5 * 10 ^ 25. If you want to be able to have factorials that high you might want to use BigInteger (similar to BigDecimal but doesn't do decimals).
I wrote this up real quick, I think it solves your problem accurately. I used the BigInteger class to avoid that cast from double to integer, which could be causing you problems. I tested it on several large numbers over 25, such as 101, which accurately returned 24 zeros.
The idea behind the method is that if you take 25! then the first calculation is 25 * 24 = 600, so you can knock two zeros off immediately and then do 6 * 23 = 138. So it calculates the factorial removing zeros as it goes.
public static int count(int number) {
final BigInteger zero = new BigInteger("0");
final BigInteger ten = new BigInteger("10");
int zeroCount = 0;
BigInteger mult = new BigInteger("1");
while (number > 0) {
mult = mult.multiply(new BigInteger(Integer.toString(number)));
while (mult.mod(ten).compareTo(zero) == 0){
mult = mult.divide(ten);
zeroCount += 1;
}
number -= 1;
}
return zeroCount;
}
Since you said you don't care about run time at all (not that my first was particularly efficient, just slightly more so) this one just does the factorial and then counts the zeros, so it's cenceptually simpler:
public static BigInteger factorial(int number) {
BigInteger ans = new BigInteger("1");
while (number > 0) {
ans = ans.multiply(new BigInteger(Integer.toString(number)));
number -= 1;
}
return ans;
}
public static int countZeros(int number) {
final BigInteger zero = new BigInteger("0");
final BigInteger ten = new BigInteger("10");
BigInteger fact = factorial(number);
int zeroCount = 0;
while (fact.mod(ten).compareTo(zero) == 0){
fact = fact.divide(ten);
zeroCount += 1;
}
}