Kombinacja matematyczna

11

Napisz program, który pobiera dane wejściowe, takie jak:

n,k

który następnie oblicza:

Kombinacja n i k.  (C (n, k))

a następnie drukuje wynik.


Numeryczny przykład:

Wejście:

5,2

Obliczenia wewnętrzne:

(5!) / (3! X2!)

Wydruk:

10

Chciałbym zobaczyć odpowiedź, która przewyższa moje rozwiązanie pythonowe składające się z 65 znaków, ale wszystkie języki są oczywiście mile widziane.

Oto moje rozwiązanie:

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

Edytować:

Przyznaję, że to pytanie pochodzi ze strony matematycznej kombinacji łamigłówek na stronie codegolf . Wiem, że moja odpowiedź może wyglądać na niewielki postęp, ale przywódcy tej układanki rozwiązali ją u prawie połowy postaci.

Obecnie najniższa liczba znaków według języka to:

Perl: 35

Rubin: 36

Python: 39

PHP: 62

backus
źródło
Funkcja czy pełny program? Twój opis mówi funkcję, która zwraca poprawny wynik, ale twój przykład to pełny program, który go drukuje.
Ventero
@Ventero Masz rację, miałem na myśli program. Przepraszam za to.
wstecz
3
Ogólnie rzecz biorąc, podstawowe pojęcia matematyczne nie są świetnymi pytaniami golfowymi, ponieważ J, APL, Maple, Mathematica i wiele innych będą je miały wbudowane. Ponadto, bardziej szczegółowo określaj format wejściowy i wyjściowy oraz podaj przykładowe wyniki - nie mogę powiedz, jeśli masz na myśli 5, wybierz 2 lub 2, wybierz 5 tutaj.
Jesse Millikan
@Jesse Dostałem to wyzwanie z innej strony internetowej, która dopuszcza tylko główne języki skryptowe, zapamiętam te wytyczne w przyszłości. Zredagowałem swoje pytanie, aby wyjaśnić wymagania dotyczące wyzwania, daj mi znać, czy jest wystarczająco jasne, czy nie.
backus
Jestem nowy, więc jesteśmy na tej samej łodzi. Nie podsumowuj jednak wyników; po prostu się zdezaktualizują. Po prostu głosuj i (w razie potrzeby) akceptuj odpowiedzi. (Ponadto sprawisz, że ludzie będą niezadowoleni, jeśli zignorujesz odpowiedzi J i GolfScript bez powodu.)
Jesse Millikan,

Odpowiedzi:

11

APL, 3 bajty

⎕!⎕

Lub dla tych, których przeglądarka nie wyświetla powyższego, w renderowaniu ASCII:

{Quad}!{Quad}
jpjacobs
źródło
3
n,kMusisz być w pełni zgodny z danymi wejściowymi !/⌽⎕.
marinus,
10

R (11 znaków)

choose(n,r)
skeevey
źródło
10

C 96

Z I / O (co zajmuje około 34 znaków). Dodano kilka nowych linii, aby była czytelna.

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);}

Teraz, przepraszam, mam ASCII i wybieram rakietę do złapania.

    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 * * |
|     *      *    \
*/    //       *  */
walpen
źródło
7

GolfScript, 17 znaków

To rozwiązanie poprawnie obsługuje przypadki takie jak k = 0 lub k = 1.

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

Część przypominająca czynnik jest oparta na poprzedniej odpowiedzi .

Nabb
źródło
6

GolfScript 21

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

Niezbyt krótki, GolfScript nie ma prawdziwej funkcji silni, ale musi to być najbardziej nikczemna manipulacja danymi, jaką kiedykolwiek zrobiłem, wymaga to śledzenia stosu:

„5,2” Dane na stosie z danych wejściowych.
~Zauważ, że polecenie Eval to operator, który przekształca liczbę w tablicę.
[0 1 2 3 4] 2
~Nie binarne.
[0 1 2 3 4] -3
)Przyrost.
[0 1 2 3 4] -2
>Weź koniec tablicy, -2 jako parametr, aby uzyskać ostatnie 2 elementy.
[3 4]
.Duplikat elementu.
[3 4] [3 4]
,Długość tablicy.
[3 4] 2
,Zmień liczbę na tablicę.
[3 4] [0 1]
]Utwórz tablicę.
[[3 4] [0 1]]
{{)}%{*}*}Blok kodu.
[[3 4] [0 1]] {{)}% {*} *}
%Wykonaj blok raz dla każdego elementu tablicy. Poniższa część pokazuje tylko pierwszą pętlę.
[3 4]
{)}%Zwiększ każdy element tablicy.
[4 5]
{*}Blok zawierający polecenie mnożenia.
[4 5] {*}
*„Złóż” tablicę za pomocą polecenia blokowania, czyli w tym przypadku wykonaj iloczyn wszystkich elementów.
20
Po zakończeniu dużej pętli zwraca tablicę z wynikami.
[20 2]
~Dekonstruuj tablicę.
20 2
/Division.
10

aaaaaaaaaaaa
źródło
6

Ruby 1.9, 52 46 (42) znaków

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

Jeśli stderr jest ignorowany:

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

Ruby 1.8, 43 znaki, bez dodatkowych danych wyjściowych do stderr:

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

Edycje:

  • (52 -> 48) Znaleziono krótszy sposób na analizę danych wejściowych
  • (48 -> 46) Mniej zapętleń, więcej ewaluacji.
Ventero
źródło
4

Python (56)

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

Nieskluczony kod i wyjaśnienie skrótu do obliczania współczynnika dwumianowego. (Uwaga: Jest pewien wgląd, którego po prostu nie rozgryzłem, aby przejść do wersji 39 znaków; nie sądzę, że to podejście cię tam zaprowadzi.)

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

źródło
Czy możesz podać nieskrępowany przykład swojego skryptu?
backus
Czy możemy używać *do analizowania danych wejściowych formularza 4545 78?
Quixotic
Niestety nie, ale nie *o to chodzi. 4545 78nie jest prawidłowym wyrażeniem w języku Python, więc input()podniesie SyntaxError. Ta sztuczka zależy całkowicie od problemu x,y. Jeśli masz funkcję, która odczytuje x yi zwraca krotkę, możesz *z nią dobrze korzystać.
4

RPL (4)

(za pomocą wbudowanej funkcji)

COMB
oliver
źródło
3

Windows PowerShell, 57

$a,$b=iex $input
$p=1
for($a-=$b;$a-ge1){$p*=1+$b/$a--}$p
Joey
źródło
3

J, 33 36

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

35 znaków jest wprowadzanych, analizowanych i wysyłanych. Drugim znakiem !jest n i wybierz k.

Obecnie nie mam systemu Windows do testowania tego, ale uważam, że powinien tam działać.

Jesse Millikan
źródło
3

Q, 32 znaki

{f:{1*/1.+(!)x};f[x]%f[y]*f x-y}
tartin
źródło
2

Perl 6 (55)

my ($a,$b)=lines;$_=1;for 1..$a-$b {$_+=$_*$b/$^a};.say
Ming-Tang
źródło
2

RPL (22)

(nie używa wbudowanej funkcji COMB)

→ n k 'n!/(k!*(n-k)!)'
oliver
źródło
2

Q ( 50 45)

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

Możesz ogolić kilka znaków powyżej, usuwając zbędne nawiasy i używając 1 * / zamiast prd.

f:{(1*/1.+til x)%(1*/1.+til y)*1*/1.+til x-y}
sinedcm
źródło
2

Matematyka 12

Prosta, wbudowana funkcja.

n~Binomial~k
DavidC
źródło
2

Perl 6 , 25 16 bajtów

-9 bajtów dzięki nwellnhof

+*o&combinations

Wypróbuj online!

Anonimowa funkcja, która pobiera dwie liczby i zwraca liczbę całkowitą. Korzysta z wbudowanego combinationsi konwertuje zwróconą listę na int.

Jo King
źródło
16 bajtów
nwellnhof,
@nwellnhof Ah, nie zdawałem sobie sprawy, że combinationsmożna wziąć numer zamiast listy
Jo King,
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?>

mellamokb
źródło
1

Python (54)

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

Zasadniczo taki sam jak powyższy Python, ale golę cztery bajty, upuszczając plik

and 1

z definicji funkcji. Powoduje to jednak, że funkcja zwraca True zamiast 1, jeśli k = 0, ale można to naprawić mnożąc przez 1 przed drukowaniem, ponieważ 1 * True = 1, dodając w ten sposób dwa bajty.

Słup
źródło
1

J, 11 znaków

!~/".1!:1[1

Pobiera dane z klawiatury.

    !~/".1!:1[1
5,2
10
Gareth
źródło
0

Haskell (80)

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

Ale jeśli x ydozwolone jest wprowadzanie danych w formacie zamiast w formacie x,y, to 74 znaki:

f[_,0]=1
f[n,k]=n/k*f[n-1,k-1]
main=interact$show.f.map read.take 2.words
marinus
źródło
0

Scala 54

val n,k=readInt
((k+1)to n product)/(1 to(n-k)product)
nieznany użytkownik
źródło
0

Python (52)

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

Ulepszony od pozostałych dwóch poprzez print+konwersję wyniku fz booleanna intna skrzynkę k==0.

Nadal nie mam pojęcia, jak zmniejszyć go do 39, zastanawiam się, czy w ogóle używają lambda.

Andrea Ambu
źródło
0

(OP tylko luźno określił metodę / format wejścia i wyjścia, więc następujące wydaje się dopuszczalne.)

Sage Notebook ( 39 41 40)

W bieżącej komórce

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

gdzie dane wejściowe w formularzu n,ksą wprowadzane i oceniane w poprzedniej komórce. Symuluje to „dane wejściowe z wiersza poleceń”, przypisując je _(podobnie jak argumenty wiersza poleceń).

Sage Notebook ( 42 44 43)

Alternatywnie, używając „danych wejściowych” (z x=dodanymi tylko znakami i znakiem nowej linii do wyniku), np.

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

Oba te podejścia są oczywiście pochodnymi wcześniejszych odpowiedzi innych osób.

res
źródło
0

Tcl , 80 bajtów

proc C n\ k {proc f n {expr $n?($n)*\[f $n-1]:1}
expr [f $n]/([f $k]*[f $n-$k])}

Wypróbuj online!

sergiol
źródło
Bardzo niegrzeczne podejście, 165 bajtów: tio.run/…
sergiol
0

JavaScript, 27 bajtów

Najpierw moje własne 35-bajtowe rozwiązania:

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

Lub alternatywnie

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

Pierwszy działa rekurencyjnie, z prostą (n,k) = (n-1,k) + (n-1,k-1)regułą. Drugi używa tego (n,k) = (n-1,k-1) * n/k.

EDYTOWAĆ

Właśnie zauważyłem rozwiązanie Arnoulda w duplikacie tego:

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

Co oznacza o 8 bajtów mniej (27 bajtów)

vrugtehagel
źródło
0

TI-BASIC, 16 znaków (8 bajtów)

Ans(1) nCr Ans(2

Dane wejściowe to lista o długości 2 cali Ans.
Dane wyjściowe są wynikiem zdefiniowanej tutaj formuły .

Jeśli powyższe rozwiązanie nie wystarczy, działają również następujące 35 znaków (24 bajty) :

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

Uwaga: TI-BASIC jest językiem tokenizowanym. Liczba znaków nie jest równa liczbie bajtów.

Tau
źródło