Count digits in a factorial using Kamenetsky’s Formula
Given an integer n (can be very large), find the number of digits that appear in its factorial, where factorial is defined as, factorial(n) = 1*2*3*4……..*n and factorial(0) = 1
Examples:
Input : n = 1
Output : 1
1! = 1, hence number of digits is 1
Input : 5
Output : 3
5! = 120, i.e., 3 digits
Input : 10
Output : 7
10! = 3628800, i.e., 7 digits
Input : 50000000
Output : 363233781
Input : 1000000000
Output : 8565705523
We’ve already discussed the solution for small values of n in the Count digits in a factorial | Set 1. However that solution would not be able to handle cases where n >10^6
So, can we improve our solution?
Yes! we can.
We can use Kamenetsky’s formula to find our answer!
It approximates the number of digits in a factorial by :
f(x) = log10(((n/e)^n) * sqrt(2*pi*n))
Thus, we can pretty easily use the property of logarithms to,
f(x) = n* log10((n/e)) + log10(2*pi*n)/2
And that’s it!
Our solution can handle very large inputs that can be accommodated in a 32-bit integer,
and even beyond that!
Below is the implementation of the above idea :
C++
#include <bits/stdc++.h>
using namespace std;
long long findDigits( int n)
{
if (n < 0)
return 0;
if (n <= 1)
return 1;
double x = ((n * log10 (n / M_E) +
log10 (2 * M_PI * n) /
2.0));
return floor (x) + 1;
}
int main()
{
cout << findDigits(1) << endl;
cout << findDigits(50000000) << endl;
cout << findDigits(1000000000) << endl;
cout << findDigits(120) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static double M_E = 2.71828182845904523536 ;
public static double M_PI = 3.141592654 ;
static long findDigits( int n)
{
if (n < 0 )
return 0 ;
if (n <= 1 )
return 1 ;
double x = (n * Math.log10(n / M_E) +
Math.log10( 2 * M_PI * n) /
2.0 );
return ( long )Math.floor(x) + 1 ;
}
public static void main(String[] args)
{
System.out.println(findDigits( 1 ));
System.out.println(findDigits( 50000000 ));
System.out.println(findDigits( 1000000000 ));
System.out.println(findDigits( 120 ));
}
}
|
Python3
import math
def findDigits(n):
if (n < 0 ):
return 0 ;
if (n < = 1 ):
return 1 ;
x = ((n * math.log10(n / math.e) +
math.log10( 2 * math.pi * n) / 2.0 ));
return math.floor(x) + 1 ;
print (findDigits( 1 ));
print (findDigits( 50000000 ));
print (findDigits( 1000000000 ));
print (findDigits( 120 ));
|
C#
using System;
class GFG {
public static double M_E = 2.71828182845904523536;
public static double M_PI = 3.141592654;
static long findDigits( int n)
{
if (n < 0)
return 0;
if (n <= 1)
return 1;
double x = (n * Math.Log10(n / M_E) +
Math.Log10(2 * M_PI * n) /
2.0);
return ( long )Math.Floor(x) + 1;
}
public static void Main()
{
Console.WriteLine(findDigits(1));
Console.WriteLine(findDigits(50000000));
Console.WriteLine(findDigits(1000000000));
Console.Write(findDigits(120));
}
}
|
PHP
<?php
function findDigits( $n )
{
if ( $n < 0)
return 0;
if ( $n <= 1)
return 1;
$x = (( $n * log10( $n / M_E) +
log10(2 * M_PI * $n ) /
2.0));
return floor ( $x ) + 1;
}
echo findDigits(1). "\n" ;
echo findDigits(50000000). "\n" ;
echo findDigits(1000000000). "\n" ;
echo findDigits(120) ;
?>
|
Javascript
<script>
function findDigits(n)
{
if (n < 0)
return 0;
if (n <= 1)
return 1;
let x = ((n * Math.log10(n / Math.E) +
Math.log10(2 * Math.PI * n) /
2.0));
return Math.floor(x) + 1;
}
document.write(findDigits(1) + "<br>" );
document.write(findDigits(50000000) + "<br>" );
document.write(findDigits(1000000000) + "<br>" );
document.write(findDigits(120) + "<br>" );
</script>
|
Output
1
363233781
8565705523
199
Time complexity: O(logn)
Auxiliary space: O(1)
Method: First finding the factorial of a number using factorial function then using while loop finding the number of digits present in the factorial number.
C++
#include <bits/stdc++.h>
using namespace std;
int factorial( int n)
{
int fact = 1;
for ( int i = 1; i <= n; i++) {
fact = fact * i;
}
return fact;
}
int main()
{
int n = 10, c = 0;
int f = factorial(n);
while (f != 0) {
f /= 10;
c += 1;
}
cout << c << endl;
}
|
Java
import java.util.*;
class GFG
{
static int factorial( int n)
{
int fact = 1 ;
for ( int i = 1 ; i <= n; i++) {
fact = fact * i;
}
return fact;
}
public static void main(String[] args)
{
int n = 10 , c = 0 ;
int f = factorial(n);
while (f != 0 ) {
f /= 10 ;
c += 1 ;
}
System.out.println(c);
}
}
|
Python3
from math import *
n = 10 ;c = 0
f = factorial(n)
while (f! = 0 ):
f / / = 10
c + = 1
print (c)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int factorial( int n)
{
int fact = 1;
for ( int i = 1; i <= n; i++) {
fact = fact * i;
}
return fact;
}
public static void Main( string [] args)
{
int n = 10, c = 0;
int f = factorial(n);
while (f != 0) {
f /= 10;
c += 1;
}
Console.WriteLine(c);
}
}
|
Javascript
<script>
function factorial(n) {
let fact = 1;
for (let i = 1; i <= n; i++) {
fact = fact * i;
}
return fact;
}
let n = 10; c = 0
let f = factorial(n)
while (f != 0) {
f = Math.floor(f / 10)
c += 1
}
document.write(c);
</script>
|
Time complexity: O(n) because factorial function is using a for loop
Auxiliary space: O(1) as it is using constant space for variables
References : oeis.org
Last Updated :
11 Jan, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...