Combinação matemática

11

Escreva um programa que aceite uma entrada como:

n,k

que então calcula:

Combinação de n e k.  (C (n, k))

e depois imprime o resultado.


Um exemplo numérico:

Entrada:

5,2

Cálculo interno:

(5!) / (3! X2!)

Saída impressa:

10

Gostaria de ver uma resposta que supera minha solução python de 65 caracteres, mas todos os idiomas são obviamente bem-vindos.

Aqui está a minha solução:

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

Editar:

Admito que esta pergunta é do quebra-cabeça de combinação matemática do site codegolf . Sei que minha resposta pode parecer que não há muito progresso nisso, mas os líderes desse quebra-cabeça o resolveram em quase a metade dos caracteres.

As contagens mais baixas atuais de caracteres por idioma são:

Perl: 35

Ruby: 36

Python: 39

PHP: 62

Backus
fonte
Função ou programa completo? Sua descrição diz a função que retorna o resultado correto, mas seu exemplo é um programa completo que o imprime.
Ventero 22/03
@Ventero Você está certo, eu quis dizer programa. Me desculpe por isso.
Backus
3
Geralmente, os conceitos matemáticos básicos não são ótimas questões de golfe, porque J, APL, Maple, Mathematica e muitos outros os incorporam. Além disso, seja um pouco mais específico sobre o formato de entrada e saída e forneça exemplos de resultados - não posso diga se você quer dizer 5, escolha 2 ou 2, escolha 5 aqui.
precisa
@ Jessie Eu recebi esse desafio de outro site que apenas permite grandes linguagens de script, lembrarei desta diretriz no futuro. Editei minha pergunta para tentar tornar os requisitos do desafio mais claros; informe-nos se é suficientemente claro ou não.
Backus
Eu sou novo, então estamos no mesmo barco. No entanto, não resuma os resultados; eles ficarão desatualizados. Apenas vote e (se apropriado) aceite as respostas. (Além disso, você vai fazer as pessoas infelizes se você ignorar J e GolfScript respostas sem uma razão.)
Jesse Millikan

Respostas:

11

APL, 3 bytes

⎕!⎕

Ou para aqueles cujo navegador não renderiza o acima, em uma renderização ASCII:

{Quad}!{Quad}
jpjacobs
fonte
3
Para estar completamente em conformidade com a n,kentrada, você teria que fazer !/⌽⎕.
marinus
10

R (11 caracteres)

choose(n,r)
skeevey
fonte
10

C 96

Com E / S (que leva cerca de 34 caracteres). Foram adicionadas algumas novas linhas para torná-las legíveis.

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

Agora, se você me der licença, eu tenho um ASCII e escolha k foguete para pegar.

    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
fonte
7

GolfScript, 17 caracteres

Esta solução lida com casos como k = 0 ou k = 1 corretamente.

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

A parte fatorial é baseada em uma resposta anterior .

Nabb
fonte
6

GolfScript 21

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

Não particularmente curto, o GolfScript não possui uma função fatorial real, no entanto, essa deve ser a manipulação de dados mais maliciosa que eu já fiz, isso exige um rastreamento de pilha:

"5,2" Dados na pilha a partir da entrada.
~O comando Eval, observe que, é um operador que transforma um número em uma matriz.
[0 1 2 3 4] 2
~Binário não.
[0 1 2 3 4] -3
)Incremento.
[0 1 2 3 4] -2
>Tome o final da matriz, -2 como parâmetro para obter os últimos 2 elementos.
[3 4]
.Elemento duplicado.
[3 4] [3 4]
,Comprimento da matriz.
[3 4] 2
,Gire o número para o array.
[3 4] [0 1]
]Crie uma matriz.
[[3 4] [0 1]]
{{)}%{*}*}Bloco de código.
[[3 4] [0 1]] {{)}% {*} *}
%Execute o bloco uma vez para cada elemento da matriz. A parte a seguir demonstra apenas o primeiro loop.
[3 4]
{)}%Incremente cada elemento da matriz.
[4 5]
{*}Bloco contendo um comando de multiplicação.
[4 5] {*}
*"Dobre" a matriz usando o comando block, ou seja, faça o produto de todos os elementos.
20
Depois que o loop grande termina, ele retorna uma matriz com os resultados.
[20 2]
~Desconstrua a matriz.
20 2
/Divisão.
10

aaaaaaaaaaaa
fonte
6

Ruby 1.9, 52 46 (42) caracteres

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

Se stderr for ignorado:

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

Ruby 1.8, 43 caracteres, sem saída adicional para o stderr:

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

Editar% s:

  • (52 -> 48) Encontrou uma maneira mais curta de analisar a entrada
  • (48 -> 46) Menos loop, mais avaliação.
Ventero
fonte
4

Python (56)

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

Código não-bloqueado e alguma explicação de um atalho para calcular o coeficiente binomial. (Observação: há algumas dicas que eu ainda não descobri para chegar à versão de 39 caracteres; não acho que essa abordagem o levará até lá.)

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

fonte
Você poderia fornecer um exemplo não-destruído de seu script?
Backus
Podemos usar *para analisar entradas do formulário 4545 78?
Quixotic 23/03
Infelizmente, não, mas não é *esse o problema. 4545 78não é uma expressão válida do Python, então input()aumentará a SyntaxError. Esse truque depende inteiramente do problema solicitado x,y. Se você tivesse uma função que lesse x ye retornasse uma tupla, poderia usá-la *perfeitamente.
4

RPL (4)

(usando a função incorporada)

COMB
oliver
fonte
3

Windows PowerShell, 57

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

J, 33 36

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

35 caracteres são de entrada, análise e saída. O outro caractere !,, é n, escolha k.

No momento, não tenho o Windows para testar isso no momento, mas acredito que deve funcionar lá.

Jesse Millikan
fonte
3

Q, 32 caracteres

{f:{1*/1.+(!)x};f[x]%f[y]*f x-y}
tmartin
fonte
2

Perl 6 (55)

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

RPL (22)

(não usando a função COMB embutida)

→ n k 'n!/(k!*(n-k)!)'
oliver
fonte
2

Q ( 50 45)

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

Você pode raspar alguns caracteres acima, removendo colchetes redundantes e usando 1 * / em vez de prd.

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

Mathematica 12

Função simples e integrada.

n~Binomial~k
DavidC
fonte
2

Perl 6 , 25 16 bytes

-9 bytes graças a nwellnhof

+*o&combinations

Experimente online!

Função anônima que recebe dois números e retorna um int. Isso usa o built-in combinationse converte a lista retornada em um int.

Brincadeira
fonte
16 bytes
nwellnhof
@nwellnhof Ah, eu não sabia que combinationspoderia ter um número em vez de uma lista
Jo rei
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
fonte
1

Python (54)

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

Essencialmente o mesmo que o Python acima, mas eu corto quatro bytes soltando o

and 1

da definição da função. No entanto, isso resulta na função retornando True em vez de 1 se k = 0, mas isso pode ser corrigido multiplicando-se 1 antes da impressão, pois 1 * True = 1, adicionando assim dois bytes.

Tor
fonte
1

J, 11 caracteres

!~/".1!:1[1

Recebe entrada do teclado.

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

Haskell (80)

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

Mas, se a entrada no formato x yé permitida, e não no formato x,y, são 74 caracteres:

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

Scala 54

val n,k=readInt
((k+1)to n product)/(1 to(n-k)product)
Usuário desconhecido
fonte
0

Python (52)

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

Aprimorado dos outros dois usando print+para converter o resultado de ffrom booleanpara intcase k==0.

Ainda não tenho idéia de como reduzi-lo para 39, gostaria de saber se eles estão usando lambda.

Andrea Ambu
fonte
0

(O OP especificou vagamente o método / formato de entrada e saída, portanto o seguinte parece aceitável.)

Caderno Sábio ( 39 41 40)

Na célula atual,

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

onde a entrada no formulário n,ké inserida e avaliada na célula anterior. Isso simula a "entrada da linha de comando" atribuindo-a a _(semelhante aos argumentos da linha de comando).

Caderno Sábio ( 42 44 43)

Como alternativa, usando "entrada na fonte" (com apenas os x=caracteres newline e adicionados à pontuação), por exemplo,

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

Ambas as abordagens são obviamente derivadas de respostas anteriores de outras pessoas.

res
fonte
0

Javascript, 27 bytes

Primeiro, minhas próprias soluções de 35 bytes:

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

Ou alternativamente,

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

O primeiro trabalhando recursivamente, com a (n,k) = (n-1,k) + (n-1,k-1)regra simples . O segundo usando isso (n,k) = (n-1,k-1) * n/k.

EDITAR

Acabei de perceber a solução de Arnould em uma duplicata:

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

Que é um gritante 8 bytes a menos (27 bytes)

vrugtehagel
fonte
0

TI-BASIC, 16 caracteres (8 bytes)

Ans(1) nCr Ans(2

Entrada é uma lista de comprimento 2 pol Ans.
Saída é o resultado da fórmula definida aqui .

Se a solução acima não for suficiente, a seguinte solução de 35 caracteres (24 bytes) também funcionará:

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

Nota: TI-BASIC é um idioma tokenizado. Contagem de caracteres não é igual à contagem de bytes.

Tau
fonte