Il est temps pour un autre défi facile auquel tous peuvent participer!
Le théorème multinomial énonce:
L'expression entre parenthèses est le coefficient multinomial, défini comme:
Laisser les termes k i s'étendre sur toutes les partitions entières de n donne le n -ième niveau du m- simplex de Pascal . Votre tâche consiste à calculer ce coefficient.
Tâche
Écrivez un programme ou une fonction qui prend m nombres, n , k 1 , k 2 , ..., k m-1 , et génère ou renvoie le coefficient multinomial correspondant. Votre programme peut éventuellement prendre m comme argument supplémentaire si nécessaire. Notez que k m n'est pas en entrée.
Ces nombres peuvent être entrés dans n'importe quel format souhaité, par exemple regroupés dans des listes ou codés en unaire, ou toute autre chose, tant que le calcul réel du coefficient multinomial est effectué par votre code, et non par le processus de codage.
Le format de sortie est également flexible.
Tout le code doit s'exécuter en moins d'une minute pour n et m jusqu'à 1000.
Ne vous inquiétez pas du débordement d'entier.
Les éléments intégrés conçus pour calculer le coefficient multinomial ne sont pas autorisés.
Des échappatoires standard s'appliquent.
Notation
Voici le code golf: la solution la plus courte en octets gagne.
Cas de test
Input: 3, [2, 0]
Output: 3
Input: 3, [1, 1]
Output: 6
Input: 11, [1, 4, 4]
Output: 34650
Input: 4, [1,2]
Output: 12
Input: 15, [5,4,3,2]
Output: 37837800
Input: 95, [65,4,4]
Output: 1934550571913396675776550070308250
Input: 32, [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]
Output: 4015057936610313875842560000000
Input: 15, [3,3,3,3]
Output: 168168000
Input: 1000, [10,10,10,10,10,10,10,10,10,10,100,100,100,100,100,100,100,100]
Output: 1892260836114766064839886173072628322819837473493540916521650371620708316292211493005889278395285403318471457333959691477413845818795311980925098433545057962732816261282589926581281484274178579110373517415585990780259179555579119249444675675971136703240347768185200859583936041679096016595989605569764359198616300820217344233610087468418992008471158382363562679752612394898708988062100932765563185864346460326847538659268068471585720069159997090290904151003744735224635733011050421493330583941651019570222984959183118891461330718594645532241449810403071583062752945668937388999711726969103987467123014208575736645381474142475995771446030088717454857668814925642941036383273459178373839445456712918381796599882439216894107889251444932486362309407245949950539480089149687317762667940531452670088934094510294534762190299611806466111882595667632800995865129329156425174586491525505695534290243513946995156554997365435062121633281021210807821617604582625046557789259061566742237246102255343862644466345335421894369143319723958653232683916869615649006682399919540931573841920000000000000
Input: 33, [17]
Output: 1166803110
Input: 55, [28]
Output: 3824345300380220
la source
1934550571913396675776550070308250
, pouvons-nous produire1.9345505719133966e+33
?[1000 {999 ones}]
, car l'exposant est bien au-delà de ce que les flottants 64 bits peuvent représenter. (Des flottants de 128 bits suffiront probablement, mais je suppose que vous souhaitez utiliser le type de numéro natif de JavaScript?)Réponses:
Gelée ,
76 octetsRegardez ma, pas d'Unicode! Ce programme prend une seule liste en entrée, avec n à son premier index.
Essayez-le en ligne! ou vérifiez tous les cas de test à la fois .
Comment ça marche
la source
CJam, 11 octets
Entrez comme une seule liste avec d'
n
abord:Cela gère les entrées jusqu'à
n
etm
1000 à peu près instantanément.Testez-le ici.
Explication
la source
MATL , 21
15octetsMettons à profit la fonction log-gamma . Cela évite les débordements internes en travaillant avec les logarithmes des factorielles, pas avec les factorielles elles-mêmes.
Cela fonctionne dans la version actuelle (9.2.2) du langage / compilateur, qui est antérieure à ce défi.
Les entrées sont: d'abord un nombre, puis un vecteur numérique. Le résultat est produit en tant que
double
, ce qui limite la sortie maximale à quelque part2^52
.Exemple
Explication
la source
PowerShell,
9174 octetsCourtiser! Ma 100ème réponse sur PPCG!
Ouf. Ne va pas gagner le code le plus court, c'est sûr. Utilise cependant quelques astuces soignées avec des plages. Et c'est probablement du charabia complet pour quiconque ne connaît pas PowerShell.
Explication
Nous prenons d'abord une entrée avec
param($n,$k)
et nous nous attendons$k
à être un tableau, par exemple.\compute-the-multinomial-coefficient.ps1 11 @(1,4,4)
.Nous allons commencer par le numérateur (tout à gauche de
/
). Il s'agit simplement d'une plage à partir de1..$n
laquelle a été-join
éditée avec*
, puis évaluée aveciex
pour calculer la factorielle (c.-à1*2*3*...*$n
-d.).Ensuite, on boucle sur
$k|%{...}
et chaque itération on retranche la valeur actuelle$_
de$n
(que nous ne se soucient pas plus) de formuler$k_m
plus tard. De plus, nous générons la plage à1..$k_i
chaque itération, qui reste sur le pipeline. Ces objets de pipeline sont concaténés en tableau avec la deuxième expression, range1..$n
(qui est$k_m
à ce stade). Tout cela est finalement-join
édité avec*
et évalué aveciex
, similaire au numérateur (cela fonctionne parce quex! * y! = 1*2*3*...*x * 1*2*3*...*y
, donc nous ne nous soucions pas de la commande individuelle).Enfin,
/
cela arrive, le numérateur est divisé par le dénominateur et la sortie.Les poignées sortent correctement pour des nombres plus importants, car nous ne convertissons pas explicitement de variables en tant que types de données particuliers, donc PowerShell sera automatiquement rediffusé en tant que types de données différents à la volée selon les besoins. Pour les plus grands nombres, les sorties via la notation scientifique permettent de conserver au mieux les chiffres significatifs lors de la refonte des types de données. Par exemple,
.\compute-the-multinomial-coefficient.ps1 55 @(28)
sortira3.82434530038022E+15
. Je suppose que cela est OK étant donné que "Le format de sortie est tout aussi flexible" est spécifié dans les commentaires du défi et de la quintopie "Si le résultat final peut tenir dans les types entiers pris en charge nativement, alors le résultat doit être précis. S'il ne le peut pas, il n'est pas une restriction sur ce qui peut être sorti. "Alternativement
Selon les décisions de formatage de sortie, ce qui suit à 92 octets
Ce qui est le même que ci-dessus, utilise simplement un formatage de sortie explicite avec
.ToString('G17')
pour atteindre le nombre de chiffres souhaité. Car55 @(28)
cela produira3824345300380220.5
Edit1 - Enregistré 17 octets en se débarrassant
$d
et en le calculant directement, et en se débarrassant du calcul$k_m
en le$k
cordant pendant que nous bouclons Edit2 - Ajout d'une version alternative avec un formatage explicite
la source
APL (Dyalog Extended) , 9 octets
Essayez-le en ligne!
Utiliser l'idée de ma réponse APL sur un autre défi qui implique des multinomiaux .
Fonction tacite dont l'argument de gauche est la liste des k et l'argument de droite est n. Les cas de test vérifient si elle est d'accord avec la solution d' Adam avec les arguments gauche et droit inversés.
Comment ça marche
la source
Mathematica, 26 octets
Exemple:
la source
Python 3,
9391Merci à Dennis et FryAmTheEggman .
n
comme entier,k
comme itérable.Non golfé:
la source
95, [65, 4, 4]
. Notez que l'entrée ne contient pas k_m . 2. Vous ne semblez pas utiliserfrom functools import*
du tout.reduce
. 2.import math;f=math.factorial
enregistre un octet. 3. Python 2 vous permettra de se débarrasser de la seconde/
en//
.f
de votre propre sauve quelques octets :f=lambda x:0**x or x*f(x-1)
.APL (Dyalog Unicode) , 16 octets SBCS
Entièrement basé sur les compétences mathématiques de mon collègue Marshall .
Fonction d'infixation anonyme. Prend k comme argument de droite et n comme argument de gauche.
Essayez-le en ligne!
{
…}
Lambda anonyme;⍺
est l'argument gauche ( n ) et l'⍵
argument droit ( k )0,⍵
ajouter un zéro à k¯1↓
déposez le dernier élément de cette+\
somme cumulée de cette⍺-
soustrayez cela de n⍵!
( k ) que×/
produit de celala source
PARI / GP, 43 octets
Assez simple; à part le formatage, la version non golfée pourrait bien être identique.
la source
Matlab 48 octets
Vous devez régler
format
à l'long
avance pour obtenir une précision plus élevée. Ensuite, c'est assez simple:la source
Pyth, 10 octets
Essayez-le en ligne: Démonstration
Explication:
la source
J, 16 octets
Usage
Pour les valeurs plus grandes, un suffixe de
x
est utilisé pour désigner les entiers à précision étendue.Explication
la source
05AB1E , 8 octets
Essayez-le en ligne! Explication:
Je n'arrive pas à trouver de meilleures façons d'effectuer l'étape 2 ou l'étape 4.
la source
APL (Dyalog Unicode) , 17 octets
Essayez-le en ligne!
Infix tacit function (Merci à @ Adám pour les 2 octets qu'il enregistre.)
APL (Dyalog Unicode) , 19 octets
Essayez-le en ligne!
Infix Dfn.
Les deux fonctions ci-dessus calculent la formule donnée.
la source
Haskell ,
5958 octetsEssayez-le en ligne!
Merci à BMO d' avoir économisé 1 octet!
la source
Clojure, 70 octets
Crée une fonction anonyme prenant tous les arguments en une seule liste, avec
n
first.30 caractères sont "gaspillés" juste pour définir la putain de fonction factorielle. Tant pis.
la source
Perl 6 ,
5250 octetsEssaye-le
Testez-le (le résultat est un rationnel avec un dénominateur de 1)
Étendu:
la source