阶乘结尾的零


35

编写一个程序或函数,该函数或函数在以n!10 为基数的末尾找到零的数目,其中n输入数字(采用任何所需的格式)是。

可以假定它n是一个正整数,也n!就是一个整数。中的小数点后没有零n!。同样,可以假定您的编程语言可以处理nand 的值n!


测试用例

1
==> 0

5
==> 1

100
==> 24

666
==> 165

2016
==> 502

1234567891011121314151617181920
==> 308641972752780328537904295461

这是代码高尔夫。适用标准规则。以字节为单位的最短代码获胜。

意见书

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

# Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以通过打败旧分数保持标题。例如:

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

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

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

您还可以将语言名称设置为链接,然后该链接将显示在页首横幅代码段中:

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

排行榜

这是一个堆栈片段,用于按语言生成常规排行榜和获胜者概述。



我们可以假设n!是否适合我们的语言的本机整数类型?
Alex A.

@AlexA。是的你可以。
Arcturus

可以n是输入字符串吗?
科纳·奥布莱恩

15
我认为这是一个更好的问题,如果您不被允许假设它n!适合您的整数类型!好吧,也许还有一次。
西蒙斯(Simmons)

Answers:


43

Python 2,27字节

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

结束零通过的五因素限制的倍数的数量5是最多nn/5(与地板师),但是这并不在的倍数计算的重复因素25, 125, ...。要得到这些,除以n5并递归。


19

果冻,5 个字节

!Æfċ5

使用适得其反的方法来找到阶乘,然后再次将其分解,在素数分解中检查5的指数。

在线尝试!

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

4
ike。谈论权衡!为了使代码减少到5个字节,请增加内存和时间以荒谬的数量。
罗斯·Presser

19

莫宁顿月牙,1949 1909字节

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字节归功于NieDzejkob


现在,这是我最赞成的答案。
pppery

3
对我们这些受到Mornington Crescent挑战的人做一个简短的解释很酷。:)
罗伯特·本森

-40个字节,并尽可能使用较短的行名。
NieDzejkob

18

Pyth,6个字节

/P.!Q5

在这里尝试。

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

备用7字节

st.u/N5

累积的减少.u/N5重复地被除以5直到被重复为止,在这种情况下,这种减少发生在它达到0之后。

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

然后,第一个元素被删除(t),其余元素相加(s)。


13

其实是10个位元组

!$R;≈$l@l-

在线尝试!

请注意,当在CPython上认真运行时,最后一个测试用例失败,因为math.factorial使用的是C扩展名(限于64位整数)。不过,在PyPy上认真运行可以正常工作。

说明:

!$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)

3
哦,我喜欢这种方法不使用5分法。
Arcturus

我指望这一个12个字节
Score_Under

1
@Score_Under实际上使用CP437代码页,而不是UTF-8。每个字符是一个字节。
Mego

9

Haskell,26个字节

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

按顺序将输入除以5,然后将结果添加到调用的函数上。该表达式(+)=<<f接受输入x和输出x+(f x)

缩短自:

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

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

一个非递归表达式给出28个字节:

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

i柜台1..n吗?
科纳·奥布莱恩

@CᴏɴᴏʀO'Bʀɪᴇɴ是的,尽管只取决于log_5(n)问题,其余部分为0。–
xnor

8

MATL,9个字节

:"@Yf5=vs

在线尝试!

这适用于非常大的数字,因为它避免了计算阶乘。

像其他答案一样,这利用了这样的事实,即因2阶乘除数而出现的次数大于或等于5出现的次数。

:     % 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

6

05AB1E,5个字节

如果我们可以保证n> 4将是4个字节

码:

Î!Ó7è

说明:

Î        # 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

替代的,更快的6字节解决方案:Luis Mendo的MATL答案启发

LÒ€`5QO

说明:

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

编辑:删除的解决方案使用¢(计数),因为所有包含5的素数都将计为5,例如53。

编辑2:添加了更有效的解决方案,以进行更高的输入作为比较。


是的5Q应该工作,而不是。不错的答案!:)
阿德南(Adnan)

我打算在较大的输入上测试“如果输出> 9,这不会失败”,但是男孩05AB1E的实现Ó
Sp3000,2016年

顺便说一句,第一个代码也可以是Î!Ó2é。该错误已于昨天修复。
阿德南

如果您使用的是utf-8,Î!Ó7è则为8字节,“ 6字节”解决方案为10字节
Score_Under

@Score_Under是的,这是正确的。但是,05AB1E使用CP-1252编码。
阿德南

6

Matlab的 (59)(54)(39)

嘿dawg !!!! 我们听说您喜欢数学....

  @(n)sum(fix(n./5.^(1:fix(log(n)/1.6))))
  • 这基于我在代码审查中创建的答案

  • 除了我在代码审查中的答案中提到的以外,阶乘(n)中零的数量的公式为Sum(n /(5 ^ k)),其中k在1和log_5(n)之间变化

  • 它不能使高尔夫球手获得成功的唯一简单原因是log5在matlab中不能作为内置函数使用,因此我用1.6替换了log(5),没关系,因为无论如何它都会被覆盖。

试试看


有几个问题。1.您实际上如何在Matlab中运行它?2. n = 1的结果是什么?
斯图尔特·布鲁夫

@StuartBruff运行此类型ANS(1),它并返回0
Abr001am

好。谢谢。有趣。我在Matlab中没有使用过多的函数句柄,因此对如何运行它感到有些困惑...为什么ans()不计入总数?答案很简单,我在Mathcad中尝试过,但是必须修改总和的上限,因为如果“上限”小于“下限”(因此我的问题是0),则Mathcad会自动减小求和变量。
斯图尔特·布拉夫

5

Mathematica,20个字节

IntegerExponent[#!]&

IntegerExponent计算零。为了好玩,这里有一个不计算阶乘的版本:

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

我认为Array在第二个解决方案上节省了一个字节。
马丁·恩德

5

C,28个字节

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

说明

尾随零的数目等于构成阶乘的五的数目。在所有这些中1..n,有五分之一贡献了五,因此我们从开始n/5。其中n/5,五分之一是25的倍数,因此请多贡献五,依此类推。我们最终f(n) = n/5 + n/25 + n/125 + ...得到的是f(n) = n/5 + f(n/5)。当确实n为零时,我们确实需要终止递归;在加法之前,我们也利用序列点?:进行除法n

另外,此代码比访问每个代码要快得多1..n(并且比计算阶乘快得多)。

测试程序

#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));
    }
}

测试输出

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


+1是一个很好的解释
Titus


4

朱莉娅34 31 30字节

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

这是一个匿名函数,可以接受任何有符号整数类型并返回整数。要调用它,请将其分配给变量。较大的测试用例需要通过n较大的类型,例如BigInt

我们计算的阶乘nprod通常比内置函数短factorial),digits以相反的顺序获得其数组,find非零元素的索引,获得第一个这样的索引,然后减去1。

在线尝试!(包括最后一个测试用例,因为最后一个用时太长,所以包括所有测试用例)

感谢Dennis,节省了一个字节!



3

视网膜,33字节

一元输入。

返回一元输出。

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

(请注意尾随换行符。)

在线尝试!

怎么运行的:

第一阶段:

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

稍微松了一下:

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

它能做什么:

  • 首先,找到11111可以匹配的最大数量。
  • 用该号码代替
  • 有效地除以5
  • 前瞻性(?=1)确保该数字为正。
  • +`重复该方法直到幂等。
  • 因此,第一阶段是“将地板重复除以5”

如果输入为100(一元),则文本为:

;;1111;11111111111111111111

第二阶段:

;

只需删除所有分号即可。


2

Ruby,22个字节

Ruby 0真实的少数情况之一是字节数问题。

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

等等为什么是0真的?
Conor O'Brien

2
@CᴏɴᴏʀO'Bʀɪᴇɴ在Ruby中,nil并且false是falsey,而不是其他的。在很多情况下,高尔夫是有帮助的,因为具有0真实性意味着nil如果没有匹配项而不是,Ruby中的index和regex索引函数会返回-1,而在某些情况下会出现问题,例如空字符串仍然具有真实性。
价值墨水

@ KevinLau-notKenny确实有道理。
科纳·奥布莱恩

2

Perl 6、23个字节

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

如果将它^...添加到Perl 6中, 我可以使它更短一些{sum $_,*div 5^...0}
如果lazysum和序列生成器之间添加了修饰符,则对于较大的数字,应具有更高的内存效率。

说明:

{ # 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
}

测试:

#! /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

(最后一行有些误导,因为MoarVM必须启动,加载Perl 6编译器和运行时,编译代码并运行它。因此,实际上总共花了大约一分半钟。
这仍然比它快得多。是用WolframAlpha.com检查最后一次测试的结果)


2

Mathcad,[tbd]字节

在此处输入图片说明

Mathcad是一种数学上的“白板”,可以二维输入表达式,文本和绘图。它对许多运算使用数学符号,例如求和,微分和积分。编程操作员是特殊符号,通常以标准键上的控制和/或移位的单个键盘组合形式输入。

上面您所看到的正是在键入和Mathcad评估时Mathcad工作表的外观。例如,将n从2016更改为任何其他值将导致Mathcad将结果从502更新为新值。

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


Mathcad的字节等效评分方法尚未确定。等效于一个符号,解决方案大约需要24个“字节”(而while操作符只能使用“ ctl-]”组合键输入(或从工具栏输入)。将Agawa001的Matlab方法转换为Mathcad时,大约需要37个字节(求和运算符由ctl-shft- $输入)。


听起来是个很棒的工具,我不会再花一秒钟的时间下载它了!
2016年

2

dc,12个字节

[5/dd0<f+]sf

这定义了一个函数f,该函数从堆栈顶部消耗其输入,而将其输出保留在堆栈顶部。有关数学基础,请参见我的C答案。我们反复除以5,将值累加到堆栈上,然后将所有结果相加:

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

测试程序

# 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

测试输出

./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  

1

Jolf,13个字节

Ώmf?H+γ/H5ΏγH

定义在输入上调用的递归函数。在这里尝试!

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

1

J,28 17 16字节

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

与xnor的答案中的非递归技术几乎相同。


这是我保留在这里的较旧版本,因为我个人更喜欢它,时钟为28字节:

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

尽管不需要,但x:为了扩大精度,我将这些情况包括在测试用例中。

   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

最后一个数字不适用于此功能。

说明

通过计算n!,将其转换为字符串并与检查每个成员的相等性来工作'0'。对于n = 15,此过程为:

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

现在,我们;._1将列表拆分为其第一个元素(零),将每个拆分结果装箱,产生一个用ace(a:)或1s 填充的框,如下所示:

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

我们简单地获得最后一个成员({:),将其取消装箱(>),然后对其求和+/,得出零的数量。

这是更具可读性的版本:

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'&= @ ": @ ! )

>:@i.可以写1+i.来保存一个字节。
algorithmhark

[:#.~'0'=":@!通过更改对结尾1进行计数的方法,可以将旧版本转换为13个字节。
cole

1

Python 3,52个字节

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

这行不通,请尝试测试用例。
xnor

现在应该可以工作了。
洋红色


1

返回 17个字节

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

Try it here.

递归运算符lambda。用法:

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

说明

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

1

Perl,24 22 +1(-p标志)= 23个字节

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

使用方法:

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

完整程序:

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

1

Java,38个字节

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

完整程序,采用非高尔夫方法:

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));
    }
}

1

J,7个字节

Monadic函数,在右侧接受参数。

3{:@q:!

如果x为正,x q: yy仅对于第一个x素数以的素数分解形式返回指数。3-rd素数是5 {:,位于列表的末尾。

请注意,您必须输入一个x以结尾结尾的整数,否则J会将其视为浮点数。

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

您可以在tryj.tk上尝试一下,但是请注意,如果您尝试尝试的任何大于1343的操作,此在线解释器都会抱怨。

如果您想要不计算n的东西!因此不需要它适合整数,请使用递归解决方案<.@%&5(+$:@)^:*。(tryj.tk对大量输入仍然不满意。)


1

Ruby,70 61 51 49字节

第3版,感谢Kenny Lau和daniero

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

编辑:原来,你可以保存映射两个字节to_i 之前reduce。怪异的

此函数n从中减去基数5 的总和,n然后将结果除以4。这与几何级数的总和有关1+5+25+..+5**n = (5**n+1)/4

例如(再次感谢Kenny Lau),请考虑3582413以5为底)减去5的底数。

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

348通过4,你会得到f(358) = 87

第2版,感谢Kenny Lau

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

n!然后,此函数计算sizeof n!sizeof (n!).reverse.to_i.to_s,从中减去of ,从而删除所有零,从而返回size零本身的of。

版本1

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

这是“ 5的素数分解有n!多少个?”的变体。使用Ruby的简单基本转换内置函数的技巧。

高尔夫球是有点痛的,虽然,从转换IntegerStringArray,抢夺的部分Array和转换,要StringInteger再次为reduce。欢迎任何打高尔夫球的建议。


to_i在减少之前,映射要稍短一些:(->n{(n-n.to_s(5).chars.map(&:to_i).reduce(:+))/4}节省两个字节)
daniero

@daniero我不会期望的。谢谢:D
Sherlock9


1

Dyalog APL,9个字节

⊥⍨'0'=⍕!⎕

提示输入号码

! 析因

串化

'0'= 检查等于零的字符

⊥⍨ 计算尾随真实数*


*从字面上看,这是混合基数到10的转换,同时使用布尔列表作为数字和基数:

⊥⍨0 1 0 1 1与相同0 1 0 1 1⊥⍨0 1 0 1 10×(0×1×0×1×1) 1×(1×0×1×1) 0×(0×1×1) 1×(1×1) + 1×(1)后者又是2(尾随1的数量)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.