至少h与至少h


42

输入项

非负整数列表。

输出量

最大的非负整数h,使得h列表中的至少一个数字大于或等于h

测试用例

[0,0,0,0] -> 0
[12,312,33,12] -> 4
[1,2,3,4,5,6,7] -> 4
[22,33,1,2,4] -> 3
[1000,2,2,2] -> 2
[23,42,12,92,39,46,23,56,31,12,43,23,54,23,56,73,35,73,42,12,10,15,35,23,12,42] -> 20

规则

您可以编写完整的程序或函数,也可以使用匿名函数。这是代码高尔夫球,因此最少的字节数获胜。不允许出现标准漏洞。

背景

h指数是在学术界使用的概念,其目的是捕捉研究员的影响和生产力。根据Wikipedia的说法,如果研究人员已发表h条科学文章,则该文章的索引为h,其中每篇科学文章均被h引用至少h次。因此,这个挑战是关于从引用计数列表中计算h指数。


更新资料

哇,好极了!我接受了最短的一个,但是如果有人提出一个更短的一个,我将相应地更新我的选择。

语言获胜者

这是按语言划分的获奖者名单,我还将尝试保持最新状态。我包括了所有分数均为非负数的帖子。如果我在这里犯了一个错误,请纠正我。

  • APL:@MorisZucca提供的7个字节
  • Bash + coreutils:29个字节,@ DigitalTrauma
  • C#:@ LegionMammal978的103个字节
  • C ++:@ user9587的219字节
  • CJam@nutki提供 15个字节
  • GolfScript@IlmariKaronen提供的 13个字节
  • Haskell:@proudhaskeller提供的40个字节
  • J:@ɐɔıʇǝɥʇuʎs提供的12个字节
  • Java:@Ypnypn的107个字节
  • JavaScript:@ edc65提供的48个字节
  • Mathematica:@ kukac67提供的38个字节
  • Perl:@nutki的32个字节
  • Pyth@isaacg提供的 10个字节
  • Python:@feersum的49个字节
  • R:@MickyT的29个字节
  • Ruby:@daniero提供的41个字节
  • Scala:@ChadRetz的62个字节
  • SQL:@MickyT的83个字节
  • TI-BASIC:@Timtech提供的22个字节

Answers:


7

杀伤人员地雷7

+/⊢≥⍋∘⍒

可以在tryapl.org上在线尝试

f←+/⊢≥⍋∘⍒
f¨(4⍴0)(12 312 33 12)(⍳7)(22 33 1 2 4)(1000 2 2 2)(23 42 12 92 39 46 23 56 31 12 43 23 54 23 56 73 35 73 42 12 10 15 35 23 12 42)
0 4 4 3 2 20

11

Python,52岁

f=lambda s,n=0:n<sum(n<x for x in s)and f(s,n+1)or n

递归解决方案。如果您担心溢出,请在Stackless Python中运行此代码

从开始n=0,检查至少n+1数量是否至少n+1。如果是这样,则递增n并重新开始。如果不是,则输出n

条件是使用Python对布尔值的短路来完成的。该表达式sum(n<x for x in s)计算的值的数量s大于n通过添加指示符Boolean(被视为0或)的数量1

为了进行比较,迭代等效项要长2个字符。它需要Python 2。

s=input()
n=0
while n<sum(n<x for x in s):n+=1
print n

不幸的是,在迭代之前需要将输入保存为变量,否则Python将尝试重复读取输入。


11

Pyth,13个10字节

tf<l-QUTT1

以诸如[22,33,1,2,4]在STDIN上的形式输入。

在这里尝试。

这个怎么运作:

-QUT是输入(Q)中的所有数字至少与要检查的数字一样大T

<l-QUTT如果该列表的长度小于,则为true T

f<l-QUTT1查找第一个整数,该整数对内部检查从true开始1并向上返回。

tf<l-QUTT1 将其减一,得到条件为假的最大值,即h索引。

从1开始确保0在测试始终为真时(例如在第一个测试用例中)返回该值。



8

CJam,15个字节

我的Perl解决方案的直接翻译。

l~{~}${W):W>},,

4
l~$W%{W):W>},,- 14个字节
优化

@Optimizer谢谢,我希望应该有一个简短的方法来反转表格。我很惊讶,尽管无法访问地图中的迭代计数。无论如何,如果只剩下1个字节,那对于我的第一个CJam代码来说还不错。
nutki 2014年

有一些12字节的解决方案现在:{$W%ee::<1b}ee加入2015年4月17日)和{$W%_,,.>1b}.加入2015年2月21日)。
彼得·泰勒

6

J(13 12)

[:+/i.@#<\:~

非常类似于randomra的解决方案。示范:

   f=:[:+/i.@:#<\:~
   f 0,0,0,0
0
   f 12,312,33,12
4
   f 1,2,3,4,5,6,7
4
   f 22,33,1,2,4
3
   f 1000,2,2,2
2
   f 23,42,12,92,39,46,23,56,31,12,43,23,54,23,56,73,35,73,42,12,10,15,35,23,12,42
20

使用#\<:代替i.@#<保存字符。
algorithmhark

5

Mathematica,44 42 40 38个字节

匿名函数:

LengthWhile[i=0;SortBy[#,-#&],#>i++&]&

通过将输入固定在末尾来运行它,如下所示:

In: LengthWhile[i=0;SortBy[#,-#&],#>i++&]&@{1,2,3,4,5,6,7}
Out: 4

@MartinBüttner是的,我可以使用#>i++。我测试了更多案例。(感谢所有建议!)
kukac67

4

SQL,81 94 83

给定值(V)的表(I),以下查询将返回h。经过PostgreSQL测试,也可以在SQL Server中使用。 编辑使其返回0而不是NULL。用COUNT做得更好,谢谢@nutki

SELECT COUNT(R)FROM(SELECT ROW_NUMBER()OVER(ORDER BY V DESC)R,V FROM I)A WHERE R<=V

SQLFiddle示例

本质上,它按降序排列数值。然后,它返回最大行号,其中行号大于等于该值。


您可以使用COUNT(R)而不是对COALESCE(MAX(R),0)NULL问题进行更简短的修复。
nutki 2014年

@nutki当然... ...谢谢
MickyT 2014年

4

R,39 35 29

s=sort(i);sum(s>=length(s):1)

给定i中的整数向量,并使用反向排序的逻辑,然后返回向量的长度,其中元素编号小于s。感谢@plannapus的提示。

> i=c(23,42,12,92,39,46,23,56,31,12,43,23,54,23,56,73,35,73,42,12,10,15,35,23,12,42)
> s=sort(i);length(s[s>=length(s):1])
[1] 20
> i=c(0,0,0,0)
> s=sort(i);length(s[s>=length(s):1])
[1] 0

真好!您甚至可以通过直接求和逻辑向量来缩短为29:s=sort(i);sum(s>=length(s):1)
plannapus 2014年

3

CJam,23个字节

l~:I,),W%{_If>:!:+>}$0=

这会将列表作为STDIN上的数组,例如

[23 42 12 92 39 46 23 56 31 12 43 23 54 23 56 73 35 73 42 12 10 15 35 23 12 42]

在这里测试。

您可以使用它来运行所有测试用例:

[0 0 0 0]
[12 312 33 12]
[1 2 3 4 5 6 7]
[22 33 1 2 4]
[1000 2 2 2]
[23 42 12 92 39 46 23 56 31 12 43 23 54 23 56 73 35 73 42 12 10 15 35 23 12 42]]
{:I,),W%{_If>:!:+>}$0=N}/

说明

l~:I,),W%{_If>:!:+>}$0=
l~:I                    "Read input, evaluate, store in I.";
    ,                   "Get length of input N.";
     ),W%               "Create range from 0 to N, reverse.";
         {         }$   "Sort stably.";
          _I            "Duplicate candidate h, push input list.";
            f>          "Map each number to 1 if it's less or 0 otherwise.";
              :!        "Invert all results.";
                :+      "Sum them up.";
                  >     "Check if the sum is less than the candidate h.";
                     0= "Pick the first element.";

逻辑有些倒退,但是节省了几个字节。基本上,传递给sort的块返回0有效候选者,1否则返回。因此,有效候选者在排序数组中排在第一位。并且由于排序是稳定的,并且我们从N到1的列表开始,因此将返回最大的有效h。


3

Perl 5:32(对于则为30 + 2 -pa

#!perl -pa
$_=grep$_>$i++,sort{$b<=>$a}@F

在STDIN上使用空格分隔的输入:

perl hidx.pl <<<'1 2 3 4 5 6 7'

1
sort{$b-$a}保存2多
暴民2014年

3

巨蟒(63)

基本上是我的J解决方案的直接端口。显然,更长的时间,就像人们可能想像的那样。

lambda x:sum(a>b for a,b in zip(sorted(x)[::-1],range(len(x))))

您可以使用来保存一些字符enumerate
xnor 2014年


3

红宝石44 41

递归,与xnor的Python解决方案大致相同的策略:

f=->a,n=0{a.count{|x|x>n}<n+1?n:f[a,n+1]}

红宝石52

非递归:

f=->a{a.size.downto(0).find{|x|a.count{|y|y>=x}>=x}}

“稳定” lambda /匿名函数,需要Ruby 1.9或更高版本。用例如致电f[[22,33,1,2,4]]


3

Bash + coreutils,29岁

sort -nr|nl -s\>|bc|grep -c 0

来自stdin的输入作为换行符分隔的列表。

  • sort 整数按降序排列
  • nl 每行以其从1开始的行号作为前缀,将行号与行的其余部分用大于号分隔 >
  • 用算术评估每行bc。小于其行号的整数将得出0。否则为1。
  • grep计算0s 的数量,即大于或等于的整数的数量h

$ for i in {23,42,12,92,39,46,23,56,31,12,43,23,54,23,56,73,35,73,42,12,10,15,35,23,12,42}; do echo $i; done | ./atleasth.sh
20
$ for i in {1,2,3,4,5,6,7}; do echo $i; done | ./atleasth.sh
4
$ 

2

JavaScript(ES6)48

递归解决方案。

F=(l,h=-1)=>l.filter(v=>v>h).length>h?F(l,h+1):h

在FireFox / FireBug控制台中测试

;[
  [0,0,0,0],
  [12,312,33,12],
  [1,2,3,4,5,6,7],
  [22,33,1,2,4],
  [1000,2,2,2],
  [23,42,12,92,39,46,23,56,31,12,43,23,54,23,56,73,35,73,42,12,10,15,35,23,12,42]
 ].forEach(l=>console.log(l,F(l)))

输出量

[0, 0, 0, 0] 0
[12, 312, 33, 12] 4
[1, 2, 3, 4, 5, 6, 7] 4
[22, 33, 1, 2, 4] 3
[1000, 2, 2, 2] 2
[23, 42, 12, 92, 39, 46, 23, 56, 31, 12, 43, 23, 54, 23, 56, 73, 35, 73, 42, 12, 10, 15, 35, 23, 12, 42] 20

47个字节:f=(l,h=0)=>l.map(v=>x+=v>h,x=0)&&x>h?f(l,h+1):h。然而,你的解决方案将是47个字节太多,如果你只是改变h=-1h=0
vrugtehagel

2

Java 8,116字节。

全班:

import java.util.*;
import java.util.stream.*;

class H{

    public static void main(String[]a){
        System.out.println(new H().f(Stream.of(a[0].split(",")).mapToInt(Integer::parseInt).toArray()));
    }

    int i;

    int f(int[]n){
        Arrays.sort(n);
        i=n.length;
        Arrays.stream(n).forEach(a->i-=a<i?1:0);
        return i;
    }
}

功能:

import java.util.*;int i;int f(int[]n){Arrays.sort(n);i=n.length;Arrays.stream(n).forEach(a->i-=a<i?1:0);return i;}}


2

C ++ 815 219从(WC -c main.cpp中)

好吧,这是我写过的最糟糕的代码!:)

#include <iostream>
#include <list>
using namespace std;int main(int c,char** v){list<int>n(--c);int h=c;for(int&m:n)m=atoi(*(v+(h--)));n.sort();for(auto r=n.rbegin();r!=n.rend()&&*r++>++h;);cout<<(h==c?h:--h)<<endl;}

2

果冻,6个字节

NỤỤ<’S

说明:

N           Negate (so that repeated elements won't mess up the second grade down)
 Ụ          Grade down
  Ụ         Twice.
   <’       Predicate, check for each element if the new one (after grading) is lower than original array (minus 1 on each element)
     S      Sum

1

CJam,22个字节

q~:Q,),{Q{1$>},,>!},W=

将列表作为输入:

[23 42 12 92 39 46 23 56 31 12 43 23  54 23 56 73 35 73 42 12 10 15 35 23 12 42]

输出:

20

在这里尝试



1

TI-BASIC,22字节

ASCII表示形式:

Input L1:1:While Ans≤sum(Ans≥L1:Ans+1:End:Ans

十六进制转储:

DC 5D 00 3E 31 3E D1 72 6D B6 72 6C 5D 00 3E 72 70 31 3E D4 3E 72

获取列表作为输入。从Ans = 0开始,检查数字中至少Ans + 1是否至少为Ans + 1。如果是这样,则递增Ans并再次循环。如果不是,则输出Ans。


1

JAGL Alpha 1.2-14

不算数,因为在问题之后添加了“ C”反向数组功能,但无论如何还是很有趣。

假定数组是堆栈中的第一项,并将答案放在堆栈的顶部。

0SJC{Sd@>+1}/S

要打印,只需P在末尾添加一个字节即可。

说明:

0               Push the number 0 (the counter)
 SJC            Swap to array, sort and reverse
    {Sd@>+1}/   For each item in the array, add 1 to counter if counter is less than item
             S  Swap counter to top of stack

1

J,15个 11个字符

(当前最短的J解决方案。)

   [:+/#\<:\:~

   ([:+/#\<:\:~) 1 2 3 4 5 6 7
4

用1..n + 1 比较<:排序的列表\:~元素,#\并计算真实比较+/

在100个随机测试用例上测试与其他J解决方案的相似性:

   */ (([:+/#\<:\:~) = ([:+/i.@#<\:~))"1 ?100 100$100
1

1

Reng v.3.2,43个字节

1#xk#yaïí'1ø ~n-1$\
1+)x(%:1,%1ex+y1-?^#y#x

在这里尝试!该代码可以分为三个部分:初始,计算和最终。

初始

1#xk#yaïí'1ø

此存储1x,输入堆栈的长度ky,并得到所有输入(aïí),然后将其排序(')。转到下一行,即下一部分。

计算的

1+)x(%:1,%1ex+y1-?^#y#x

Reng没有内在的不平等。因此,必须实现一种算法。我找到的最短算法a < b%:1,%1e;看起来像这样:

Command | Stack
  ---   | a, b
   %    | a/b
   :    | a/b, a/b
   1    | a/b, a/b, 1
   ,    | a/b, (a/b)%1
   e    | (a/b) == ((a/b)%1)

我确定可以清除!让我进一步解释。x % 1,即模数为1的映射x(-1,1)。我们知道那(a/b) % 1a/b什么时候a < b。因此,该表达式等于a < b

但是,由于模数为零的问题,因此效果不佳。因此,我们首先增加堆栈的每个成员和计数器。

在堆栈上获得不等式布尔值之后,x+将其添加到x中,但暂时将其保留在堆栈上。y1-递减y,然后?^增加,y == 0然后我们进入最后阶段。否则,我们把y-1进入y和新x进入x

最后

             ~n-1$\

y-1将从堆栈中弹出残差,减少结果,输出结果,然后结束程序。



0

Mathematica,57个字节

FirstCase[Range[Length@#,0,-1],h_/;Count[#,k_/;k>=h]>=h]&

这是一个匿名函数,它获取一个列表并返回一个整数,例如

FirstCase[Range[Length@#,0,-1],h_/;Count[#,k_/;k>=h]>=h]&@{1,2,3,4,5,6,7}

使用它来检查所有测试用例:

FirstCase[Range[Length@#,0,-1],h_/;Count[#,k_/;k>=h]>=h]& /@ {
  {0, 0, 0, 0},
  {12, 312, 33, 12},
  {1, 2, 3, 4, 5, 6, 7},
  {22, 33, 1, 2, 4},
  {1000, 2, 2, 2},
  {23, 42, 12, 92, 39, 46, 23, 56, 31, 12, 43, 23, 54, 23, 56, 73, 35,
    73, 42, 12, 10, 15, 35, 23, 12, 42}
}

0

C#,103

匿名函数。

a=>{try{return a.OrderBy(b=>-b).Select((b,c)=>new{b,c}).First(b=>b.b<b.c+1).c;}catch{return a.Length;}}

缩进:

a =>
{
    try
    {
        return a.OrderBy(b => -b).Select((b, c) => new { b, c }).First(b => b.b < b.c + 1);
    }
    catch
    {
        return a.Length;
    }
}

0

斯卡拉,62岁

def h(a:Int*)=Range(a.size,-1,-1).find(b=>a.count(b<=)>=b).get
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.