Matematiksel Kombinasyon


11

Aşağıdaki gibi bir girdi alan bir program yazın:

n,k

sonra hesaplar:

N ve k kombinasyonu.  (C (n, k))

ve ardından sonucu yazdırır.


Sayısal bir örnek:

Giriş:

5,2

İç hesaplama:

(5!) / (3! X2!)

Yazdırılan Çıktı:

10

65 karakterlik python çözümümü yenen bir cevap görmek istiyorum, ancak tüm diller açıktır.

İşte benim çözümüm:

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

Düzenle:

Bu sorunun codegolf web sitesi matematik kombinasyonu bulmaca olduğunu itiraf ediyorum . Cevabımın çok fazla ilerleme kaydedilemeyebileceğini biliyorum, ancak bu bulmacanın liderleri bunu yaklaşık yarım karakterle çözdü.

Dile göre geçerli en düşük karakter sayısı:

Perl: 35

Yakut: 36

Python: 39

PHP: 62


İşlev veya tam program? Açıklamanız doğru sonucu döndüren işlevi söylüyor, ancak örneğiniz bunu yazdıran tam bir programdır.
Ventero

@Ventero Haklısın Program demek istedim. Bunun için üzgünüm.
backus

3
Genellikle, temel matematik kavramları golf soruları değildir çünkü J, APL, Maple, Mathematica ve daha pek çoğu bunları yerleşik hale getirecektir. 5'i 2 veya 2'yi seçin, burada 5'i seçin.
Jesse Millikan

@Jesse Bu zorluğu sadece büyük betik dillerine izin veren başka bir web sitesinden aldım, gelecekte bu kılavuzu hatırlayacağım. Zorluk gereksinimlerini daha net hale getirmek için sorumu düzenledim, yeterince açık olup olmadığını bana bildirin.
backus

Ben yeniyim, bu yüzden aynı gemideyiz. Ancak, sonuçları özetlemeyin; sadece eskimiş olacaklar. Sadece oy verin ve (uygunsa) cevapları kabul edin. (Ayrıca, J ve GolfScript cevaplarını bir sebep olmadan görmezden gelirseniz insanları mutsuz edersiniz.)
Jesse Millikan

Yanıtlar:


11

APL, 3 bayt

⎕!⎕

Veya bir ASCII oluşturma işleminde tarayıcısı yukarıdakileri oluşturmayanlar için:

{Quad}!{Quad}

3
n,kGirdi ile tamamen uyumlu olmak için yapmanız gerekir !/⌽⎕.
marinus


10

C 96

I / O (yaklaşık 34 karakter alır). Okunabilir hale getirmek için birkaç yeni satır eklendi.

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

Şimdi izin verirseniz, yakalamak için bir ASCII n seçim k roketim var.

    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 karakter

Bu çözüm, k = 0 veya k = 1 gibi durumları doğru şekilde işler.

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

Faktöriyel benzeri bölüm önceki bir cevaba dayanmaktadır .


6

GolfScript 21

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

Özellikle kısa değil, GolfScript gerçek bir faktöriyel fonksiyona sahip değildir, ancak bu şimdiye kadar yaptığım en kötü veri manipülasyonu olmalı, bu bir yığın izlemesi gerektirir:

"5,2" Girişteki yığıntaki veriler.
~Eval komutu, bir sayıyı diziye dönüştüren bir işleç olduğunu unutmayın.
[0 1 2 3 4] 2
~İkili değil.
[0 1 2 3 4] -3
)Artış.
[0 1 2 3 4] -2
>Son 2 elemanı almak için dizi olarak -2 parametresini alın.
[3 4]
.Yinelenen öğe.
[3 4] [3 4]
,Dizi uzunluğu.
[3 4] 2
,Numarayı diziye çevirin.
[3 4] [0 1]
]Dizi oluşturun.
[[3 4] [0 1]]
{{)}%{*}*}Kod bloğu.
[[3 4] [0 1]] {{)}% {*} *}
%Dizinin her öğesi için bir kez blok yürüt. Aşağıdaki bölüm yalnızca ilk döngüyü gösterir.
[3 4]
{)}%Her dizi elemanını arttırın.
[4 5]
{*}Bir çarpma komutu içeren blok.
[4 5] {*}
*Diziyi block komutunu kullanarak "katlayın", bu durumda tüm öğelerin çarpımını yapın.
20
Büyük döngü bittikten sonra sonuçları içeren bir dizi döndürür.
[20 2]
~Diziyi yeniden yapılandırın.
20 2
/Bölüm.
10


6

Yakut 1.9, 52 46 (42) karakter

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

Stderr önemsenmezse:

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

Ruby 1.8, 43 karakter, stderr için ek çıktı yok:

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

Düzenlemeler:

  • (52 -> 48) Girdiyi ayrıştırmak için daha kısa bir yol buldu
  • (48 -> 46) Daha az döngü, daha fazla değerlendirme.

4

Python (56)

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

Kodlanmamış kod ve binom katsayısını hesaplamak için bir kısayolun açıklaması. (Not: 39 karakter versiyonuna inmek için henüz çözemediğim konusunda bir fikir var; Bu yaklaşımın sizi oraya götüreceğini sanmıyorum.)

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

Senaryonuzun çözümsüz bir örneğini verebilir misiniz?
backus

*Formun girdilerini ayrıştırmak için kullanabilir miyiz 4545 78?
Quixotic

Ne yazık ki hayır, ama sorun bu değil *. 4545 78geçerli bir Python ifadesi değil, bu nedenle input()bir SyntaxError. Bu hile tamamen sorulan soruna bağlıdır x,y. Eğer x ybir tuple okuyan ve döndüren bir fonksiyonunuz varsa , o zaman bunu kullanabilirsiniz *.


3

Windows PowerShell, 57

$a,$b=iex $input
$p=1
for($a-=$b;$a-ge1){$p*=1+$b/$a--}$p

3

J, 33 36

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

35 karakter giriş, ayrıştırma ve çıktıdır. Diğer karakter, !n k seçmektir.

Şu anda bunu test etmek için Windows'um yok, ancak orada çalışması gerektiğine inanıyorum.



2

Perl 6 (55)

my ($a,$b)=lines;$_=1;for 1..$a-$b {$_+=$_*$b/$^a};.say

2

RPL (22)

(dahili COMB işlevini kullanmamak)

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

2

Q ( 50 45)

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

Gereksiz parantezleri kaldırarak ve prd yerine 1 * / kullanarak birkaç karakteri tıraş edebilirsiniz.

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

2

Mathematica 12

Basit, yerleşik işlev.

n~Binomial~k

2

Perl 6 , 25 16 bayt

Nwellnhof sayesinde -9 bayt

+*o&combinations

Çevrimiçi deneyin!

İki sayı alan ve int döndüren anonim işlev. Bu yerleşik combinationsolanı kullanır ve döndürülen listeyi int'ye dönüştürür.



@nwellnhof Ah, combinationsbir liste yerine bir sayı alabileceğinin farkında değildim
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?>


1

Python (54)

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

Aslında yukarıdaki Python ile aynı, ancak bırakarak dört bayt tıraş ediyorum

and 1

fonksiyon tanımından. Ancak, bu, k = 0 ise 1 yerine True döndürerek işleve neden olur, ancak 1 * True = 1 olduğundan, yazdırmadan önce 1 ile çarpılarak sabitlenebilir, böylece iki bayt eklenir.


1

J, 11 karakter

!~/".1!:1[1

Klavyeden giriş alır.

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

0

Haskell (80)

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

Ancak, biçim x yyerine girdi biçimine izin verilirse x,y, 74 karakterdir:

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

Kullanarak diğer ikisinden Geliştirilmiş print+sonucunu dönüştürmek için fgelen booleaniçin intdurumunda k==0.

39'a nasıl küçültebileceğimi hala bilmiyorum, lambda kullanıp kullanmadıklarını merak ediyorum.


0

(OP yalnızca giriş ve çıkış yöntemini / biçimini gevşek bir şekilde belirtti, bu nedenle aşağıdakiler kabul edilebilir görünüyor.)

Adaçayı Defteri ( 39 41 40)

Mevcut hücrede,

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

burada formdaki n,kgirdi önceki hücreye girilir ve değerlendirilir. Bu, komut satırı girdisini _(komut satırı bağımsız değişkenlerine benzer şekilde) atayarak simüle eder .

Adaçayı Defteri ( 42 44 43)

Alternatif olarak, "kaynak içi girdi" kullanılması (yalnızca x=ve yeni satır karakterlerinin skora eklenmesi ile), ör.

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

Bu yaklaşımların her ikisi de, başkalarının daha önceki cevaplarından ayrılmaktadır.



0

Javascript, 27 bayt

Öncelikle kendi 35 baytlık çözümlerim:

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

Veya alternatif olarak,

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

İlk (n,k) = (n-1,k) + (n-1,k-1)kural yinelemeli, basit kuralla. İkincisi bunu kullanıyor (n,k) = (n-1,k-1) * n/k.

DÜZENLE

Ben sadece bu bir kopyasını Arnould tarafından çözüm fark ettim:

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

Hangi 8 bayt daha az (27 bayt)


0

TI-BASIC, 16 karakter (8 bayt)

Ans(1) nCr Ans(2

Giriş, 2 inç uzunluğunun bir listesidir Ans.
Çıktı, burada tanımlanan formülün sonucudur .

Yukarıdaki çözüm yeterli değilse, aşağıdaki 35 karakter (24 bayt) çözümü de çalışır:

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

Not: TI-BASIC tokenize bir dildir. Karakter sayısı bayt sayısına eşit değil .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.