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


11

Напишіть програму, яка приймає такі дані, як:

n,k

який потім обчислює:

Поєднання n і k.  (C (n, k))

а потім друкує результат.


Числовий приклад:

Вхід:

5,2

Внутрішні обчислення:

(5!) / (3! X2!)

Друкований вихід:

10

Я хотів би побачити відповідь, яка перемагає моє рішення пітона 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

Пітон: 39

PHP: 62


Функція або повна програма? У вашому описі йдеться про функцію, яка повертає правильний результат, але ваш приклад - це повна програма, яка її друкує.
Вентеро

@ Вентеро Ти правий, я мав на увазі програму. Вибач за те.
backus

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

@Jesse Я отримав цей виклик з іншого веб-сайту, який дозволяє лише основні мови сценаріїв, я буду пам'ятати цю інструкцію в майбутньому. Я відредагував своє запитання, щоб спробувати зробити більш чіткими вимоги до виклику, дайте мені знати, чи достатньо ясне його чи ні.
backus

Я новачок, тому ми майже в одному човні. Однак не підбивайте підсумки; вони просто застаріють. Просто голосуйте і (якщо потрібно) приймайте відповіді. (Також ви змусите людей бути нещасними, якщо без причини проігнорувати відповіді J та GolfScript.)
Jesse Millikan

Відповіді:


11

APL, 3 байти

⎕!⎕

Або для тих, чий браузер не рендерує вище, у вікні ASCII:

{Quad}!{Quad}

3
Щоб повністю відповідати вкладеному документу n,k, вам доведеться це зробити !/⌽⎕.
Марін


10

C 96

За допомогою вводу / виводу (який займає близько 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 n вибрати 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 * * |
|     *      *    \
*/    //       *  */


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 як параметр, щоб отримати останні два елементи.
[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

Пітон (56)

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

Невикольований код і деяке пояснення ярлика для обчислення біноміального коефіцієнта. (Примітка. Існує деяке розуміння, що я просто не зрозумів, щоб перейти до версії 39 char; я не думаю, що такий підхід до вас потрапить.)

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

Не могли б ви надати приклад свого сценарію?
backus

Чи можемо ми використовувати *для розбору входів форми 4545 78?
Кіхот

На жаль, ні, але справа не *в цьому. 4545 78не є дійсним виразом Python, тому input()підніме a SyntaxError. Ця хитрість повністю залежить від заданої проблеми x,y. Якщо у вас була функція, яка читала x yі повертала кортеж, ви могли б використовувати *з цим просто чудово.



3

J, 33 36

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

35 символів - це введення, розбір та вихід. Інший символ !,, n n вибрати k.

Наразі у мене немає Windows для тестування цього, але я вважаю, що це має працювати там.




2

RPL (22)

(не використовується вбудована функція COMB)

→ n k 'n!/(k!*(n-k)!)'

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

Математика 12

Пряма, вбудована функція.

n~Binomial~k

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

Пітон (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

Пітон (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

(ОП лише слабко вказав метод / формат введення та виведення, тому наступне здається прийнятним.)

Шавлія зошит ( 39 41 40)

У поточній комірці

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

де вхід у форму n,kвводиться та оцінюється у попередній комірці. Це імітує "введення командного рядка" шляхом призначення його _(аналогічно аргументам командного рядка).

Мудрець зошита ( 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.

EDIT

Я щойно помітив рішення Арнульда у двох примірниках цього:

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.