Zeroes at the end of a factorial

35

2

Write a program or function that finds the number of zeroes at the end of n! in base 10, where n is an input number (in any desired format).

It can be assumed that n is a positive integer, meaning that n! is also an integer. There are no zeroes after a decimal point in n!. Also, it can be assumed that your programming language can handle the value of n and n!.


Test cases

1
==> 0

5
==> 1

100
==> 24

666
==> 165

2016
==> 502

1234567891011121314151617181920
==> 308641972752780328537904295461

This is code golf. Standard rules apply. The shortest code in bytes wins.

Submissions

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

# Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

# Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the leaderboard snippet:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

Leaderboard

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

/* Configuration */

var QUESTION_ID = 79762; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 43444; // This should be the user ID of the challenge author.

/* App */

var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;

function answersUrl(index) {
  return "https://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
  return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(answer_page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      answers_hash = [];
      answer_ids = [];
      data.items.forEach(function(a) {
        a.comments = [];
        var id = +a.share_link.match(/\d+/);
        answer_ids.push(id);
        answers_hash[id] = a;
      });
      if (!data.has_more) more_answers = false;
      comment_page = 1;
      getComments();
    }
  });
}

function getComments() {
  jQuery.ajax({
    url: commentUrl(comment_page++, answer_ids),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      data.items.forEach(function(c) {
        if (c.owner.user_id === OVERRIDE_USER)
          answers_hash[c.post_id].comments.push(c);
      });
      if (data.has_more) getComments();
      else if (more_answers) getAnswers();
      else process();
    }
  });  
}

getAnswers();

var SCORE_REG = /<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
  return a.owner.display_name;
}

function process() {
  var valid = [];
  
  answers.forEach(function(a) {
    var body = a.body;
    a.comments.forEach(function(c) {
      if(OVERRIDE_REG.test(c.body))
        body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
    });
    
    var match = body.match(SCORE_REG);
    if (match)
      valid.push({
        user: getAuthorName(a),
        size: +match[2],
        language: match[1],
        link: a.share_link,
      });
    
  });
  
  valid.sort(function (a, b) {
    var aB = a.size,
        bB = b.size;
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  valid.forEach(function (a) {
    if (a.size != lastSize)
      lastPlace = place;
    lastSize = a.size;
    ++place;
    
    var answer = jQuery("#answer-template").html();
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", a.user)
                   .replace("{{LANGUAGE}}", a.language)
                   .replace("{{SIZE}}", a.size)
                   .replace("{{LINK}}", a.link);
    answer = jQuery(answer);
    jQuery("#answers").append(answer);

    var lang = a.language;
    if (/<a/.test(lang)) lang = jQuery(lang).text();
    
    languages[lang] = languages[lang] || {lang: a.language, user: a.user, size: a.size, link: a.link};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    if (a.lang > b.lang) return 1;
    if (a.lang < b.lang) return -1;
    return 0;
  });

  for (var i = 0; i < langs.length; ++i)
  {
    var language = jQuery("#language-template").html();
    var lang = langs[i];
    language = language.replace("{{LANGUAGE}}", lang.lang)
                       .replace("{{NAME}}", lang.user)
                       .replace("{{SIZE}}", lang.size)
                       .replace("{{LINK}}", lang.link);
    language = jQuery(language);
    jQuery("#languages").append(language);
  }

}
body { text-align: left !important}

#answer-list {
  padding: 10px;
  width: 290px;
  float: left;
}

#language-list {
  padding: 10px;
  width: 290px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="answer-list">
  <h2>Leaderboard</h2>
  <table class="answer-list">
    <thead>
      <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
    </thead>
    <tbody id="answers">

    </tbody>
  </table>
</div>
<div id="language-list">
  <h2>Winners by Language</h2>
  <table class="language-list">
    <thead>
      <tr><td>Language</td><td>User</td><td>Score</td></tr>
    </thead>
    <tbody id="languages">

    </tbody>
  </table>
</div>
<table style="display: none">
  <tbody id="answer-template">
    <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>
<table style="display: none">
  <tbody id="language-template">
    <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>

Arcturus

Posted 2016-05-12T02:36:13.140

Reputation: 6 537

Related. – xnor – 2016-05-12T02:39:01.220

Can we assume that n! will fit within our languages' native integer type? – Alex A. – 2016-05-12T02:45:52.147

@AlexA. Yes you can. – Arcturus – 2016-05-12T03:01:31.193

Can n be an input string? – Conor O'Brien – 2016-05-12T03:10:22.030

@CᴏɴᴏʀO'Bʀɪᴇɴ Yes. – Arcturus – 2016-05-12T03:11:03.853

15I think this would be a better question if you were not allowed to assume n! would fit into your integer type! Well, maybe another time. – A Simmons – 2016-05-12T10:45:52.980

@ASimmons Most of the answers so far, or at least the ones that use the floor division trick, don't rely on that assumption anyway. – Alex A. – 2016-05-12T16:53:21.390

https://oeis.org/A027868 – Willem – 2016-05-13T17:13:22.147

I was wondering this today as well after seeing a number of ways a pack of cards can be shuffled. – philcolbourn – 2016-05-17T19:08:07.750

Also of interest: Last non-zero digit of n!.

– Toby Speight – 2018-06-05T10:49:26.530

Answers

43

Python 2, 27 bytes

f=lambda n:n and n/5+f(n/5)

The ending zeroes are limited by factors of 5. The number of multiples of 5 that are at most n is n/5 (with floor division), but this doesn't count the repeated factors in multiples of 25, 125, .... To get those, divide n by 5 and recurse.

xnor

Posted 2016-05-12T02:36:13.140

Reputation: 115 687

19

Jelly, 5 bytes

!Æfċ5

Uses the counterproductive approach of finding the factorial then factorising it again, checking for the exponent of 5 in the prime factorisation.

Try it online!

!              Factorial
 Æf            List of prime factors, e.g. 120 -> [2, 2, 2, 3, 5]
   ċ5          Count number of 5s

Sp3000

Posted 2016-05-12T02:36:13.140

Reputation: 58 729

4yikes. Talk about trade-offs! To get the code down to 5 bytes, increase the memory and time by absurd amounts. – Ross Presser – 2016-05-12T16:18:39.033

19

Mornington Crescent, 1949 1909 bytes

Take Northern Line to Bank
Take Circle Line to Bank
Take District Line to Parsons Green
Take District Line to Cannon Street
Take Circle Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Victoria
Take Circle Line to Victoria
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take District Line to Turnham Green
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Turnham Green
Take District Line to Bank
Take Circle Line to Hammersmith
Take Circle Line to Blackfriars
Take Circle Line to Hammersmith
Take Circle Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Becontree
Take District Line to Upminster
Take District Line to Becontree
Take District Line to Upminster
Take District Line to Becontree
Take District Line to Upminster
Take District Line to Bank
Take Circle Line to Blackfriars
Take District Line to Upminster
Take District Line to Temple
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Bank
Take Circle Line to Blackfriars
Take Circle Line to Hammersmith
Take District Line to Becontree
Take District Line to Cannon Street
Take District Line to Becontree
Take District Line to Cannon Street
Take District Line to Becontree
Take District Line to Blackfriars
Take Circle Line to Bank
Take District Line to Upminster
Take District Line to Becontree
Take District Line to Upminster
Take District Line to Becontree
Take District Line to Upminster
Take District Line to Becontree
Take District Line to Bank
Take Circle Line to Bank
Take Northern Line to Angel
Take Northern Line to Bank
Take Circle Line to Bank
Take District Line to Upminster
Take District Line to Bank
Take Circle Line to Bank
Take Northern Line to Mornington Crescent

-40 bytes thanks to NieDzejkob

pppery

Posted 2016-05-12T02:36:13.140

Reputation: 3 987

And this is now my most upvoted answer. – pppery – 2016-05-17T13:25:28.473

3A brief explanation for those of us who are Mornington Crescent-challenged would be cool. :) – Robert Benson – 2017-03-23T13:26:02.013

-40 bytes by using shorter line names where possible. – NieDzejkob – 2018-03-15T17:02:43.803

18

Pyth, 6 bytes

/P.!Q5

Try it here.

/    5   Count 5's in
 P        the prime factorization of
  .!Q      the factorial of the input.

Alternative 7-byte:

st.u/N5

The cumulative reduce .u/N5 repeatedly floor-divides by 5 until it gets a repeat, which in this case happens after it hits 0.

34 -> [34, 6, 1, 0]

The first element is then removed (t) and the rest is summed (s).

xnor

Posted 2016-05-12T02:36:13.140

Reputation: 115 687

13

Actually, 10 bytes

!$R;≈$l@l-

Try it online!

Note that the last test case fails when running Seriously on CPython because math.factorial uses a C extension (which is limited to 64-bit integers). Running Seriously on PyPy works fine, though.

Explanation:

!$R;≈$l@l-
!           factorial of input
 $R         stringify, reverse
   ;≈$      make a copy, cast to int, then back to string (removes leading zeroes)
      l@l-  difference in lengths (the number of leading zeroes removed by the int conversion)

Mego

Posted 2016-05-12T02:36:13.140

Reputation: 32 998

3Oh wow, I like how this method doesn't use the dividing by 5 trick. – Arcturus – 2016-05-12T04:36:17.640

I count 12 bytes on this one – Score_Under – 2016-05-14T02:09:19.670

1@Score_Under Actually uses the CP437 code page, not UTF-8. Each character is one byte. – Mego – 2016-05-14T02:41:40.260

10

Haskell, 26 bytes

f 0=0
f n=(+)=<<f$div n 5

Floor-divides the input by 5, then adds the result to the function called on it. The expression (+)=<<f takes an input x and outputs x+(f x).

Shortened from:

f 0=0
f n=div n 5+f(div n 5)

f 0=0
f n|k<-div n 5=k+f k

A non-recursive expression gave 28 bytes:

f n=sum[n`div`5^i|i<-[1..n]]

xnor

Posted 2016-05-12T02:36:13.140

Reputation: 115 687

Is i a counter from 1..n? – Conor O'Brien – 2016-05-12T03:35:09.573

@CᴏɴᴏʀO'Bʀɪᴇɴ Yes, though only up to log_5(n) matters, the rest gives 0. – xnor – 2016-05-12T03:36:15.497

8

MATL, 9 bytes

:"@Yf5=vs

Try it online!

This works for very large numbers, as it avoids computing the factorial.

Like other answers, this exploits the fact that the number of times 2 appears as divisor of the factorial is greater or equal than the number of times 5 appears.

:     % Implicit input. Inclusive range from 1 to that
"     % For each
  @   %   Push that value
  Yf  %   Array of prime factors
  5=  %   True for 5, false otherwise
  v   %   Concatenate vertically all stack contents
  s   %   Sum

Luis Mendo

Posted 2016-05-12T02:36:13.140

Reputation: 87 464

6

05AB1E, 5 bytes

Would be 4 bytes if we could guarantee n>4

Code:

Î!Ó7è

Explanation:

Î        # push 0 then input
  !      # factorial of n: 10 -> 2628800
   Ó     # get primefactor exponents -> [8, 4, 2, 1]
    7è   # get list[7] (list is indexed as string) -> 2
         # implicit output of number of 5s or 0 if n < 5

Alternate, much faster, 6 byte solution: Inspired by Luis Mendo's MATL answer

LÒ€`5QO

Explanation:

L         # push range(1,n) inclusive, n=10 -> [1,2,3,4,5,6,7,8,9,10]
 Ò        # push prime factors of each number in list -> [[], [2], [3], [2, 2], [5], [2, 3], [7], [2, 2, 2], [3, 3], [2, 5]]
  €`      # flatten list of lists to list [2, 3, 2, 2, 5, 2, 3, 7, 2, 2, 2, 3, 3, 2, 5]
    5Q    # and compare each number to 5 -> [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
      O   # sum -> 2

Edit: removed solutions using ¢ (count) as all primes containing 5 would be counted as 5 e.g. 53.

Edit 2: added a more efficient solution for higher input as comparison.

Emigna

Posted 2016-05-12T02:36:13.140

Reputation: 50 798

Yeah, instead of , 5Q should work. Nice answer though! :) – Adnan – 2016-05-12T08:41:23.537

I was going to test on larger inputs with the comment "wouldn't this fail if the output was > 9", but boy 05AB1E's implementation of Ó is slow – Sp3000 – 2016-05-12T09:51:43.020

Btw, the first code can also be Î!Ó2é. The bug was fixed yesterday.

– Adnan – 2016-05-12T10:15:36.180

If you're using utf-8, Î!Ó7è is 8 bytes, and the "6 byte" solution is 10 bytes – Score_Under – 2016-05-14T02:11:30.860

@Score_Under Yes that is correct. However, 05AB1E uses the CP-1252 encoding. – Adnan – 2016-05-14T08:50:27.083

6

Matlab (59) (54)(39)

Hey dawg !!!! we heard you like maths ....

  @(n)sum(fix(n./5.^(1:fix(log(n)/1.6))))
  • This is based on my created answer in code review.

  • further than what is mentioned in my answer in code review, the formula for number of zeros in factorial(n) is Sum(n/(5^k)) where k varies between 1 and log_5(n)

  • The only trivial reason why it cant get golfier is that log5 isnt available in matlab as a builtin , thus I replaced log(5) by 1.6, doesnt matter because it will be anyways floored.

Give it a try

Abr001am

Posted 2016-05-12T02:36:13.140

Reputation: 862

A couple of questions. 1. How do you actually run this in Matlab? 2. What is the result for n=1? – Stuart Bruff – 2016-05-12T14:46:25.133

@StuartBruff to run this type ans(1) and it does return 0. – Abr001am – 2016-05-12T16:09:17.797

OK. Thanks. Interesting. I haven't used function handles much in Matlab, so was a little puzzled as to how to run it ... why doesn't the ans() count towards the total? Neat answer though, I tried it in Mathcad but had to modify the upper limit of the sum as Mathcad autodecrements the summation variable if the "upper" is less than the "lower" limit (and hence my question about 0). – Stuart Bruff – 2016-05-13T12:27:02.567

5

Mathematica, 20 bytes

IntegerExponent[#!]&

IntegerExponent counts the zeros. For fun, here's a version that doesn't calculate the factorial:

Tr[#~IntegerExponent~5&~Array~#]&

LegionMammal978

Posted 2016-05-12T02:36:13.140

Reputation: 15 731

I think Array saves a byte on the second solution. – Martin Ender – 2016-05-12T12:54:44.497

5

C, 28 bytes

f(n){return(n/=5)?n+f(n):n;}

Explanation

The number of trailing zeros is equal to the number of fives that make up the factorial. Of all the 1..n, one-fifth of them contribute a five, so we start with n/5. Of these n/5, a fifth are multiples of 25, so contribute an extra five, and so on. We end up with f(n) = n/5 + n/25 + n/125 + ..., which is f(n) = n/5 + f(n/5). We do need to terminate the recursion when n reaches zero; also we take advantage of the sequence point at ?: to divide n before the addition.

As a bonus, this code is much faster than that which visits each 1..n (and much, much faster than computing the factorial).

Test program

#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv) {
    while(*++argv) {
        int i = atoi(*argv);
        printf("%d: %d\n",i,f(i));
    }
}

Test output

1: 0
4: 0
5: 1
24: 4
25: 6
124: 28
125: 31
666: 165
2016: 502
2147483644: 536870901
2147483647: 536870902

Toby Speight

Posted 2016-05-12T02:36:13.140

Reputation: 5 058

+1 for an excellent explanation – Titus – 2018-06-05T10:42:18.663

4

JavaScript ES6, 20 bytes

f=x=>x&&x/5+f(x/5)|0

Same tactic as in xnor's answer, but shorter.

Conor O'Brien

Posted 2016-05-12T02:36:13.140

Reputation: 36 228

4

Julia, 34 31 30 bytes

n->find(digits(prod(1:n)))[]-1

This is an anonymous function that accepts any signed integer type and returns an integer. To call it, assign it to a variable. The larger test cases require passing n as a larger type, such as a BigInt.

We compute the factorial of n (manually using prod is shorter than the built-in factorial), get an array of its digits in reverse order, find the indices of the nonzero elements, get the first such index, and subtract 1.

Try it online! (includes all but the last test case because the last takes too long)

Saved a byte thanks to Dennis!

Alex A.

Posted 2016-05-12T02:36:13.140

Reputation: 23 761

3

C, 36

r;f(n){for(r=0;n/=5;)r+=n;return r;}

Same method as @xnor's answer of counting 5s, but just using a simple for loop instead of recursion.

Ideone.

Digital Trauma

Posted 2016-05-12T02:36:13.140

Reputation: 64 644

@TobySpeight there you go. – Digital Trauma – 2016-05-13T17:01:58.570

3

Retina, 33 bytes

Takes input in unary.

Returns output in unary.

+`^(?=1)(1{5})*1*
$#1$*1;$#1$*
;

(Note the trailing linefeed.)

Try it online!

How it works:

The first stage:

+`^(?=1)(1{5})*1*
$#1$*1;$#1$*

Slightly ungolfed:

+`^(?=1)(11111)*1*\b
$#1$*1;$#1$*1

What it does:

  • Firstly, find the greatest number of 11111 that can be matched.
  • Replace by that number
  • Effectively floor-divides by 5.
  • The lookahead (?=1) assures that the number is positive.
  • The +` means repeat until idempotent.
  • So, the first stage is "repeated floor-division by 5"

If the input is 100 (in unary), then the text is now:

;;1111;11111111111111111111

Second stage:

;

Just removes all semi-colons.

Leaky Nun

Posted 2016-05-12T02:36:13.140

Reputation: 45 011

2

Ruby, 22 bytes

One of the few times where the Ruby 0 being truthy is a problem for byte count.

f=->n{n>0?f[n/=5]+n:0}

Value Ink

Posted 2016-05-12T02:36:13.140

Reputation: 10 608

wait why is 0 truthy? – Conor O'Brien – 2016-05-12T04:00:07.867

2@CᴏɴᴏʀO'Bʀɪᴇɴ In Ruby, nil and false are falsey, and nothing else is. There are a lot of cases where helps out in golf, since having 0 be truthy means the index and regex index functions in Ruby return nil if there is no match instead of -1, and some where it is a problem, like empty strings still being truthy. – Value Ink – 2016-05-12T04:24:07.990

@KevinLau-notKenny That does make sense. – Conor O'Brien – 2016-05-12T04:25:27.877

2

Perl 6, 23 bytes

{[+] -$_,$_,*div 5…0}
{sum -$_,$_,*div 5...0}

I could get it shorter if ^... was added to Perl 6 {sum $_,*div 5^...0}.
It should be more memory efficient for larger numbers if you added a lazy modifier between sum and the sequence generator.

Explanation:

{ # implicitly uses $_ as its parameter
  sum

    # produce a sequence
    -$_,     # negate the next value
     $_,     # start of the sequence

     * div 5 # Whatever lambda that floor divides its input by 5

             # the input being the previous value in the sequence,
             # and the result gets appended to the sequence

     ...     # continue to do that until:

     0       # it reaches 0
}

Test:

#! /usr/bin/env perl6

use v6.c;
use Test;

my @test = (
     1,   0,
     5,   1,
   100,  24,
   666, 165,
  2016, 502,
  1234567891011121314151617181920,
        308641972752780328537904295461,

  # [*] 5 xx 100
  7888609052210118054117285652827862296732064351090230047702789306640625,
        1972152263052529513529321413206965574183016087772557511925697326660156,
);

plan @test / 2;

# make it a postfix operator, because why not
my &postfix:<!0> = {[+] -$_,$_,*div 5...0}

for @test -> $input, $expected {
  is $input!0, $expected, "$input => $expected"
}

diag "runs in {now - INIT now} seconds"
1..7
ok 1 - 1 => 0
ok 2 - 5 => 1
ok 3 - 100 => 24
ok 4 - 666 => 165
ok 5 - 2016 => 502
ok 6 - 1234567891011121314151617181920 => 308641972752780328537904295461
ok 7 - 7888609052210118054117285652827862296732064351090230047702789306640625 => 1972152263052529513529321413206965574183016087772557511925697326660156
# runs in 0.0252692 seconds

( That last line is slightly misleading, as MoarVM has to start, load the Perl 6 compiler and runtime, compile the code, and run it. So it actually takes about a second and a half in total.
That is still significantly faster than it was to check the result of the last test with WolframAlpha.com )

Brad Gilbert b2gills

Posted 2016-05-12T02:36:13.140

Reputation: 12 713

2

Mathcad, [tbd] bytes

enter image description here

Mathcad is sort of mathematical "whiteboard" that allows 2D entry of expressions, text and plots. It uses mathematical symbols for many operations, such as summation, differentiation and integration. Programming operators are special symbols, usually entered as single keyboard combinations of control and/or shift on a standard key.

What you see above is exactly how the Mathcad worksheet looks as it is typed in and as Mathcad evaluates it. For example, changing n from 2016 to any other value will cause Mathcad to update the result from 502 to whatever the new value is.

http://www.ptc.com/engineering-math-software/mathcad/free-download


Mathcad's byte equivalence scoring method is yet to be determined. Taking a symbol equivalence, the solution takes about 24 "bytes" (the while operator can only be entered using the "ctl-]" key combination (or from a toolbar)). Agawa001's Matlab method takes about 37 bytes when translated into Mathcad (the summation operator is entered by ctl-shft-$).

Stuart Bruff

Posted 2016-05-12T02:36:13.140

Reputation: 501

Sounds a stunning tool to handle, I wont spare a second downloading it ! – Abr001am – 2016-05-13T13:42:10.760

2

dc, 12 bytes

[5/dd0<f+]sf

This defines a function f which consumes its input from top of stack, and leaves its output at top of stack. See my C answer for the mathematical basis. We repeatedly divide by 5, accumulating the values on the stack, then add all the results:

5/d   # divide by 5, and leave a copy behind
d0<   # still greater than zero?
f+    # if so, apply f to the new value and add

Test program

# read input values
?
# print prefix
[  # for each value
    # print prefix
    [> ]ndn[ ==> ]n
    # call f(n)
    lfx
    # print suffix
    n[  
]n
    # repeat for each value on stack
    z0<t
]
# define and run test function 't'
dstx

Test output

./79762.dc <<<'1234567891011121314151617181920 2016 666 125 124 25 24 5 4 1'
1 ==> 0  
4 ==> 0  
5 ==> 1  
24 ==> 4  
25 ==> 6  
124 ==> 28  
125 ==> 31  
666 ==> 165  
2016 ==> 502  
1234567891011121314151617181920 ==> 308641972752780328537904295461  

Toby Speight

Posted 2016-05-12T02:36:13.140

Reputation: 5 058

1

Pyt, 5 bytes

5←!ḋɔ

Explanation:

5             Pushes 5
 ←            Gets input
  !           Factorial
   ḋ          Prime factors (with duplicates)
    ɔ         Count occurrences of 5 in the list of prime factors

Try it online!

mudkip201

Posted 2016-05-12T02:36:13.140

Reputation: 833

1

J, 15 bytes

+/<.(%5:^>:@i.)

Who needs to calculate factorial?

Probably longer than with though :p

Explanation when I get home

Bolce Bussiere

Posted 2016-05-12T02:36:13.140

Reputation: 970

(%5:^>:@i.) -> (%5^1+i.) – FrownyFrog – 2018-01-04T03:06:46.897

1

Runic Enchantments, 21 bytes

Rl1)?@+
/:>i5,'fA:0)?

Try it online!

Uses the same f(n) = n/5 + f(n/5) as other answers. Just took some coercion to to reduce the footprint as much as possible. Fortunately > does nothing when executed (it simply marks the entry point) and i pushes nothing to the stack when no more input remains.

Draco18s no longer trusts SE

Posted 2016-05-12T02:36:13.140

Reputation: 3 053

1

Python 3, 52 bytes

g=lambda x,y=1,z=0:z-x if y>x else g(x,y*5,z+x//y)

Magenta

Posted 2016-05-12T02:36:13.140

Reputation: 1 322

This doesn't work, try the test cases. – xnor – 2016-05-12T03:00:41.887

It should work now. – Magenta – 2016-05-12T15:26:00.543

1

J, 28 17 16 bytes

<.@+/@(%5^>:@i.)

Pretty much the same as the non-recursive technique from xnor's answer.


Here's an older version I have kept here because I personally like it more, clocking in at 28 bytes:

+/@>@{:@(0<;._1@,'0'&=@":@!)

Whilst not needed, I have included x: in the test cases for extended precision.

   tf0 =: +/@>@{:@(0<;._1@,'0'&=@":@!@x:)
   tf0 5
1
   tf0 100
24

   tf0g =: tf0"0
   tf0g 1 5 100 666 2016
0 1 24 165 502

The last number doesn't work with this function.

Explanation

This works by calculating n!, converting it to a string, and checking each member for equality with '0'. For n = 15, this process would be:

15
15! => 1307674368000
": 1307674368000 => '1307674368000'
'0' = '1307674368000' => 0 0 1 0 0 0 0 0 0 0 1 1 1

Now, we use ;._1 to split the list on its first element (zero), boxing each split result, yielding a box filled with aces (a:) or runs of 1s, like so:

┌┬─┬┬┬┬┬┬┬─────┐
││1│││││││1 1 1│
└┴─┴┴┴┴┴┴┴─────┘

We simple obtain the last member ({:), unbox it (>), and perform a summation over it +/, yielding the number of zeroes.

Here is the more readable version:

split =: <;._1@,
tostr =: ":
is =: =
last =: {:
unbox =: >
sum =: +/
precision =: x:
n =: 15

NB. the function itself
tf0 =: sum unbox last 0 split '0' is tostr ! precision n
tf0 =: sum @ unbox @ last @ (0 split '0'&is @ tostr @ ! @ precision)
tf0 =: +/ @ > @ {: @ (0 <;._1@, '0'&= @ ": @ ! )

Conor O'Brien

Posted 2016-05-12T02:36:13.140

Reputation: 36 228

>:@i. can be written 1+i. to save a byte. – algorithmshark – 2016-05-18T21:02:48.503

Your older version can be made into [:#.~'0'=":@! for 13 bytes by changing the method of counting the trailing 1s. – cole – 2017-12-28T01:11:42.487

1

Jolf, 13 bytes

Ώmf?H+γ/H5ΏγH

Defines a recursive function which is called on the input. Try it here!

Ώmf?H+γ/H5ΏγH  Ώ(H) = floor(H ? (γ = H/5) + Ώ(γ) : H)
Ώ              Ώ(H) =
       /H5                           H/5
      γ                         (γ =    )
     +    Ώγ                              + Ώ(γ)
   ?H       H               H ?                  : H
 mf                   floor(                        )
               // called implicitly with input

Conor O'Brien

Posted 2016-05-12T02:36:13.140

Reputation: 36 228

1

Dyalog APL, 9 bytes

⊥⍨'0'=⍕!⎕

prompt for number

! factorialize

stringify

'0'= check equality to character zero

⊥⍨ count trailing trues*


*Literally it is a mixed-base to base-10 conversion, using the boolean list as both number and base:

⊥⍨0 1 0 1 1 is the same as 0 1 0 1 1⊥⍨0 1 0 1 1 which is 0×(0×1×0×1×1) 1×(1×0×1×1) 0×(0×1×1) 1×(1×1) + 1×(1) which again is two (the number of trailing 1s).

Adám

Posted 2016-05-12T02:36:13.140

Reputation: 37 779

1

Perl, 24 22 + 1 (-p flag) = 23 bytes

$\+=$_=$_/5|0while$_}{

Using:

> echo 2016 | perl -pe '$\+=$_=$_/5|0while$_}{'

Full program:

while (<>) {
# code above added by -p
    while ($_) {
        $\ += $_ = int($_ / 5);
    }
} {
# code below added by -p
    print;  # prints $_ (undef here) and $\
}

Denis Ibaev

Posted 2016-05-12T02:36:13.140

Reputation: 876

1

Pyke, 5 bytes

SBP5/

Try it here!

S     -    range(1,input()+1)
 B    -   product(^)
  P   -  prime_factors(^)
   5/ - count(^, 5)

Blue

Posted 2016-05-12T02:36:13.140

Reputation: 26 661

1

RETURN, 17 bytes

[$[5÷\%$F+][]?]=F

Try it here.

Recursive operator lambda. Usage:

[$[5÷\%$F+][]?]=F666F

Explanation

[             ]=F  Lambda -> Operator F
 $                 Check if top of stack is truthy
  [       ][]?     Conditional
   5÷\%$F+         If so, do x/5+F(x/5)

Mama Fun Roll

Posted 2016-05-12T02:36:13.140

Reputation: 7 234

1

Ruby, 70 61 51 49 bytes

Version 3 with thanks to Kenny Lau and daniero

->n{(n-n.to_s(5).chars.map(&:to_i).reduce(:+))/4}

Edit: Turns out you can save two bytes by mapping to_i before you reduce. Weird :P

This function subtracts the sum of n's base 5 digits from n and then divides that result by 4. This is related to the sum of the geometric series 1+5+25+..+5**n = (5**n+1)/4.

As an example (again, with thanks to Kenny Lau), consider 358 (2413 in base 5) minus its base 5 digits.

2413-2-4-1-3 
= (2000-2) + (400-4) + (10-1) + (3-3)
# consider that 1000-1=444 and you'll see why every 5**n is multiplied by 4
= 2*444 + 4*44 + 1*4 + 3*0
= 2*(4*5**0+4*5**1+4*5**2) + 4*(4*5**0+4*5**1) + 1*(4*5**0) + 3*()
= 348

Divide 348 by 4 and you get f(358) = 87.

Version 2 with thanks to Kenny Lau

->n{s=(1..n).reduce(:*).to_s;s.size-s.reverse.to_i.to_s.size}

This function calculates n! then subtracts the size of n! from the size of (n!).reverse.to_i.to_s, which removes all the zeroes, thus, returning the size of the zeroes themselves.

Version 1

->n{s=n.to_s(5).chars;(0...s.size).reduce{|a,b|a+(s[0,b]*'').to_i(5)}}

This a variation of the "How many 5s are there in the prime factorization of n!?" trick that uses Ruby's simple base conversion builtins.

The golfing is a bit of a pain though, with converting from Integer to String to Array, grabbing part of the Array and converting that to String to Integer again for the reduce. Any golfing suggestions are welcome.

Sherlock9

Posted 2016-05-12T02:36:13.140

Reputation: 11 664

It's slightly shorter to map to_i before reducing: ->n{(n-n.to_s(5).chars.map(&:to_i).reduce(:+))/4} (saves two bytes) – daniero – 2016-05-16T16:21:54.033

@daniero I would not have expected that. Thanks :D – Sherlock9 – 2016-05-16T17:37:16.620

1

Java, 38 bytes

int z(int n){return n>0?n/5+z(n/5):0;}

Full program, with ungolfed method:

import java.util.Scanner;

public class Q79762{
    int zero_ungolfed(int number){
        if(number == 0){
            return 0;
        }
        return number/5 + zero_ungolfed(number/5);
    }
    int z(int n){return n>0?n/5+z(n/5):0;}
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.close();
        System.out.println(new Q79762().zero_ungolfed(n));
        System.out.println(new Q79762().z(n));
    }
}

Leaky Nun

Posted 2016-05-12T02:36:13.140

Reputation: 45 011

1

J, 7 bytes

Monadic function, taking argument on the right.

3{:@q:!

If x is positive, x q: y returns the exponents in a prime factorization of y, for only the first x primes. The 3-rd prime is 5 and {: takes the tail of a list.

Note that you have to input integers with an x at the end, or else J will treat them as floats.

   3{:@q:! 100x
24
   3{:@q:! 666x
165
   3{:@q:! 2016x
502

Try it yourself at tryj.tk, though be warned that this online interpreter will complain if you try anything larger than 1343.

If you want something that doesn't compute n! and hence doesn't require it fit in an integer, use the recursive solution <.@%&5(+$:@)^:*. (tryj.tk is still whiny on large inputs.)

algorithmshark

Posted 2016-05-12T02:36:13.140

Reputation: 8 144

1

Julia, 21 19 bytes

!n=n<5?0:!(n÷=5)+n

Uses the recursive formula from xnor's answer.

Try it online!

Dennis

Posted 2016-05-12T02:36:13.140

Reputation: 196 637

0

GML, 35 bytes

a=argument0 while a/=5b+=a return b

Timtech

Posted 2016-05-12T02:36:13.140

Reputation: 12 038

0

Japt, 6 bytes

Can only handle inputs up to 21 due to JavaScript's integer limitations.

Êk xv5

Try it


Explanation

Ê          :Factorial
 k         :Prime factors
   v5      :Divisible by 5?
  x        :Reduce by addition

Shaggy

Posted 2016-05-12T02:36:13.140

Reputation: 24 623

0

PHP, 43 39 bytes

based on Toby Speight´s C solution

function f($n){return$n?f($n/=5)+$n|0:0;}

Try it online.

Titus

Posted 2016-05-12T02:36:13.140

Reputation: 13 814

0

Stax, 4 bytes

╩+Pî

Run and debug it

I omitted the final test case. The algorithm is correct, but the time requirements are beyond my patience or predicted lifespan.

Method:

  1. Compute factorial
  2. Calculate "multiplicity" by 10.

recursive

Posted 2016-05-12T02:36:13.140

Reputation: 8 616

0

Forth (gforth), 38 bytes

Based on Toby Speight's C Solution

: f dup 0> if 5 / dup recurse + then ;

Try it online!

Code Explanation

: f           \ start a new word definition
  dup 0> if   \ check if n > 0
    5 / dup   \ divide by 5 and duplicate if so
    recurse   \ call f on n/5
    +         \ add to sum
  then        \ end if
;             \ end word definition

reffu

Posted 2016-05-12T02:36:13.140

Reputation: 1 361

0

Keg, -rR, 9 bytes

0&¡÷{0=|⑹

Try it online!

I'm sure there is a more efficient way by using some sort of formula, but a counting method was the best I could think of.

Explained

0&¡÷{0=|⑹
0&          #Store 0 in the register
  ¡÷        #Take the factorial of the (implicit) input and item split
    {0=     #While the top item is still 0:
       |⑹  #    Increment the register
            #-rR prints the register as an integer at end of execution

Lyxal

Posted 2016-05-12T02:36:13.140

Reputation: 5 253

0

CJam, 9 bytes

l~m!mf5e=

Try it online!

Just counting the 5's 5e= in the prime factorization mf of the factorial m! of the input l~.

Doesn't work for big factorials, since they don't fit into an integer.

Denker

Posted 2016-05-12T02:36:13.140

Reputation: 6 639

0

C, 53 bytes

 i,r;z(n){for(;i=n--;)for(;i=i%5?0:i/5;)r++;return r;}

Counting 5s in the sequence that makes up the factorial, instead of calculating the factorial and then counting its 5s.

Full program:

i,r;z(n){for(;i=n--;)for(;i=i%5?0:i/5;)r++;return r;}
#include <stdio.h>
int main(int argc, char **argv) {
    int n;
    sscanf(argv[1], "%d", &n);
    printf("%d -> %d\n", n, z(n));
    return 0;
}

tucuxi

Posted 2016-05-12T02:36:13.140

Reputation: 583

0

Convex, 6 bytes

¡mf5e=

Use Java interpreter or this alternate version that works on TIO: Try it online

This would be 4 bytes if I was finished getting rid of 2 char operators....

GamrCorps

Posted 2016-05-12T02:36:13.140

Reputation: 7 058

0

PowerShell v2+, 60 bytes (but see the NB below)

A completely different approach, doing exactly what is requested by the challenge. ;-)

$a=2..$args[0]-join'*'|iex;"$a".length-"$a".Trim('0').length

Takes input $args and creates a dynamic range .., then -joins it together with * for multiplication, pipes that to iex (similar to eval) to compute the factorial. Store that in $a.

We then take the length of the string representation and subtract off the length of the string representation after we've passed it to .Trim('0') which will remove leading and trailing zeroes. Since there will never be leading zeroes, this gets us the result we want.

NB: The above will work for up to n=17 without a problem, as even though 17! is bigger than [Int]::MaxValue, since we didn't explicitly specify the casting for $a, PowerShell will dynamically convert it to [double] for us upon overflow. Yeah ... in PowerShell, [int] will overflow to [double] if not explicitly cast. No, I don't know why it goes to that rather than [int64].

However, at 18!, PowerShell will automatically convert the number to scientific notation when the implicit .ToString() is called (i.e., when encapsulating it within quotes), in order to preserve significant digits. We can get around that with explicit formatting instead -- $a="{0:0}"-f(2..$args[0]-join'*'|iex);$a.length-$a.Trim('0').length -- at 67 bytes. That will get us up to 20! before we start to run into loss of precision.

Thus, to handle an "arbitrary" input, we'll need to combine the above explicit formatting with the [bigint] datatype ...

PowerShell v2+, 80 bytes

$a="{0:0}"-f("[bigint]"+(2..$args[0]-join'*')|iex);$a.length-$a.Trim('0').length

This will prepend an explicit cast of [bigint] to the first number in the range 2, and in PowerShell the datatype on the left of the operator is used for output, so that [bigint] datatype will continue through the rest of the factorial calculation.


An few examples of the three methods at some key points, with some additional output text showing what's happening in the background -- the first output is the top code, the middle is with the explicit string formatting, and the bottom is with the [bigint] datatype.

PS C:\Tools\Scripts> .\golfing\zeroes-at-end-of-factorial.ps1 17
(Normal) 355687428096000 = 3
(Format) 355687428096000 = 3
(BigInt) 355687428096000 = 3

PS C:\Tools\Scripts> .\golfing\zeroes-at-end-of-factorial.ps1 18
(Normal) 6.402373705728E+15 = 0
(Format) 6402373705728000 = 3
(BigInt) 6402373705728000 = 3

PS C:\Tools\Scripts> .\golfing\zeroes-at-end-of-factorial.ps1 21
(Normal) 5.10909421717094E+19 = 0
(Format) 51090942171709400000 = 5
(BigInt) 51090942171709440000 = 4

PS C:\Tools\Scripts> .\golfing\zeroes-at-end-of-factorial.ps1 100
(Normal) 9.33262154439441E+157 = 0
(Format) 933262154439441000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000 = 143
(BigInt) 933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000
00000000 = 24

PS C:\Tools\Scripts> .\golfing\zeroes-at-end-of-factorial.ps1 666
(Normal) Infinity = 0
(Format) Infinity = 0
(BigInt) 101063205684078149339082270812987645175758239832414541134042080735741380210369702298920280680149101204098980220355752703933970405713072930283454242384
016585642874066153029797241068282869939717688434251350949378748077490349338925526287834176188326189942648494465716169313138031111761957305152642332038964180541
081606760789306748325981681536460982866866274811038560365797328460484207809414155642770874534510059882948847250594907196772727091196506088520929434066550648022
642608335790150309778114083249701373807911277761571911620331754219999948922714475266708579675248268885046126373228453917614236582397369676453760327876932228670
885547506983568164371084614056976933006577541441308350104365957229945444651724282400214055514046429629100190143841467573055296491456926973403850076414055114364
283612861330473414734808609512385966092678846067118146921625221337465049955783174195059482714722569989641408869425126104519667256749553222882671938160611697400
311264211156133257350321296072971178199390387741639438171846476552757501425212904028323696392262434445697502405816736843180906854457725847298397943781807264821
360865009874936976105696120379126536366566469680224519996204004154443821032721047698220334845859609307929656956126740947391412413210205581149373619966878853487
232170536051130524871079644147921335454258357607659625021345466796883799602327316306909470042946710666392541958119313633986054565867362395523193239940480940410
876723200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000 = 165

AdmBorkBork

Posted 2016-05-12T02:36:13.140

Reputation: 41 581

0

dc, 26

?[5/dd0<m]dsmx[+z1<m]dsmxp

Digital Trauma

Posted 2016-05-12T02:36:13.140

Reputation: 64 644

0

rs, 95 bytes

(\d+)/(_)^^(\1)
_(_+)/_\1 \1
+_(_+) _(_+)$/(_\1)^^((^^_\2)) \2
 _$/
(_+)/(^^\1)
.*?(0*)$/(^^\1)

Live demo.

Note that I can't test this with large inputs such as 100. Feel free to try it, but you'd need over 8.486e145 TB of RAM...

An explanation of the first 5 lines is available here. The last line just counts the zeroes at the end.

kirbyfan64sos

Posted 2016-05-12T02:36:13.140

Reputation: 8 730

0

Haskell, 39 bytes

Can't compete with @xnor, but it was fun and the result is a different approach:

f n=sum$[1..n]>>= \i->1<$[5^i,2*5^i..n]

Michael Klein

Posted 2016-05-12T02:36:13.140

Reputation: 2 111

0

CJam, 11

Efficient solution, similar to other answers.

Loop version:

ri{5/_}h]:+

Try it online

Explanation:

ri      read the input and convert to integer
{…}h    do…while
  5/    divide by 5
  _     duplicate the last number
         the loop terminates when the number reaches 0
]:+     add all the numbers from the stack

Recursive version:

ri0{5/_j+}j

Try it online

Explanation:

ri       read the input and convert to integer
0{…}j    calculate with memoized recursion and initial value 0 for input 0
  5/     divide by 5
  _      duplicate the result
  j      calculate the number of zeros recursively for that number
  +      add the 2 results

aditsu quit because SE is EVIL

Posted 2016-05-12T02:36:13.140

Reputation: 22 326

0

PHP, 62 bytes

for($n=$z=0;++$n<=log(125,5);){$z+=floor(125/(5**$n));}echo$z;
exploded view
for ($n=$z=0; ++$n<=log(125,5); ) {
  $z += floor( 125 / (5 ** $n) );
}
echo $z;

The starting point for many of the answers here is that every 5th factor adds a single 0, since there are 2-3 even numbers that precede it, and you can only get a new 0 with both a factor of 2 and a factor of 5.

If we assumed this to be true, the answer is simple in PHP, in 23 bytes:

echo(floor(argv[0]/5));

However, consider 25!. 24! has 4 0's in it (because of 5, 10, 15, and 20). But 25 adds two 5's to the equation, meaning 25! has 6 0's in it. So we have to account for 5^n as well.

ricdesi

Posted 2016-05-12T02:36:13.140

Reputation: 499

0

GNU coreutils, 34 bytes

seq $1|factor|tr \  \\n|grep -cx 5

The set of prime factors of the factorial n! is the union of the sets of prime factors of 1..n. We just need to count the number of fives, as this will always be less than the number of twos, and it takes one five and one two to produce each trailing zero. Luckily, we don't need to deal with n==0 (would the solitary zero count as 'trailing'?)

The output of factor is not quite what we want (in fact, in every golf I do, the reprinting of input is a nuisance):

$ seq 6|factor
1:
2: 2
3: 3
4: 2 2
5: 5
6: 2 3

By replacing each space with a newline, we can match lines that are exactly 5 (this handily eliminates the 5: prefix for that line), and count the total.

You will probably run out of memory and/or time trying the last of the example inputs, but there's nothing in the program itself that wouldn't work.

Toby Speight

Posted 2016-05-12T02:36:13.140

Reputation: 5 058

0

bc, 51 bytes

define f(x){if(x){return x/5+f(x/5)}else{return 0}}

Same tactic as in xnor and Cᴏɴᴏʀ O'Bʀɪᴇɴ's answers, but longer.

David Conrad

Posted 2016-05-12T02:36:13.140

Reputation: 1 037

0

Erlang, 33 bytes

f(0)->0;f(N)->N div 5+f(N div 5).

Same tactic as in xnor and Cᴏɴᴏʀ O'Bʀɪᴇɴ's answers.

Ungolfed:

f(0) -> 0;
f(N) when N > 0 -> N div 5 + f(N div 5).

David Conrad

Posted 2016-05-12T02:36:13.140

Reputation: 1 037