https://wcipeg.com/wiki/index.php?title=Trailing_zeroes_in_factorial&feed=atom&action=historyTrailing zeroes in factorial - Revision history2024-03-29T06:47:07ZRevision history for this page on the wikiMediaWiki 1.25.2https://wcipeg.com/wiki/index.php?title=Trailing_zeroes_in_factorial&diff=1623&oldid=prevBrian: use pointfree style :D2012-02-28T23:07:52Z<p>use pointfree style :D</p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr style='vertical-align: top;'>
<td colspan='2' style="background-color: white; color:black; text-align: center;">← Older revision</td>
<td colspan='2' style="background-color: white; color:black; text-align: center;">Revision as of 23:07, 28 February 2012</td>
</tr><tr><td colspan="2" class="diff-lineno" id="L45" >Line 45:</td>
<td colspan="2" class="diff-lineno">Line 45:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>Functional style (Haskell):</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>Functional style (Haskell):</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div><syntaxhighlight lang="haskell"></div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div><syntaxhighlight lang="haskell"></div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>zeroes <del class="diffchange diffchange-inline">n </del>= sum <del class="diffchange diffchange-inline">$ </del>tail <del class="diffchange diffchange-inline">$ </del>takeWhile (>0) <del class="diffchange diffchange-inline">(</del>iterate (flip div 5<del class="diffchange diffchange-inline">) n</del>) -- note that 0 is an edge case</div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>zeroes = sum <ins class="diffchange diffchange-inline">. </ins>tail <ins class="diffchange diffchange-inline">. </ins>takeWhile (>0) <ins class="diffchange diffchange-inline">. </ins>iterate (flip div 5) -- note that 0 is an edge case</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div></syntaxhighlight></div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div></syntaxhighlight></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>Bases other than 10 may be trickier to handle. For example, consider the problem of finding the number of zeroes at the end of <math>n!</math> when expressed in base 12 (with prime factorization <math>2^2 \cdot 3</math>). In this case we have to count factors of 2 and factors of 3, but it takes ''two'' factors of 2 to make one factor of 12, so we have to divide by two and then compare it with the number of factors of 3 (the smaller of the two results will be the answer). It's not obvious which factor will "run out" first, so it might be necessary to find the number of times ''each'' prime factor in the base appears in <math>n!</math>. The algorithm shown above still works for each individual prime factor, though (provided that "5" is replaced with the appropriate number).</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>Bases other than 10 may be trickier to handle. For example, consider the problem of finding the number of zeroes at the end of <math>n!</math> when expressed in base 12 (with prime factorization <math>2^2 \cdot 3</math>). In this case we have to count factors of 2 and factors of 3, but it takes ''two'' factors of 2 to make one factor of 12, so we have to divide by two and then compare it with the number of factors of 3 (the smaller of the two results will be the answer). It's not obvious which factor will "run out" first, so it might be necessary to find the number of times ''each'' prime factor in the base appears in <math>n!</math>. The algorithm shown above still works for each individual prime factor, though (provided that "5" is replaced with the appropriate number).</div></td></tr>
</table>Brianhttps://wcipeg.com/wiki/index.php?title=Trailing_zeroes_in_factorial&diff=1622&oldid=prevBrian at 23:05, 28 February 20122012-02-28T23:05:33Z<p></p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr style='vertical-align: top;'>
<td colspan='2' style="background-color: white; color:black; text-align: center;">← Older revision</td>
<td colspan='2' style="background-color: white; color:black; text-align: center;">Revision as of 23:05, 28 February 2012</td>
</tr><tr><td colspan="2" class="diff-lineno" id="L45" >Line 45:</td>
<td colspan="2" class="diff-lineno">Line 45:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>Functional style (Haskell):</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>Functional style (Haskell):</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div><syntaxhighlight lang="haskell"></div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div><syntaxhighlight lang="haskell"></div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>zeroes n = sum $ tail $ takeWhile (>0) (iterate (flip div 5) n)</div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>zeroes n = sum $ tail $ takeWhile (>0) (iterate (flip div 5) n) <ins class="diffchange diffchange-inline">-- note that 0 is an edge case</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div></syntaxhighlight></div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div></syntaxhighlight></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>Bases other than 10 may be trickier to handle. For example, consider the problem of finding the number of zeroes at the end of <math>n!</math> when expressed in base 12 (with prime factorization <math>2^2 \cdot 3</math>). In this case we have to count factors of 2 and factors of 3, but it takes ''two'' factors of 2 to make one factor of 12, so we have to divide by two and then compare it with the number of factors of 3 (the smaller of the two results will be the answer). It's not obvious which factor will "run out" first, so it might be necessary to find the number of times ''each'' prime factor in the base appears in <math>n!</math>. The algorithm shown above still works for each individual prime factor, though (provided that "5" is replaced with the appropriate number).</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>Bases other than 10 may be trickier to handle. For example, consider the problem of finding the number of zeroes at the end of <math>n!</math> when expressed in base 12 (with prime factorization <math>2^2 \cdot 3</math>). In this case we have to count factors of 2 and factors of 3, but it takes ''two'' factors of 2 to make one factor of 12, so we have to divide by two and then compare it with the number of factors of 3 (the smaller of the two results will be the answer). It's not obvious which factor will "run out" first, so it might be necessary to find the number of times ''each'' prime factor in the base appears in <math>n!</math>. The algorithm shown above still works for each individual prime factor, though (provided that "5" is replaced with the appropriate number).</div></td></tr>
</table>Brianhttps://wcipeg.com/wiki/index.php?title=Trailing_zeroes_in_factorial&diff=1621&oldid=prevBrian: Created page with "A well-known programming exercise involves finding the number of trailing zeroes at the end of the decimal representation of <math>n!</math>, for some given value of <math>n</mat..."2012-02-28T19:28:33Z<p>Created page with "A well-known programming exercise involves finding the number of trailing zeroes at the end of the decimal representation of <math>n!</math>, for some given value of <math>n</mat..."</p>
<p><b>New page</b></p><div>A well-known programming exercise involves finding the number of trailing zeroes at the end of the decimal representation of <math>n!</math>, for some given value of <math>n</math>.<ref>{{SPOJ|FCTRL|Factorial}}</ref><ref>{{Problem|acsl1p3|Task 3: Zeros}}</ref><br />
<br />
One possible approach, of course, is to explicitly calculate the factorial. The only problem with this is that <math>n!</math> may be very large for reasonably sized values of <math>n</math>. For example, <math>100! > 10^{100}</math>, so [[bignum]] arithmetic is needed for this kind of approach. This tends to be slow and inexpedient.<br />
<br />
A much cleverer solution&mdash;one that does not involve calculating the factorial explicitly&mdash;can be obtained by noting that what is really desired is the largest <math>k</math> such that <math>10^k</math> divides <math>n!</math>. The prime factorization of <math>10^k</math> is <math>2^k 5^k</math>, so really all we need to do is find out how many factors of 2 are in <math>n!</math>, and how many factors of 5 are in <math>n!</math>, and the smaller of the two gives the answer. For example, <math>10!</math> has prime factorization <math>2^8 \cdot 3^4 \cdot 5^2 \cdot 7</math>, so it contains 8 factors of 2 and 2 factors of 5. Consistent with these figures, there are 2 zeroes at the end of its decimal representation (3628800).<br />
<br />
How do we calculate this? A workable approach is to simply determine how many factors of 2 and 5 are in each of the numbers <math>1, 2, ..., n</math>. When we multiply those numbers to get <math>n!</math>, we of course ''add'' the exponents in their prime factorizations; so the sum of the numbers of factors of 2 in each of the integers <math>1, 2, ..., n</math> gives us the number of factors of 2 in <math>n!</math>; and we do something similar for factors of 5. Determining how many times 2 or 5 divides a number is as easy as actually performing the division over and over again (until a non-integer result is obtained).<br />
<br />
There is a cleverer solution yet, though. When we multiply all the numbers from 1 to <math>n</math>, exactly <math>\lfloor n/2 \rfloor</math> of them will be even, so each one of those contributes a factor of 2. However, the ones that are divisible by 4 actually contribute ''two'' factors of 2, so we have to add <math>\lfloor n/4 \rfloor</math> to the result (we counted those numbers once in <math>\lfloor n/2 \rfloor</math>, and now we are counting them again in <math>\lfloor n/4 \rfloor</math>). But then there may be some numbers that are divisible by 8, which contribute at least ''three'' factors of 2, so we have to add <math>\lfloor n/8 \rfloor</math>; and so on until we reach some power of 2 that is greater than <math>n</math> (so that it obviously divides none of <math>1, 2, ..., n</math>). We can then do something similar for factors of 5. This gives us a formula:<br />
:<math>k = \min\left(\left\lfloor \frac{n}{2} \right\rfloor + \left\lfloor \frac{n}{4} \right\rfloor + \left\lfloor \frac{n}{8} \right\rfloor + ..., \left\lfloor \frac{n}{5} \right\rfloor + \left\lfloor \frac{n}{25} \right\rfloor + \left\lfloor \frac{n}{125} \right\rfloor + ...\right)</math><br />
It is now fairly obvious by inspection that the second argument&mdash;the number of factors of 5&mdash;is always the smaller of the two.<br />
<br />
This formula can be used as-is, hence:<br />
<syntaxhighlight lang="c"><br />
#include <stdio.h><br />
int main()<br />
{<br />
int n;<br />
scanf("%d", &n);<br />
int p = 5;<br />
int k = 0;<br />
while (p <= n)<br />
{<br />
k += n/p;<br />
p *= 5;<br />
}<br />
printf("There are %d zeroes at the end of %d!\n", k, n);<br />
return 0;<br />
}<br />
</syntaxhighlight><br />
The formula can also be re-worked into the following form. The mathematical reasoning behind the correctness of this implementation is left as an exercise for the reader.<br />
<syntaxhighlight lang="c"><br />
#include <stdio.h><br />
int main()<br />
{<br />
int n;<br />
scanf("%d", &n);<br />
int k = 0;<br />
while (n > 0)<br />
k += n /= 5;<br />
printf("There are %d zeroes at the end of %d!\n", k, n);<br />
return 0;<br />
}<br />
</syntaxhighlight><br />
Functional style (Haskell):<br />
<syntaxhighlight lang="haskell"><br />
zeroes n = sum $ tail $ takeWhile (>0) (iterate (flip div 5) n)<br />
</syntaxhighlight><br />
Bases other than 10 may be trickier to handle. For example, consider the problem of finding the number of zeroes at the end of <math>n!</math> when expressed in base 12 (with prime factorization <math>2^2 \cdot 3</math>). In this case we have to count factors of 2 and factors of 3, but it takes ''two'' factors of 2 to make one factor of 12, so we have to divide by two and then compare it with the number of factors of 3 (the smaller of the two results will be the answer). It's not obvious which factor will "run out" first, so it might be necessary to find the number of times ''each'' prime factor in the base appears in <math>n!</math>. The algorithm shown above still works for each individual prime factor, though (provided that "5" is replaced with the appropriate number).<br />
<br />
==References==<br />
<references/></div>Brian