不要给我五个!


38

题 :

您将获得序列的开始和结束整数,并应返回其中不包含数字的整数数目5。应该包括开始和结束编号!

例子:

1,9→1,2,3,4,6,7,8,9→结果8

4,17→4,6,7,8,9,10,11,12,13,14,16,17→结果12

50,60→60→结果1

-59,-50→→结果0

结果可能包含五个。

起始编号将始终小于终止编号。两个数字也可以为负!

我对您的解决方案以及解决方案的方式感到非常好奇。也许你们中有人会找到一个简单的纯数学解决方案。

编辑 这是一个代码高尔夫球挑战,因此最短的代码获胜。


3
@betseq:太近了;但这一范围可变(不需要取模)。
泰特斯

4
我建议使用最短的代码作为获胜标准和代码高尔夫标签(我什至没有发现它不是!)。另外,您可能应该放置一个跨越50或500的测试用例;也可能跨度为-50,跨度为0的那一个是个好主意。
乔纳森·艾伦

1
@JonathanAllan:我将更新示例。
Arasuvel '17

4
测试案例:50, 59 -> 0
Zgarb

14
您说:“起始编号将始终小于结束编号。” 但是您的一个示例(-50,-59)直接与此矛盾
theonlygusti

Answers:


21

JavaScript(ES6),36 33字节

使用currying语法进行输入(a)(b)

a=>F=b=>b<a?0:!/5/.test(b)+F(b-1)

格式化和评论

a =>                 // outer function: takes 'a' as argument, returns F
  F = b =>           // inner function F: takes 'b' as argument, returns the final result
    b < a ?          // if b is less than a
      0              //   return 0
    :                // else
      !/5/.test(b) + //   add 1 if the decimal representation of b does not contain any '5'
      F(b - 1)       //   and do a recursive call to F with b - 1

测试用例


(我通常喜欢testexec时,你只需要一个布尔值。)
尼尔

@Neil确实更有意义。更新。
Arnauld

注意:我找不到有关ES6 currying语法的任何技巧,所以我写了一个
Arnauld

5
@TheLethalCoder b<a在计数从b至的所有数字后,会停止递归a,因此删除它只会导致无限递归。
ETHproductions

1
@HristiyanDodov未命名的外部函数将a作为参数和返回F功能,而这又需要b作为参数, -从递归调用迭代-因为你注意到ba,递增计数器对于不包含所有整数5的十进制表示。
Arnauld

17

果冻8 7 字节

多亏了丹尼斯(Dennis),所以-1字节(使用将数字索引为小数列表的事实)

rAw€5¬S

TryItOnline!

怎么样?

rAw€5¬S - Main link: from, to    e.g. -51, -44
r       - range(from, to)        e.g. [-51,-50,-49,-48,-47,-46,-45,-44]
 A      - absolute value         e.g. [51,50,49,48,47,46,45,44]
  w€    - first index of... for €ach (0 if not present)
    5   - five                   e.g. [1,1,0,0,0,0,2,0]
     ¬  - logical not            e.g. [0,0,1,1,1,1,0,1]
      S - sum                    e.g. 5

*绝对值atom A是必需的,因为强制转换为十进制列表的负数具有负数条目,但都不是负数5(给定的示例将全部计数为八个而不是两个)。


rAw€5¬S保存一个字节。
丹尼斯

@丹尼斯,谢谢!我的描述“将该数字作为小数点列表处理”是否正确?
乔纳森·艾伦

2
差不多了 w将整数参数转换为其十进制数字。
丹尼斯


13

2sable6 5字节

多亏了Adnan,节省了一个字节

Ÿ5¢_O

在线尝试!

说明

 Ÿ      # inclusive range
  5¢    # count 5's in each element of the range
    _   # negate
     O  # sum

注意:之所以起作用,是因为在¢使函数将自身应用于每个元素而不是计算列表中的匹配元素时存在错误。


您可以删除,`因为它在数组:p上的行为相同。
阿德南

@Adnan:谢谢!我本来要测试但忘了;)
Emigna

9

Python2,59个 55 52 51 47 43 42字节

f=lambda a,b:a<=b and-(`5`in`a`)-~f(a+1,b)

递归解决方案。感谢@xnor给予我动力来寻找使用逻辑运算符的解决方案!另外,感谢@JonathanAllan@xnor指导我并将字节从43 切成 42!

其他尝试43字节

f=lambda a,b:a<=b and-~-(`5`in`a`)+f(a+1,b)
f=lambda a,b:a<=b and 1-(`5`in`a`)+f(a+1,b)

if!`x`.count('5')工作吗?
泰特斯

2
@Titus Python具有类似C的语言的not运算符!,但是需要3个字节:(
Yytsi

1
考虑使用and和进行逻辑短路or
xnor

1
是的,做得很好!现在考虑缩短时间not
xnor

1
你真的很亲密!继续尝试。
xnor


6

05AB1E8 7 6字节

多亏了Adnan,节省了一个字节

Ÿ5.å_O

在线尝试!

说明

Ÿ         # inclusive range
 5.å      # map 5 in y for each y in the list
    _     # logical negation 
     O    # sum

05AB1E也具有向量化å,即,因此您可以做Ÿ5.å_O6个字节。
阿德南

negate意思-n还是n==0?1:0
ETHproductions

@ETHproductions:对不起,还不清楚。我的意思是逻辑上的否定,所以n==0?1:0
Emigna

6

Pyth,9 8字节

多亏了FryAmTheEggman,节省了一个字节!

lf-\5T}E

说明:

        Q # Input
      }E  # Form an inclusive range starting from another input
          #   order is reversed, but doesn't matter
 f-\5T    # Filter by absence of '5'
l         # Count the number of elements left

在线尝试!


5

Perl 6、23个字节

{+grep {!/5/},$^a..$^b}

在线尝试!

这个怎么运作

{                     }  # A lambda.
              $^a..$^b   # Range between the two lambda arguments.
  grep {!/5/},           # Get those whose string representation doesn't match the regex /5/.
 +                       # Return the size of this list.

5

Haskell,39个字节

s!e=sum[1|x<-[s..e],notElem '5'$show x]

在线尝试!用法:

Prelude> 4 ! 17
12

说明:

             [s..e]                     -- yields the range from s to e inclusive
          x<-[s..e]                     -- for each x in this range
          x<-[s..e],notElem '5'$show x  -- if the char '5' is not in the string representation of x
       [1|x<-[s..e],notElem '5'$show x] -- then add a 1 to the resulting list      
s!e=sum[1|x<-[s..e],notElem '5'$show x] -- take the sum of the list

4

R,33个字节

f=function(x,y)sum(!grepl(5,x:y))

用法:

> f=function(x,y)sum(!grepl(5,x:y))
> f(40,60)
[1] 10
> f(1,9)
[1] 8
> f(4,17)
[1] 12



4

PHP 7.1,57个 55字节

for([,$a,$b]=$argv;$a<=$b;)$n+=!strstr($a++,53);echo$n;

与运行 php -r '<code>' <a> <b>


这不是PHP7.1语法吗?
aross

@aross:是的。但是PHP 7.1的发布时间超过5个小时(12月1日发布
Titus

1
当然,我只是问,因为我习惯于指定版本是7还是更高版本。这也是一种惯例为Python的
aross

1
据我所知,PHP的约定是使用最新版本,除非另有说明。
泰特斯

我认为没有多少人拥有最新的次要版本。目前,最小公分母可能是5.5。我个人使用的是FC 25(被认为是最先进的),目前已分发PHP 7.0。如果您使用的是Windows,则可能需要手动更新。
2015年

4

Mathematica,46 44 42字节

感谢alephalpha和DavidC分别节省了2个字节!

Tr@Boole[FreeQ@5/@IntegerDigits@Range@##]&

带有两个整数参数并返回整数的未命名函数。IntegerDigits@Range@##将输入之间的所有数字转换为数字列表;FreeQ@5测试这些列表,以确定哪些列表不包含任何列表5。然后Boole将布尔值转换为零和一,并对Tr结果求和。

其他解决方案(44和47字节):

Count[Range@##,x_/;IntegerDigits@x~FreeQ~5]&

IntegerDigits@x~FreeQ~5确定一个数字的位数列表是否不含5s,并Count[Range@##,x_/;...]&计算输入之间有多少个数字通过该测试。

Tr[Sign[1##&@@IntegerDigits@#-5]^2&/@Range@##]&

1##&@@IntegerDigits@#-5取一个数字的列表,从所有数字中减去5,然后将答案相乘;Sign[...]^2然后将所有非零数字转换为1。


1
Count[Range@##,x_/;IntegerDigits@x~FreeQ~5]&
DavidC

1
Tr@Boole[FreeQ@5/@IntegerDigits@Range@##]&
alephalpha

3

Ruby,36 35字节

->a,b{(a..b).count{|x|!x.to_s[?5]}}

-1字节的Thx IMP1


1
这不返回不包含数字5而不是列表大小的列表吗?
IMP1

您是对的,我复制/粘贴了错误的版本。
GB

1
您也可以在搜索中使用?5'5'字符)代替/5/以保存字节。
IMP1

3

Java 7,80 78字节

int c(int a,int b){int r=0;for(;a<=b;)r+=(""+a++).contains("5")?0:1;return r;}

取消高尔夫:

int c(int a, int b){
  int r = 0;
  for (; a <= b; ) {
    r += ("" + a++).contains("5")
          ? 0
          : 1;
  }
  return r;
}

测试代码:

在这里尝试。

class M{
  static int c(int a,int b){int r=0;for(;a<=b;)r+=(""+a++).contains("5")?0:1;return r;}

  public static void main(String[] a){
    System.out.println(c(1, 9));
    System.out.println(c(4, 17));
  }
}

输出:

8
12

3

PowerShell,42 41字节

param($a,$b)$a..$b|%{$z+=!($_-match5)};$z

从命令行作为。\ no5s.ps1 1 20调用


1
您可以删除空间以保存一个字节。使用严格的数字正则表达式模式,您不需要定界符(例如-replace3-split1-notmatch5)。
AdmBorkBork

啊,很好,谢谢@AdmBorkBork
mcmurdo

2

Python 2,61 56字节

lambda a,b:len([n for n in range(a,b+1) if not"5"in`n`])

-5字节归功于tukkaaX


不要气aged!重要的是要有乐趣和挑战自己。您可以在not "5" in:: 处删除两个空格。此外,如果您使用的是Python2,则可以x用引号引起来,而不是使用str(x)
Yytsi

@TuukkaX谢谢!还删除了in和`x`之间的空间
sagiksp

您可以删除[]。您也不需要空格if
丹尼斯

@Dennis我已经尝试过了,但是它抱怨“类型为'generator'的对象没有len()”。
Yytsi'1

@TuukkaX对。lambda a,b:sum(not"5"in`n`for n in range(a,b+1))虽然有效。tio.run/nexus/…–
丹尼斯

2

迅捷52字节

($0...$1).filter { !String($0).contains("5") }.count

由于您的挑战是一个代码高尔夫挑战,因此您应该包括您的字节数。另外,在代码高尔夫中(至少在这里),所有程序都必须实际竞争(例如,您的函数名称只能是单个字符,您的实际函数可以简化为一行)。我不了解Swift,您可能需要在某些方面纠正我。
clismique '17

2

批处理,95字节

@set/an=0,i=%1
:g
@if "%i%"=="%i:5=%" set/an+=1
@set/ai+=1
@if %i% leq %2 goto g
@echo %n%

手动循环可以节省一些字节,因为无论如何我都需要在变量中使用循环计数器。


2

PHP,56字节

for($i=$argv[1];$i<=$argv[2];)trim(5,$i++)&&$x++;echo$x;

像这样运行:

php -r 'for($i=$argv[1];$i<=$argv[2];)trim(5,$i++)&&$x++;echo$x;' 1 9 2>/dev/null;echo
> 8

PHP 7.1的版本将为53个字节(记入Titus):

for([,$i,$e]=$argv;$i<=$e;)trim(5,$i++)&&$x++;echo$x;

说明

for(
  $i=$argv[1];          # Set iterator to first input.
  $i<=$argv[2];         # Loop until second input is reached.
)
  trim(5,$i++) && $x++; # Trim string "5" with the characters in the
                        # current number; results in empty string when
                        # `5` is present in the number. If that is not
                        # the case, increment `$x`

echo$x;                 # Output `$x`

阿当,我又忘记了第二个trim参数。
泰特斯

2

CJam“简单的纯数学解决方案”,60

{{Ab5+_,\_5#)<\9e]);_4f>.m9b}%}:F;q~_:z$\:*0>{((+F:-}{F:+)}?

在线尝试

它以数组的任何顺序获取数字。

说明:

一个核心问题是对于任何正数n计算f(n)=从1到n(含)的非5数的数量。答案是:取n的十进制数字,将前5个数字(如果有的话)替换为9,然后将所有数字5..9替换为4..8(减数),然后从9转换为底数。例如1752→ 1759→1648→1 * 9 ^ 3 + 6 * 9 ^ 2 + 4 * 9 + 8 = 1259。基本上,每个数字位置都有9个可接受的值,并且5xxxx等效于49999,因为它们之间没有更多的有效数字。

一旦解决了这个问题,我们就会遇到以下几种情况:如果输入数字(例如a和b,a <b)(严格地)为正,则结果为f(b)-f(a-1)。如果它们是负数,那么我们可以取绝对值,对其重新排序并使用相同的计算。如果a <= 0 <= b,则结果为f(-a)+ f(b)+1。

程序首先实现上述函数F(但应用于数组中的每个数字),然后读取输入,将数字转换为绝对值并对它们重新排序,然后根据是否使用a来使用上述2种计算之一* b> 0最初。


不是“纯”的,而是不错的方法。在这里,获得+1 :)
马修·鲁

@MatthewRoh谢谢,但是你是什么意思不纯呢?该解决方案可以对输入数字进行相当直接的数学计算,而无需遍历范围。您还期待什么?
aditsu

2

Python 2,54个字节

i,j=input();k=0
while i<=j:k+=not"5"in`i`;i+=1
print k

在线尝试!

不是最短的Python答案使用相同的算法,但是使用while循环实现的方法不同,并且不是lambda函数。


它是程序而不是函数,它使用while代替for。有什么不一样的?好的,它仍然在增加的输入中寻找字符串“ 5”,这是同意的。有没有更好的办法?
ElPedro

这就是它的确切含义,这就是它与众不同的原因。抱歉,也许应该让我的评论与众不同。
ElPedro

相同的算法,不同的实现方式。您的评论没问题。措辞更好吗?
ElPedro

是的,是的:)我将删除这些注释,以使注释部分看起来干净。
Yytsi

1

Java 7,77字节

这是对Kevins Answer的改进,但是由于我还没有评论的名声,因此必须使用新的答案。

所以我做的是:

  • indexOfcontains(-1字节)替换语句
  • 将for循环的递增部分移至条件语句(-2个字节)

for循环(77个字节):

int c(int a,int b){int r=1;for(;a++<b;)r+=(""+a).contains("5")?0:1;return r;}

递归(79个字节):

int d(int r,int a,int b){r+=(""+a).contains("5")?0:1;return a!=b?d(r,a+1,b):r;}

输出:

8
12

8
12

在这里测试!


欢迎来到PPCG!在已经非常不错的高尔夫答案中获得了不错的发现。我对Java不太了解,但是不应(""+a).contains("5")?0:1被取代!(""+a).contains("5")吗?
克里斯多夫(Christoph)

1
@Christoph可悲的是没有,因为在Java中,布尔值实际上只是一个布尔值。因此,三元运算是唯一的方法。
Tobias Meister

嗯,这很可悲。那(""+a).contains("5")||r++
克里斯多夫(Christoph)

1
@Christoph也不起作用,因为您不能单独拥有布尔表达式。我一直在尝试使其在其他地方工作(例如for循环声明),但没有取得太大的成功。好主意tho;)
Tobias Meister

1

C#,67个字节

a=>b=>{int c=0;for(;a<=b;)c+=(a+++"").Contains("5")?0:1;return c;};

我希望使用for(int c=0;...)它,但是随后由于无法返回而无法编译c
TheLethalCoder

1

JavaScript(ES6),58 56 49字节

let f =

(s,e)=>{for(c=0;s<=e;)c+=!/5/.test(s++);return c}

console.log(f(1, 9));
console.log(f(4, 17));
console.log(f(-9, -1));

由于ETHproductions,高尔夫球了7个字节。


1
您可以c+=!/5/.test(s++)用来保存一些字节:-)
ETHproductions'Jan

非常感谢!不过,我必须删除高尔夫球。我为他们感到骄傲。:(
Hristiyan Dodov '17

我认为您可以使用currying即`s => e =>`
TheLethalCoder

重要的答案是使用currying语法。我不会编辑我的,因为它将变得几乎一样。不过,感谢您指出这一点!
Hristiyan Dodov '17

1

MATL,10字节

&:!V53-!As

在线尝试!

说明

        % Implicitly grab two input arguments
&:      % Create an array from [input1....input2]
!V      % Convert to a string where each number is it's own row
53-     % Subtract ASCII '5' from each character.
!A      % Detect which rows have no false values (no 5's). Returns a logical array
s       % Sum the logical array to get the # numbers without 5's
        % Implicitly display the result

1

C#,77个字节

(n,m)=>{var g=0;for(var i=n;i<m+1;i++)g+=(i+"").Contains("5")?0:1;return g;};

匿名lambda呼叫。

使用n(第一个数字)和m(最后一个数字)作为输入,然后通过字符串包含("".Contains(""))检查。


我不是一个低调的人,但是5模不是解决OP所提出挑战的正确解决方案。它应该排除数字5中包含数字的任何内容,因此10(您的答案不会计算在内)应计算在内。
凯文·克鲁伊森

@KevinCruijssen固定。
devRicher

它不会编译,g因为它必须被初始化,因为它被命名为var您需要的名称,因此var g="";您可以使用currying即n=>m=>
TheLethalCoder

也会

1
@KevinCruijssen通过您的编辑,这基本上是我的答案...
TheLethalCoder

1

实际上,13个字节

u@x`$'5íuY`░l

在线尝试!

说明:

u@x`$'5íuY`░l
u@x            range(a, b+1)
   `$'5íuY`░   take where:
    $            string representation
     '5íuY       does not contain "5"
            l  length
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.