Combinaison mathématique

11

Écrivez un programme qui accepte une entrée telle que:

n,k

qui calcule ensuite:

Combinaison de n et k.  (C (n, k))

puis imprime le résultat.


Un exemple numérique:

Contribution:

5,2

Calcul interne:

(5!) / (3! X2!)

Sortie imprimée:

10

Je voudrais voir une réponse qui bat ma solution python de 65 caractères, mais toutes les langues sont évidemment les bienvenues.

Voici ma solution:

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

Éditer:

J'admets que cette question provient du puzzle de combinaison mathématique du site Web de codegolf . Je sais que ma réponse peut sembler que peu de progrès peuvent être réalisés, mais les dirigeants de ce puzzle l'ont résolu en près de la moitié du nombre de personnages.

Le nombre de caractères actuellement le plus bas par langue est:

Perl: 35

Rubis: 36

Python: 39

PHP: 62

backus
la source
Fonction ou programme complet? Votre description indique une fonction qui renvoie le résultat correct, mais votre exemple est un programme complet qui l'imprime.
Ventero
@Ventero Vous avez raison, je voulais dire programme. Désolé pour ça.
backus
3
Généralement, les concepts mathématiques de base ne sont pas de bonnes questions de golf car J, APL, Maple, Mathematica et bien d'autres les auront intégrés. Aussi, soyez un peu plus précis sur le format d'entrée et de sortie, et fournissez des exemples de résultats - je ne peux pas dites si vous voulez dire 5 choisissez 2 ou 2 choisissez 5 ici.
Jesse Millikan
@Jesse J'ai obtenu ce défi d'un autre site Web qui n'autorise que les principaux langages de script, je me souviendrai de cette directive à l'avenir. J'ai édité ma question pour essayer de rendre les exigences du défi plus claires, faites-moi savoir si c'est assez clair ou non.
backus
Je suis nouveau, nous sommes donc dans le même bateau. Cependant, ne résumez pas les résultats; ils deviendront juste obsolètes. Il suffit de voter et (le cas échéant) d'accepter les réponses. (De plus, vous rendrez les gens mécontents si vous ignorez les réponses J et GolfScript sans raison.)
Jesse Millikan

Réponses:

11

APL, 3 octets

⎕!⎕

Ou pour ceux dont le navigateur ne rend pas ce qui précède, dans un rendu ASCII:

{Quad}!{Quad}
jpjacobs
la source
3
Pour être complètement conforme à l' n,kentrée, vous devez le faire !/⌽⎕.
marinus
10

R (11 caractères)

choose(n,r)
skeevey
la source
10

C 96

Avec E / S (qui prend environ 34 caractères). Ajout de quelques nouvelles lignes pour le rendre lisible.

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

Maintenant, si vous m'excusez, j'ai une fusée ASCII et choisissez k pour attraper.

    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
la source
7

GolfScript, 17 caractères

Cette solution gère correctement les cas tels que k = 0 ou k = 1.

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

La partie de type factoriel est basée sur une réponse précédente .

Nabb
la source
6

GolfScript 21

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

Pas particulièrement court, GolfScript n'a pas de véritable fonction factorielle, mais cela doit être la manipulation de données la plus méchante que j'aie jamais faite, cela nécessite une trace de pile:

"5,2" Données sur la pile depuis l'entrée.
~La commande Eval, notez que, est un opérateur qui transforme un nombre en un tableau.
[0 1 2 3 4] 2
~Non binaire.
[0 1 2 3 4] -3
)Incrément.
[0 1 2 3 4] -2
>Prendre la fin du tableau, -2 comme paramètre pour obtenir les 2 derniers éléments.
[3 4]
.Élément en double.
[3 4] [3 4]
,Longueur du tableau.
[3 4] 2
,Transformez le numéro en tableau.
[3 4] [0 1]
]Créer un tableau.
[[3 4] [0 1]]
{{)}%{*}*}Bloc de code.
[[3 4] [0 1]] {{)}% {*} *}
%Exécute le bloc une fois pour chaque élément du tableau. La partie suivante ne montre que la première boucle.
[3 4]
{)}%Incrémentez chaque élément du tableau.
[4 5]
{*}Bloc contenant une commande multiplier.
[4 5] {*}
*"Pliez" le tableau à l'aide de la commande block, c'est-à-dire faites dans ce cas le produit de tous les éléments.
20 Une
fois la grande boucle terminée, elle renvoie un tableau avec les résultats.
[20 2]
~Déconstruisez le tableau.
20 2
/Division.
dix

aaaaaaaaaaaa
la source
6

Ruby 1.9, 52 46 (42) caractères

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

Si stderr est ignoré:

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

Ruby 1.8, 43 caractères, pas de sortie supplémentaire vers stderr:

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

Modifications:

  • (52 -> 48) Trouvé un moyen plus court pour analyser l'entrée
  • (48 -> 46) Moins de boucles, plus d’éval.
Ventero
la source
4

Python (56)

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

Code non golfé et explication d'un raccourci pour calculer le coefficient binomial. (Remarque: Il y a des informations que je n'ai tout simplement pas découvert afin de passer à la version 39 caractères; je ne pense pas que cette approche vous y amènera.)

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

la source
Pourriez-vous fournir un exemple non golfé de votre script?
backus
Pouvons-nous utiliser *pour analyser les entrées du formulaire 4545 78?
Quixotic
Malheureusement, non, mais ce n'est pas *le problème. 4545 78n'est pas une expression Python valide, donc input()lèvera un SyntaxError. Cette astuce dépend entièrement du problème posé x,y. Si vous aviez une fonction qui lisait x yet renvoyait un tuple, alors vous pourriez l'utiliser *avec ça très bien.
4

RPL (4)

(en utilisant la fonction intégrée)

COMB
oliver
la source
3

Windows PowerShell, 57

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

J, 33 36

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

35 caractères sont entrés, analysés et sortis. L'autre caractère !,, est n choisissez k.

Je n'ai pas Windows pour tester cela pour le moment, mais je pense que cela devrait fonctionner là-bas.

Jesse Millikan
la source
3

Q, 32 caractères

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

Perl 6 (55)

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

RPL (22)

(sans utiliser la fonction COMB intégrée)

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

Q ( 50 45)

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

Vous pouvez raser quelques caractères de ce qui précède en supprimant les crochets redondants et en utilisant 1 * / au lieu de prd.

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

Mathematica 12

Fonction simple et intégrée.

n~Binomial~k
DavidC
la source
2

Perl 6 , 25 16 octets

-9 octets grâce à nwellnhof

+*o&combinations

Essayez-le en ligne!

Fonction anonyme qui prend deux nombres et retourne un int. Cela utilise la fonction intégrée combinationset convertit la liste renvoyée en int.

Jo King
la source
16 octets
nwellnhof
@nwellnhof Ah, je ne savais pas que je combinationspouvais prendre un nombre au lieu d'une liste
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
la source
1

Python (54)

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

Essentiellement le même que celui de Python ci-dessus, mais je rase quatre octets en laissant tomber le

and 1

à partir de la définition de la fonction. Cependant, cela entraîne la fonction renvoyant True au lieu de 1 si k = 0, mais cela peut être corrigé en multipliant par 1 avant l'impression, car 1 * True = 1, ajoutant ainsi deux octets.

Tor
la source
1

J, 11 caractères

!~/".1!:1[1

Prend l'entrée du clavier.

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

Haskell (80)

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

Mais, si l'entrée dans le format x yest autorisée au lieu de dans le format x,y, c'est 74 caractères:

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

Scala 54

val n,k=readInt
((k+1)to n product)/(1 to(n-k)product)
Utilisateur inconnu
la source
0

Python (52)

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

L' amélioration des deux autres en utilisant print+pour convertir le résultat de fpartir booleanpour inten cas k==0.

Je ne sais toujours pas comment le réduire à 39, je me demande s'ils utilisent lambda du tout.

Andrea Ambu
la source
0

(L'OP n'a spécifié que de manière lâche la méthode / le format d'entrée et de sortie, donc ce qui suit semble acceptable.)

Cahier Sage ( 39 41 40)

Dans la cellule actuelle,

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

où l'entrée dans le formulaire n,kest entrée et évaluée dans la cellule précédente. Cela simule "l'entrée de ligne de commande" en l'affectant à _(similaire aux arguments de ligne de commande).

Cahier Sage ( 42 44 43)

Alternativement, en utilisant "l'entrée dans la source" (avec seulement les caractères x=et la nouvelle ligne s'ajoutant au score), par exemple,

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

Ces deux approches sont évidemment des retombées de réponses antérieures d'autres auteurs.

res
la source
0

Javascript, 27 octets

D'abord mes propres solutions de 35 octets:

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

Ou bien,

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

Le premier fonctionne récursivement, avec la (n,k) = (n-1,k) + (n-1,k-1)règle simple . Le second utilise ça (n,k) = (n-1,k-1) * n/k.

ÉDITER

Je viens de remarquer la solution d'Arnould en double:

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

Ce qui représente un énorme 8 octets de moins (27 octets)

vrugtehagel
la source
0

TI-BASIC, 16 caractères (8 octets)

Ans(1) nCr Ans(2

L'entrée est une liste de 2 pouces de longueur Ans.
La sortie est le résultat de la formule définie ici .

Si la solution ci-dessus ne suffit pas, la solution suivante de 35 caractères (24 octets) fonctionne également:

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

Remarque: TI-BASIC est un langage à jetons. Le nombre de caractères n'est pas égal au nombre d'octets.

Tau
la source