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


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}

3
Para estar completamente em conformidade com a n,kentrada, você teria que fazer !/⌽⎕.
marinus


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 * * |
|     *      *    \
*/    //       *  */

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 .


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


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.

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)

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

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 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á.


3

Q, 32 caracteres

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

2

Perl 6 (55)

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

2

RPL (22)

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

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

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}

2

Mathematica 12

Função simples e integrada.

n~Binomial~k

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.



@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?>


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.


1

J, 11 caracteres

!~/".1!:1[1

Recebe entrada do teclado.

    !~/".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.(++")").('(':)

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


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.


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.



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)


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.