Математическая комбинация


11

Напишите программу, которая принимает данные, такие как:

n,k

который затем вычисляет:

Сочетание п и к.  (C (n, k))

и затем печатает результат.


Числовой пример:

Входные данные:

5,2

Внутренние вычисления:

(5!) / (3! Х2!)

Печатная продукция:

10

Я хотел бы увидеть ответ, который превосходит мое решение на Python из 65 символов, но все языки, безусловно, приветствуются.

Вот мое решение:

n,k=input();f=lambda x:+(x<2)or x*f(x-1);print f(n)/(f(k)*f(n-k))

Редактировать:

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

Текущие минимальные числа символов по языку:

Perl: 35

Рубин: 36

Python: 39

PHP: 62


Функция или полная программа? В вашем описании написана функция, которая возвращает правильный результат, но ваш пример - полная программа, которая ее печатает.
Вентеро

@ Ventero Вы правы, я имел в виду программу. Прости за это.
Бэкус

3
Как правило, базовые математические концепции не являются хорошими вопросами для игры в гольф, потому что J, APL, Maple, Mathematica и многие другие имеют их встроенные. Кроме того, я должен быть более конкретным в отношении формата ввода и вывода и привести примеры результатов - я не могу скажите, если вы имеете в виду 5 выберите 2 или 2 выберите 5 здесь.
Джесси Милликен

@Jesse Я получил этот вызов с другого сайта, который допускает только основные языки сценариев, я буду помнить это руководство в будущем. Я отредактировал свой вопрос, чтобы попытаться прояснить требования к задаче, дайте мне знать, достаточно ли это ясно или нет.
Бэкус

Я новичок, поэтому мы в одной лодке. Однако не суммируйте результаты; они просто устареют. Просто проголосуйте и (при необходимости) примите ответы. (Кроме того, вы будете расстраивать людей, если будете без причины игнорировать ответы J и GolfScript.)
Джесси Милликен,

Ответы:


11

APL, 3 байта

⎕!⎕

Или для тех, чей браузер не рендерит выше, в рендеринге ASCII:

{Quad}!{Quad}

3
Чтобы быть полностью совместимым с n,kвводом, вы должны сделать !/⌽⎕.
Маринус


10

С 96

С I / O (который занимает около 34 символов). Добавлена ​​пара новых строк, чтобы сделать его читабельным.

main(a,b,c,d){scanf("%d,%d",&a,&b);
d=a-b;for(c=1;a>b;){c*=a--;}for(;d;)
{c/=d--;}printf("%d",c);}

Теперь, если вы меня извините, у меня есть ASCII и я выберу k ракет, чтобы поймать.

    d;main(a
   ,         b
  ,           c
 )  int        a
 ;   {scanf    (
 (   "%d %d"   )
 ,   &a,  &b   )
 ;   d    =a   -
 b   +     b   -
 b   *     1   ;
 a             -
 a  ;for    (  c
 =  1;a>   b   ;
 )  {c=   c    *
 (  (a-- )     )
 ;  }for(      b
 =  b + 1      ;
 d  ;    )     {
 c  =     c    /
 (  d--    )   ;
  }           {
  }           {
   }         (
  printf("%d",c)
 )      ;       }
/*     *  *   * *\
 * * X   * 8 * * |
|     *      *    \
*/    //       *  */

7

GolfScript, 17 символов

Это решение правильно обрабатывает такие случаи, как k = 0 или k = 1.

~>.,,]{1\{)*}/}//

Факториально-подобная часть основана на предыдущем ответе .


6

GolfScript 21

~~)>.,,]{{)}%{*}*}%~/

В частности, в GolfScript отсутствует реальная факториальная функция, однако это, должно быть, самая злая манипуляция с данными, которую я когда-либо делал, это требует трассировки стека:

«5,2» Данные в стеке от ввода.
~Обратите внимание, что команда Eval - это оператор, который превращает число в массив.
[0 1 2 3 4] 2
~Двоичные нет.
[0 1 2 3 4] -3
)Приращение.
[0 1 2 3 4] -2
>Возьмите конец массива, -2 в качестве параметра, чтобы получить последние 2 элемента.
[3 4]
.Двойной элемент.
[3 4] [3 4]
,Длина массива.
[3 4] 2
,Превратить число в массив.
[3 4] [0 1]
]Создать массив.
[[3 4] [0 1]]
{{)}%{*}*}Блок кода.
[[3 4] [0 1]] {{)}% {*} *}
%Выполнить блок один раз для каждого элемента массива. Следующая часть демонстрирует только первый цикл.
[3 4]
{)}%Увеличивать каждый элемент массива.
[4 5]
{*}Блок, содержащий команду умножения.
[4 5] {*}
*«Сложите» массив с помощью команды block, то есть в этом случае создайте произведение всех элементов.
20
После завершения большого цикла он возвращает массив с результатами.
[20 2]
~Разобрать массив.
20 2
/дивизион.
10


6

Рубин 1.9, 52 46 (42) персонажей

eval"A,B="+gets;i=0;p eval"(A-B+i+=1)/i*"*B+?1

Если stderr игнорируется:

eval"A,B=I="+gets;p eval"I/(A-I-=1)*"*B+?1

Ruby 1.8, 43 символа, без дополнительного вывода в stderr:

eval"a,b=i="+gets;p eval"i/(a-i-=1)*"*b+"1"

Редактирование:

  • (52 -> 48) Нашел более короткий способ разбора ввода
  • (48 -> 46) Меньше петли, больше оценки.

4

Python (56)

f=lambda n,k:k<1and 1or f(n-1,k-1)*n/k;print f(*input())

Неуправляемый код и некоторые объяснения ярлыка для вычисления биномиального коэффициента. (Примечание: есть некоторая информация, которую я просто не понял, чтобы перейти к версии с 39 символами; я не думаю, что такой подход приведет вас туда.)

# Since choose(n,k) =
#
#     n!/((n-k)!k!)
#
#          [n(n-1)...(n-k+1)][(n-k)...(1)]
#        = -------------------------------
#            [(n-k)...(1)][k(k-1)...(1)]
#
# We can cancel the terms:
#
#     [(n-k)...(1)]
#
# as they appear both on top and bottom, leaving:
#
#    n (n-1)     (n-k+1)
#    - ----- ... -------
#    k (k-1)       (1)
#
# which we might write as:
#
#      choose(n,k) = 1,                      if k = 0
#                  = (n/k)*choose(n-1, k-1), otherwise
#
def choose(n,k):
    if k < 1:
        return 1
    else:
        return choose(n-1, k-1) * n/k

# input() evaluates the string it reads from stdin, so "5,2" becomes
# (5,2) with no further action required on our part.
#
# In the golfed version, we make use of the `*` unpacking operator, 
# to unpack the tuple returned by input() directly into the arguments
# of f(), without the need for intermediate variables n, k at all.
#
n, k = input()

# This line is left as an exercise to the reader.
print choose(n, k)

Не могли бы вы привести пример своего сценария?
Бэкус

Можем ли мы использовать *для анализа входных данных вида 4545 78?
Quixotic

К сожалению, нет, но дело не *в этом. 4545 78не является допустимым выражением Python, поэтому input()вызовет SyntaxError. Этот трюк целиком и полностью зависит от поставленной задачи x,y. Если бы у вас была функция, которая читала x yи возвращала кортеж, то вы могли бы использовать ее *просто отлично.



3

J, 33 36

(":!~/".;._1}:toJ',',1!:1(3))1!:2(4)

35 символов ввода, анализа и вывода. Другой символ !,, n выбрать k.

На данный момент у меня нет Windows для тестирования, но я считаю, что она должна работать там.





2

Q ( 50 45)

 f:{(prd 1.+til x)%((prd 1.+til y)*prd 1.+til x-y)}

Вы можете сбрить несколько символов из вышеперечисленного, удалив лишние скобки и используя 1 * / вместо prd.

f:{(1*/1.+til x)%(1*/1.+til y)*1*/1.+til x-y}


2

Perl 6 , 25 16 байт

-9 байт благодаря nwellnhof

+*o&combinations

Попробуйте онлайн!

Анонимная функция, которая принимает два числа и возвращает int. Это использует встроенный combinationsи преобразует возвращенный список в int.



@nwellnhof Ах, я не осознавал, что могу combinationsвзять номер вместо списка
Джо Кинг,

1

PHP (71 79 )

<?$a=fgetcsv(STDIN);$x=1;while($a[1]-$i)$x=$x*($a[0]-++$i+1)/$i;echo$x;

<?php $a=fgetcsv(STDIN);$x=1;while(++$i<=$a[1])$x=$x*($a[0]-$i+1)/$i;echo $x?>


1

Python (54)

f=lambda n,k:k<1or f(n-1,k-1)*n/k;print 1*f(*input())

По сути то же самое, что и вышеупомянутый Python, но я сбрасываю четыре байта, опуская

and 1

из определения функции. Однако это приводит к тому, что функция возвращает True вместо 1, если k = 0, но это можно исправить путем умножения на 1 перед печатью, поскольку 1 * True = 1, добавляя, таким образом, два байта.


1

J, 11 символов

!~/".1!:1[1

Принимает ввод с клавиатуры.

    !~/".1!:1[1
5,2
10

0

Хаскелл (80)

f(_,0)=1
f(n,k)=n/k*f(n-1,k-1)
main=getLine>>=putStr.show.f.read.(++")").('(':)

Но если x yразрешен ввод в формате, а не в формате x,y, это 74 символа:

f[_,0]=1
f[n,k]=n/k*f[n-1,k-1]
main=interact$show.f.map read.take 2.words


0

Python (52)

 f=lambda n,k:k<1or f(n-1,k-1)*n/k;print+f(*input())

Улучшение от двух других, используя print+для преобразования результата fот booleanк intв случае k==0.

До сих пор не знаю, как уменьшить его до 39, интересно, используют ли они лямбду вообще.


0

(Оператор OP только слабо определил метод / формат ввода и вывода, поэтому следующее представляется приемлемым.)

Sage Notebook ( 39 41 40)

В текущей ячейке

f=lambda n,k:k<1or f(n-1,k-1)*n/k;+f(*_)

где ввод в форму n,kвводится и оценивается в предыдущей ячейке. Это моделирует «ввод из командной строки», назначая его _(аналогично аргументам командной строки).

Sage Notebook ( 42 44 43)

В качестве альтернативы, используя «ввод из источника» (с x=добавлением к партитуре только символов и новой строки), например,

x=5,2
f=lambda n,k:k<1or f(n-1,k-1)*n/k;+f(*x)

Оба этих подхода, очевидно, являются побочным продуктом более ранних ответов других.



0

Javascript, 27 байт

Сначала мои собственные 35-байтовые решения:

f=(n,k)=>n-k&&k?f(--n,k)+f(n,k-1):1

Или, альтернативно,

f=(n,k,i=k)=>i?f(n-1,k-1,i-1)*n/k:1

Первый работает рекурсивно, с простым (n,k) = (n-1,k) + (n-1,k-1)правилом. Второй использует это (n,k) = (n-1,k-1) * n/k.

РЕДАКТИРОВАТЬ

Я только что заметил решение от Arnould в дубликате этого:

f=(n,k)=>k?n*f(n-1,k-1)/k:1

Что на 8 байтов меньше (27 байтов)


0

TI-BASIC, 16 символов (8 байт)

Ans(1) nCr Ans(2

Вход представляет собой список длиной 2 дюйма Ans.
Выходные данные являются результатом формулы, определенной здесь .

Если вышеуказанного решения недостаточно, то также работает следующее решение 35 символов (24 байта) :

Ans(2)!⁻¹(Ans(1)-Ans(2))!⁻¹Ans(1)!

Примечание: TI-BASIC - это токенизированный язык. Количество символов не равно количеству байтов.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.