По крайней мере ч с по крайней мере ч

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 , если он опубликовал h научных статей, каждая из которых была процитирована в других статьях как минимум h раз. Таким образом, эта задача заключается в вычислении h-индекса из списка счетчиков цитирования.


Обновить

Вау, отличные ответы со всех сторон! Я принял самый короткий вариант, но если кто-то придумает еще более короткий, я соответствующим образом обновлю свой выбор.

Победители по языку

Вот таблица победителей по языкам, которые я также постараюсь держать в курсе. Я включил все посты с неотрицательной оценкой. Пожалуйста, поправьте меня, если я допустил ошибку здесь.

  • APL : 7 байтов @MorisZucca
  • Bash + coreutils : 29 байт от @DigitalTrauma
  • C # : 103 байта от @ LegionMammal978
  • C ++ : 219 байт, @ user9587
  • CJam : 15 байтов @nutki
  • GolfScript : 13 байтов @IlmariKaronen
  • Haskell : 40 байтов @proudhaskeller
  • J : 12 байт от @ ɐɔıʇǝɥʇuʎs
  • Java : 107 байт @Ypnypn
  • JavaScript : 48 байт, @ edc65
  • Mathematica : 38 байтов @ kukac67
  • Perl : 32 байта @nutki
  • Pyth : 10 байтов @isaacg
  • Python : 49 байтов @feersum
  • R : 29 байт @MickyT
  • Рубин : 41 байт @daniero
  • Scala : 62 байта @ChadRetz
  • SQL : 83 байта @MickyT
  • TI-BASIC : 22 байта @Timtech
Zgarb
источник

Ответы:

7

APL 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при добавлении индикатора Booleans, которые рассматриваются как 0или 1.

Для сравнения, итерационный эквивалент на 2 символа длиннее. Требуется Python 2.

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

К сожалению, входные данные должны быть сохранены для переменной перед повторением, иначе Python будет пытаться прочитать входные данные повторно.

XNOR
источник
11

Pyth, 13 10 байт

tf<l-QUTT1

Ввод в форме, такой как [22,33,1,2,4]на STDIN.

Попробуй это здесь.

Как это работает:

-QUTэто все числа на входе ( Q) , по крайней мере , как большой , как число проверяется, T.

<l-QUTTИстинно, если длина этого списка меньше T.

f<l-QUTT1находит первое целое число, которое возвращает true для внутренней проверки, начиная с 1и повышаясь.

tf<l-QUTT1 уменьшает это на единицу, давая наибольшее значение, для которого условие ложно, то есть h-индекс.

Начиная с 1, 0возвращается, когда тест всегда верен, например, в первом тестовом примере.

isaacg
источник
11

Python 2, 49

Ввод должен быть набран в том же формате, что и примеры.

i=0
for z in sorted(input())[::-1]:i+=z>i
print i
feersum
источник
3
Какой удивительный алгоритм!
гордый haskeller
8

CJam, 15 байтов

Прямой перевод моего Perl-решения.

l~{~}${W):W>},,
nutki
источник
4
l~$W%{W):W>},,- 14 байт
оптимизатор
@Optimizer Спасибо, я ожидал, что должен быть короткий способ перевернуть таблицу. Я удивлен тем, что в картах нет доступа к количеству итераций. В любом случае, если вы можете взять 1 байт, это неплохо для моего первого кода CJam.
Nutki
Сейчас есть несколько 12-байтовых решений: {$W%ee::<1b}( eeбыло добавлено 2015-04-17) и {$W%_,,.>1b}( .было добавлено 2015-02-21).
Питер Тейлор
6

J ( 13 12)

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

Очень похоже на решение Рандомры. Демонстрация:

   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
ɐɔıʇǝɥʇuʎs
источник
Использование #\<:вместо i.@#<сохранения персонажа.
алгоритмическая
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
kukac67
источник
@ MartinBüttner Вы правы, я могу использовать #>i++. Я проверил еще несколько случаев. (И спасибо за все предложения!)
kukac67
4

SQL 81 94 83

Учитывая таблицу (I) значений (V), следующий запрос вернет 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 пример

По сути, он нумерует строки в порядке убывания значений. Затем он возвращает максимальный номер строки, где номер строки больше, чем равно значению.

MickyT
источник
Вы можете использовать COUNT(R)вместо COALESCE(MAX(R),0)более короткого решения проблемы NULL.
Nutki
@nutki конечно ... Спасибо
MickyT
4

Р, 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
MickyT
источник
Ницца! Вы можете даже сократить до 29, непосредственно суммируя логический вектор:s=sort(i);sum(s>=length(s):1)
plannapus
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.";

Логика немного отсталая, но она сэкономила пару байтов. По сути, блок, переданный для сортировки, возвращает 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'
nutki
источник
1
sort{$b-$a}сохраняет еще 2
моб
3

Python (63)

В основном прямой порт моего решения J. Очевидно, намного дольше, как можно себе представить.

lambda x:sum(a>b for a,b in zip(sorted(x)[::-1],range(len(x))))
ɐɔıʇǝɥʇuʎs
источник
Вы можете сохранить некоторые символы с помощью enumerate.
xnor
3

Хаскелл, 40

f s=[x-1|x<-[1..],x>sum[1|r<-s,r>=x]]!!0

это ищет первое число, которое не соответствует схеме и возвращает его предшественника.

гордый хаскеллер
источник
39 байт с until: Попробуйте онлайн!
Лайкони
3

Руби 44 41

Рекурсивная, более или менее та же стратегия, что и в решении xnor Python:

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

Ruby 52

Нерекурсивна:

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

«Стабби» лямбда / анонимные функции, требующие Ruby 1.9 или новее. Позвоните, например, сf[[22,33,1,2,4]]

daniero
источник
3

Bash + coreutils, 29

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

Ввод взят из стандартного ввода в виде списка, разделенного новой строкой.

  • 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
edc65
источник
47 байт: f=(l,h=0)=>l.map(v=>x+=v>h,x=0)&&x>h?f(l,h+1):h. Тем не менее, ваше решение будет 47 байт тоже , если вы просто изменить h=-1к h=0.
вругтехагель
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;}
user9587
источник
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

GolfScript, 13 байт

$-1%0\{1$>+}/

Протестируйте этот код онлайн. 1

Принимает ввод как массив в стеке. Использует тот же алгоритм, что и решение Pyers feersum , перебирая числа в массиве и увеличивая счетчик от 0 до тех пор, пока он не станет равным или не превосходит текущий элемент массива.

1) Кажется, что онлайн сервер GolfScript снова испытывает случайные таймауты. Если для программы истекло время ожидания, попробуйте перезапустить ее.

Илмари Каронен
источник
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.

Timtech
источник
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
globby
источник
1

J, 15 11 символов

(Текущее самое короткое J-решение.)

   [:+/#\<:\:~

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

Сравнивает <:отсортированные \:~элементы списка с 1..n + 1 #\и считает истинные сравнения +/.

Проверка сходства с другим J-решением на 100 случайных тестовых случаях:

   */ (([:+/#\<:\:~) = ([:+/i.@#<\:~))"1 ?100 100$100
1
randomra
источник
1

Reng v.3.2, 43 байта

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

Попробуй это здесь! Этот код можно разделить на три части: начальную, вычислительную и конечную.

начальный

1#xk#yaïí'1ø

Это хранит 1до x, длина стека ввода kк y, и получает все входные данные ( aïí) , который затем отсортированные ( '). переходит к следующей строке, т. е. к следующей части.

вычислительный

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

Ренг не имеет встроенного неравенства. Таким образом, алгоритм должен быть реализован. Самый короткий алгоритм, который я нашел, 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) % 1это a/bкогда a < b. Таким образом, это выражение равно a < b.

Тем не менее, это не очень хорошо работает из-за проблем с модулем с нуля. Итак, мы изначально увеличиваем каждый элемент стека и счетчик.

После того, как мы получаем неравенство Boolean в стеке, 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;
    }
}
LegionMammal978
источник
0

Скала, 62

def h(a:Int*)=Range(a.size,-1,-1).find(b=>a.count(b<=)>=b).get
Чад Рец
источник