how many trailing zeros after factorial? - r

I am trying to do this programming task:
Write a program that will calculate the number of trailing zeros in a
factorial of a given number.
N! = 1 * 2 * 3 * ... * N
Be careful 1000! has 2568 digits.
For more info, see: http://mathworld.wolfram.com/Factorial.html
Examples:
zeros(6) = 1 ->
6! = 1 * 2 * 3 * 4 * 5 * 6 = 720 --> 1 trailing zero
zeros(12) = 2 ->
12! = 479001600 --> 2 trailing zeros
I'm confused as one of the sample tests I have is showing this: expect_equal(zeros(30), 7)
I could be misunderstanding the task, but where do the trailing 7 zeros come from when the input is 30?
with scientific notation turned on I get this:
2.6525286e+32
and with it turned off I get this:
265252859812191032282026086406022

What you are experiencing is a result of this: Why are these numbers not equal?
But in this case, calculating factorials to find the numbers of trailing zeros is not that efficient.
We can count number of 5-factors in a number (since there will be always enough 2-factors to pair with them and create 10-factors). This function gives you trailing zeros for a factorial by counting 5-factors in a given number.
tailingzeros_factorial <- function(N){
mcount = 0L
mdiv = 5L
N = as.integer(N)
while (as.integer((N/mdiv)) > 0L) {
mcount = mcount + as.integer(N/mdiv)
mdiv = as.integer(mdiv * 5L)
}
return(mcount)
}
tailingzeros_factorial(6)
#> 1
tailingzeros_factorial(25)
#> 6
tailingzeros_factorial(30)
#> 7

Related

Finding the closest pentagonal number, 𝑝𝑛 given a positive integer, S where S ≥ 1

I need to create a function in R that takes as input an integer, S ≥ 1 and returns as output the pentagonal number which is closest to S.The output of my function should be the pentagonal number 𝑝𝑛 which satisfies |𝑝𝑛−𝑠|≤|𝑝𝑚−𝑠| for all positive integers m.
However if I could get two different pentagonal numbers which happens when the integer, s is literally in the middle of them. Then it doesn't matter which one it takes (greater or lesser value) which is like when S is 17 and the pentagonal number closest to 17 is 12 and 22 so it can take either one.
Here is the following code that I have created which is used to find the pentagonal number 𝑝𝑛 for a given positive integer, n:
P_n=function(n){
x=(3*n^2-n)/2
if(n == 0){
return (0)
}else{
return(x)
}
}
After writing the code to find pn, I am now stuck with finding the closest pentagonal number for integer, s. I know that the main idea is to distinguish Pm and Pn using ceiling and floor function but I don't really know how to link it to the equation |𝑝𝑛−𝑠|≤|𝑝𝑚−𝑠|.
You can try the code below
P_n <- Vectorize(function(n) max((3 * n^2 - n) / 2, 0))
k <- floor((1 + sqrt(1 + 24 * x)) / 6)
(n <- k - 1 + which.min(abs(P_n(c(k,k+1)) - x)))
Example 1
> x <- 18
> k <- floor((1 + sqrt(1 + 24 * x)) / 6)
> (n <- k - 1 + which.min(abs(P_n(c(k,k+1)) - x)))
[1] 4
Example 2
> x <- 17
> k <- floor((1 + sqrt(1 + 24 * x)) / 6)
> (n <- k - 1 + which.min(abs(P_n(c(k,k+1)) - x)))
[1] 3
You don't need loops, just solve following problem:
For input S find minimum n such that: 3n^2-n-2S >= 0
By doing that you get your two candidates:
n <- (1 + sqrt(1 + 24 * S)) / 6
p1 <- P_n(floor(n))
p2 <- P_n(ceiling(n))
c(p1, p2)[which.min(c(S - p1, p2 - S))]
In the case when the difference is same this will prefer lower pentagonal number (because of the way which.min works in case of equal numbers).

Summation inside summation inside production in R

I have problems with the coding of a function to optimize in which there are two summations and one production, all with different indexing. I split the code into two functions for simplicity.
In the first function j goes from 0 to k:
w = function(n,k,gam){
j = 0:k
w = (1 / factorial(k)) * n * sum(choose(k, j * gam))
return(w)}
In the second function k goes from 0 to n (that is fixed to 10); instead the production goes from 1 to length(x):
f = function(gam,del){
x = mydata #vector of 500 elements
n = 10
k = 0:10
for (i in 0:10)
pdf = prod( sum( w(n, k[i], gam) * (1 / del + (n/x)^(n+1))
return(-pdf)}
When I try the function I obtain the following error:
Error in 0:k : argument of length 0
Edit: This is what I am tryig to code
where I want to maximize L(d,g) using optim and:
and n is fixed to a specific value.
Solution
Change for (i in 0:10) to for ( i in 1:11 ). Note: When I copied and ran your code I also noticed some unrelated bracket/parentheses omissions you may need to fix also.
Explanation
Your problem is that R uses a 1-based indexing system rather than a 0-based one like many other programming languages or some mathematical formulae. If you run the following code you'll get the same error, and it pinpoints the problem:
k = 0:10
for ( i in 0:10 ) {
print(0:k[i])
}
Error in 0:k[i] : argument of length 0
You get an error on the first iteration because there is no 0 element of k. Compare that to the following loop:
k = 0:10
for ( i in 1:11 ) {
print(0:k[i])
}
[1] 0
[1] 0 1
[1] 0 1 2
[1] 0 1 2 3
[1] 0 1 2 3 4
[1] 0 1 2 3 4 5
[1] 0 1 2 3 4 5 6
[1] 0 1 2 3 4 5 6 7
[1] 0 1 2 3 4 5 6 7 8
[1] 0 1 2 3 4 5 6 7 8 9
[1] 0 1 2 3 4 5 6 7 8 9 10
Update
Your comment to the answer clarifies some additional information you need:
Just to full understand everything, how do I know in a situation like
this that R is indexing the production on x and the summation on k?
The short answer is that it depends on how you nest your loops and function calls. In more detail:
When you call f(), you start a for loop over the elements of k, so R is indexing the block of code within the for loop (everything in the braces in my re-formatted version of f() below) "on" k. For every element in k, you assign prod(...) to pdf (Side note: I don't know why you're re-writing over pdf in every iteration of this loop)
sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)) produces a vector of length max(length(w(n, k[i], gam)), length(s)) (side note: Beware of recycling! -- see Section 2.2 of "An Introduction to R"); prod(sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1))) effectively indexes over the elements of that vector
w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1) produces a vector of length max(length(w(n, k[i], gam)), length(s)); sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)) effectively indexes over the elements of that vector
Etc.
What you're indexing over, explicitly or implicitly through vectorized operations, depends on which level of nested loops or function calls you're talking about. You may need some careful thinking and planning about when you want to index over what, which will tell you how you need to nest things. Put the operation whose indices should vary fastest on the innermost call. For example, in effect, prod(1:3 + sum(1:3)) will index over sum(1:3) to produce that sum first then index over 1:3 + sum(1:3) to produce the product. I.e., sum(1:3) = 1 + 2 + 3 = 6, then prod(1:3 + sum(1:3)) = (1 + 6) * (2 + 6) * (3 + 6) = 7 * 8 * 9 = 504. It's just like how parentheses work in mathematics.
Also, another side note, I wouldn't refer to global variables from within a function as you do in f() -- I've highlighted below in your code where you do that and offered an alternative that doesn't do it.
f = function(gam, del){
x = mydata # don't refer to a global variable "mydata", make it an argument
n = 10
s = n / x
k = 1:11
for (i in 1:11){
pdf = prod( sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)))
}
return(-pdf)
}
# Do this instead
# (though there are still other things to fix,
# like re-writing over "pdf" eleven times and only using the last value)
f = function(gam, del, x, n = 10) {
s = n / x
s = n / x
k = 0:10
for (i in 1:11){
pdf = prod( sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)))
}
return(-pdf)
}

Recursive approach for pow(x,n) for finding 2^(37) with less than 10 multiplications

The regular recursive approach for pow(x,n) is as follows:
pow (x,n):
= 1 ...n=0
= 0 ...x=0
= x ...n=1
= x * pow (x, n-1) ...n>0
With this approach 2^(37) will require 37 multiplications. How do I modify this to reduces the number of multiplications to less than 10? I think this could be done only if the function is not excessive.
With this approach you can compute 2^(37) with only 7 multiplications.
pow(x,n):
= 1 ... n=0
= 0 ... x=0
= x ... n=1
= pow(x,n/2) * pow (x,n/2) ... n = even
= x * pow(x,n/2) * pow(x,n.2) ... n = odd
Now lets calculate 2^(37) with this approach -
2^(37) =
= 2 * 2^(18) * 2^(18)
= 2^(9) * 2^(9)
= 2 * 2^(4) * 2^(4)
= 2^(2) * 2^(2)
= 2 * 2
This function is not excessive and hence it reuses the values once calculated. Thus only 7 multiplications are required to calculate 2^(37).
You can calculate the power of a number in logN time instead of linear time.
int cnt = 0;
// calculate a^b
int pow(int a, int b){
if(b==0) return 1;
if(b%2==0){
int v = pow(a, b/2);
cnt += 1;
return v*v;
}else{
int v = pow(a, b/2);
cnt += 2;
return v*v*a;
}
}
Number of multiplications will be 9 for the above code as verified by this program.
Doing it slightly differently than invin did, I come up with 8 multiplications. Here's a Ruby implementation. Be aware that Ruby methods return the result of the last expression evaluated. With that understanding, it reads pretty much like pseudo-code except you can actually run it:
$count = 0
def pow(a, b)
if b > 0
$count += 1 # note only one multiplication in both of the following cases
if b.even?
x = pow(a, b/2)
x * x
else
a * pow(a, b-1)
end
else # no multiplication for the base case
1
end
end
p pow(2, 37) # 137438953472
p $count # 8
Note that the sequence of powers with which the method gets invoked is
37 -> 36 -> 18 -> 9 -> 8 -> 4 -> 2 -> 1 -> 0
and that each arrow represents one multiplication. Calculating the zeroth power always yields 1, with no multiplication, and there are 8 arrows.
Since xn = (xn/2)2 = (x2)n/2 for even values of n, we can derive this subtly different implementation:
$count = 0
def pow(a, b)
if b > 1
if b.even?
$count += 1
pow(a * a, b/2)
else
$count += 2
a * pow(a * a, b/2)
end
elsif b > 0
a
else
1
end
end
p pow(2, 37) # 137438953472
p $count # 7
This version includes all of the base cases in the original question, it's easy to run and confirm that it calculates 2^37 in 7 multiplications, and doesn't require any allocation of local variables. For production use you would, of course, comment out or remove the references to $count.

Separate a number into fixed part

What is the algorithm to find the number way to separate number M to p part and no two part equal.
Example:
M = 5, P = 2
they are (1,4) (2,3). If P = 3 then no partition availabe, i.e
not (1,2,2) because there two 2 in partition.
In the expanded product
(1+x)(1+x2)(1+x3)...(1+xn)
find the coefficient of x^n. This gives the number of any possibility to represent n as sum of different numbers, i.e., a variable number of terms.
You want the number of possibilites to have
n = i1+i2+...+iP with i1 < i2 < ... < iP
which can be realized by setting
i1=j1, i2=i1+j2=j1+j2, ...
iP=iP-1+jP=j1+j2+...+jP with all jk > 0
so that the original task is the same as counting all the ways that one can solve
n = P * j1+(P-1) * j2+...+1 * jP with all jk > 0, but unrelated among each other.
The corresponding generator function is the product of the geometric series of the powers of x, omitting the constant term,
(x+x2+x3+...) * (x2+x4+x6+...) * (x3+x6+x9+...) * ... * (xP+x2*P+x3*P+...)
= xP*(P+1)/2 * (1+x+x2+...) * (1+x2+x4+...) * (1+x3+x6+...) * ... * (1+xP+x2*P+...)
Clearly, one needs n >= P*(P+1)/2 to get any solution at all. For P=3 that bound is n >= 6, so that n=5 has indeed no solutions in that case.
Algorithm
count = new double[N]
for k=0..N-1 do count[k] = 1
for j=2..P do
for k=j..N-1 do
count[k] += count[k-j]
Then count[k] contains the number of combinations for n=P*(P+1)/2+k.

Calculating Total Number of Times of Loops

I'm trying to calculate the total number of times the innermost statement is executed.
count = 0;
for i = 1 to n
for j = 1 to n - i
count = count + 1
I figured that the most the loop can execute is O(n*n-i) = O(n^2). I wanted to prove this by using double summation but I'm getting lost since the I'm having trouble starting the equation since j = 1 is thrown into there.
Can someone help me explain this to me?
Thanks
For each i, the inner loop executes n - i times (n is constant). Therefore (since i ranges from 1 to n), to determine the total number of times the innermost statement is executed, we must evaluate the sum
(n - 1) + (n - 2) + (n - 3) + ... + (n - n)
By rearranging the terms (grouping all the ns that appear first), we can see that this is equal to
n*n - (1 + 2 + 3 + ... + n) = n*n - n(n+1)/2 = n*(n-1)/2 = n*n/2 - n/2
Here's a simple implementation in Python to verify this:
def f(n):
count = 0;
for i in range(1, n + 1):
for _ in range(1, n - i + 1):
count = count + 1
return count
for n in range(1,11):
print n, '\t', f(n), '\t', n*n/2 - n/2
Output:
1 0 0
2 1 1
3 3 3
4 6 6
5 10 10
6 15 15
7 21 21
8 28 28
9 36 36
10 45 45
The first column is n, the second is the number of times that inner statement is executed, and the third is n*n/2 - n/2.

Resources