Distribution de fréquence des lancers de dés mixtes

24

Une suite à ce défi

Étant donné un ensemble de dés mixtes, affichez la distribution de fréquence de tous les lancers et de la somme des nombres lancés sur chaque dé.

Par exemple, considérez 1d12 + 1d8(lancer 1 dé à 12 faces et 1 dé à 8 faces). Les lancers maximum et minimum sont 20et 2, respectivement, ce qui est similaire au lancer 2d10(2 dés à 10 faces). Cependant, il en 1d12 + 1d8résulte une distribution plus plate que 2d10: [1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 7, 6, 5, 4, 3, 2, 1]versus [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1].

Règles

  • Les fréquences doivent être répertoriées dans l'ordre croissant de la somme à laquelle la fréquence correspond.
  • L'étiquetage des fréquences avec les sommes correspondantes est autorisé, mais pas obligatoire (car les sommes peuvent être déduites de l'ordre requis).
  • Vous n'avez pas à gérer les entrées lorsque la sortie dépasse la plage représentable d'entiers pour votre langue.
  • Les zéros au début ou à la fin ne sont pas autorisés. Seules les fréquences positives doivent apparaître dans la sortie.
  • Vous pouvez prendre l'entrée dans n'importe quel format raisonnable (liste de dés ( [6, 8, 8]), liste de paires de dés ( [[1, 6], [2, 8]]), etc.).
  • Les fréquences doivent être normalisées de sorte que le GCD des fréquences soit 1 (par exemple [1, 2, 3, 2, 1]au lieu de [2, 4, 6, 4, 2]).
  • Tous les dés auront au moins un visage (donc a d1est le minimum).
  • Il s'agit de , donc le code le plus court (en octets) l'emporte. Les failles standard sont interdites, comme d'habitude.

Cas de test

Ces cas de test sont donnés comme input: output, où l'entrée est donnée sous la forme d'une liste de paires [a, b]représentant les a bdés à faces (donc [3, 8]fait référence 3d8et [[1, 12], [1, 8]]fait référence 1d12 + 1d8).

[[2, 10]]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[[1, 1], [1, 9]]: [1, 1, 1, 1, 1, 1, 1, 1, 1]
[[1, 12], [1, 8]]: [1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 7, 6, 5, 4, 3, 2, 1]
[[2, 4], [3, 6]]: [1, 5, 15, 35, 68, 116, 177, 245, 311, 363, 392, 392, 363, 311, 245, 177, 116, 68, 35, 15, 5, 1]
[[1, 3], [2, 13]]: [1, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 37, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 1]
[[1, 4], [2, 8], [2, 20]]: [1, 5, 15, 35, 69, 121, 195, 295, 423, 579, 761, 965, 1187, 1423, 1669, 1921, 2176, 2432, 2688, 2944, 3198, 3446, 3682, 3898, 4086, 4238, 4346, 4402, 4402, 4346, 4238, 4086, 3898, 3682, 3446, 3198, 2944, 2688, 2432, 2176, 1921, 1669, 1423, 1187, 965, 761, 579, 423, 295, 195, 121, 69, 35, 15, 5, 1]
[[1, 10], [1, 12], [1, 20], [1, 50]]: [1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 285, 360, 444, 536, 635, 740, 850, 964, 1081, 1200, 1319, 1436, 1550, 1660, 1765, 1864, 1956, 2040, 2115, 2180, 2235, 2280, 2316, 2344, 2365, 2380, 2390, 2396, 2399, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2399, 2396, 2390, 2380, 2365, 2344, 2316, 2280, 2235, 2180, 2115, 2040, 1956, 1864, 1765, 1660, 1550, 1436, 1319, 1200, 1081, 964, 850, 740, 635, 536, 444, 360, 285, 220, 165, 120, 84, 56, 35, 20, 10, 4, 1]
Mego
la source
Sandbox
Mego

Réponses:

7

Gelée ,  14  7 octets

-3 octets grâce à M. Xcoder (utilisation d'une plage implicite pour éviter de mener R; remplacement de réduire par le produit cartésien dyadique et d'aplatir p/F€, avec le produit cartésien intégré à cet effet ,.Œp )

ŒpS€ĠL€

Un lien monadique reprenant une liste de faces de dés et renvoyant la distribution normalisée des sommes croissantes.

Essayez-le en ligne!

Comment?

Parcourt la liste des "tailles" de dés (implicitement) en fait leur liste de faces, puis obtient le produit cartésien de ces listes (tous les jets possibles de l'ensemble de dés), puis résume ces jets, obtient les groupes d'égaux indices (par valeur ascendante) et prend la longueur de chaque groupe.

ŒpS€ĠL€ - Link: list of numbers, dice  e.g. [2,5,1,2]
Œp      - Cartisian product (implicit range-ification -> [[1,2],[1,2,3,4,5],[1],[1,2]])
        -                   -> [[1,1,1,1],[1,1,1,2],[1,2,1,1],[1,2,1,2],[1,3,1,1],[1,3,1,2],[1,4,1,1],[1,4,1,2],[1,5,1,1],[1,5,1,2],[2,1,1,1],[2,1,1,2],[2,2,1,1],[2,2,1,2],[2,3,1,1],[2,3,1,2],[2,4,1,1],[2,4,1,2],[2,5,1,1],[2,5,1,2]]
  S€    - sum €ach          -> [4,5,5,6,6,7,7,8,8,9,5,6,6,7,7,8,8,9,9,10]
    Ġ   - group indices     -> [[1],[2,3,11],[4,5,12,13],[6,7,14,15],[8,9,16,17],[10,18,19],[20]]
     L€ - length of €ach    -> [1,3,4,4,4,3,1]

Remarque: il n'y a qu'une seule façon de lancer le minimum (en lançant un sur chaque dé) et nous ne comptons pas deux fois les lancers, il n'est donc pas nécessaire d'effectuer une normalisation GCD.

Jonathan Allan
la source
Merci, je me demande si nous en avons besoin ÷g/$(n'est-ce pas toujours une seule façon d'obtenir le minimum ou le maximum?)
Jonathan Allan
2
Je pensais que c'était une alternative à partager:ŒpS€µLƙ
M. Xcoder
5

MATL , 8 octets

1i"@:gY+

L'entrée est un tableau de tailles de matrice (éventuellement répétées).

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

1      % Push 1
i      % Input: numeric array
"      % For each k in that array
  @    %   Push k
  :    %   Range: gives [1 2 ... k]
  g    %   Convert to logical: gives [1 1 ... 1]
  Y+   %   Convolution, with full size
       % End (implicit). Display (implicit)
Luis Mendo
la source
5

Husk , 7 octets

mLkΣΠmḣ

L'entrée est une liste de dés. Essayez-le en ligne!

Explication

mLkΣΠmḣ  Implicit input, say x=[3,3,6].
     mḣ  Map range: [[1,2,3],[1,2,3],[1,2,3,4,5,6]]
    Π    Cartesian product: [[1,1,1],[1,1,2],..,[3,3,6]]
  kΣ     Classify by sum: [[[1,1,1]],[[1,1,2],[1,2,1],[2,1,1]],..,[[3,3,6]]]
mL       Map length: [1,3,6,8,9,9,8,6,3,1]
Zgarb
la source
4

Octave , 88 69 58 56 octets

Comme mentionné dans la réponse de Haskell, cela utilise le fait que la distribution, par exemple, d'un dé à 3 côtés et d'un dé à 5 côtés est la convolution discrète des deux vecteurs [1,1,1]et [1,1,1,1,1]. Merci @LuisMendo pour -11 octets de golf intelligent!

function y=f(c);y=1:c;if d=c(2:end);y=conv(~~y,f(d));end

Essayez-le en ligne!

Cette soumission utilise une approche récursive. Mais si vous utilisiez une boucle, elle serait légèrement plus longue:

function y=f(c);y=1;for k=cellfun(@(x)ones(1,x),c,'Un',0);y=conv(y,k{1});end
flawr
la source
4

Haskell , 80 78 64 octets

Cette solution a fini par être presque la même que celle de @ Sherlock9 dans le défi précédent avec l'approche peut-être plus naturelle. @xnor a une solution Haskell encore plus courte !

import Data.List
g x=[1..x]
map length.group.sort.map sum.mapM g

Explication:

                              mapM g -- all possible outcomes
                      map sum        -- the sums of all possible outcomes
map length.group.sort                -- count the frequency of each sum

Essayez-le en ligne!

Solution précédente:

Cela utilise la fonction de convolution discrète @AndersKaseorg . L'observation ici est que la distribution, par exemple, d'un dé à 3 côtés et d'un dé à 5 côtés est la convolution discrète des deux vecteurs [1,1,1]et [1,1,1,1,1].

foldl1(#).map(`take`l)
(a:b)#c=zipWith(+)(0:b#c)$map(a*)c++[]#b
_#c=0<$c
l=1:l

Essayez-le en ligne!

flawr
la source
4

Wolfram Language (Mathematica) , 26 octets

Tally[Tr/@Tuples@Range@#]&

Essayez-le en ligne!

Une modification de ma réponse au défi précédent . Cela génère simplement tous les résultats possibles, les additionne et correspond aux résultats.

Pour le plaisir, nous pourrions l'écrire comme Tally@*Total@*Thread@*Tuples@*Range, mais c'est plus long.

Wolfram Language (Mathematica) , 41 octets

CoefficientList[1##&@@((x^#-1)/(x-1)),x]&

Essayez-le en ligne!

C'est l'approche basée sur la convolution (ici, nous prenons des convolutions via le produit des fonctions génératrices - 1+x+x^2+...+x^(N-1)est la fonction génératrice pour faire rouler un dN - puis prenons la liste des coefficients). Je l'inclus parce que la première solution n'est pas pratique pour les grandes entrées.

Misha Lavrov
la source
4

Mathematica, 44 octets

Sort les fréquences étiquetées avec les sommes correspondantes

Tally@*Fold[Join@@Table[#+i,{i,#2}]&]@*Range

Essayez-le en ligne!

-5 octets de Martin Ender

merci à Misha Lavrov de m'avoir fait savoir que "étiqueté" est valide

J42161217
la source
3

Pyth , 12 octets

lM.gs.nk*FSM

Essayez-le ici!

Comment?

lM.gs.nk * FSM ~ Programme complet.

          SM ~ Carte avec plage entière unaire inclusive [1, N].
        * F ~ Fold (réduire de) produit cartésien.
  .g ~ Résultat du regroupement par fonction.
    sn ~ La somme de la liste lorsqu'elle est aplatie.
lM ~ Longueur de chaque groupe.
M. Xcoder
la source
3

Gelée , 14 octets

R+Ѐ/FċЀSR$ḟ0

Essayez-le en ligne!

L'entrée est une liste de valeurs de matrice. Je pourrais jouer au golf en volant ĠL€l'autre réponse de Jelly, mais je pourrais aussi jouer au golf pendant la première moitié et finir avec la même chose, donc je vais laisser les choses comme elles sont

dylnan
la source
2

Python 2 , 120 119 octets

lambda v:[reduce(lambda a,c:sum([[b+y for b in a]for y in range(c)],[]),v,[0]).count(d)for d in range(sum(v)-len(v)+1)]

Essayez-le en ligne!

Merci pour Mego / Jonathon Allan pour 1 octet.

Chas Brown
la source
... c'est-à-dire enregistrer un octet .
Jonathan Allan
2

05AB1E , 11 octets

€L.«âOO{γ€g

Essayez-le en ligne!

Comment ça marche

€ L. «âOO {γ € g - Programme complet.

€ L - Pour chaque N de la liste, obtenez [1 .. N].
  . «- Pliez une fonction dyadique entre chaque élément d'une liste de droite à gauche.
    â - Et choisissez le produit cartésien comme fonction.
     O - Aplatir chacun.
      O - Sommez chacun.
       {γ - Trier et regrouper en séries de valeurs adjacentes égales.
         € g - Obtenez les longueurs de chacun.

1 octet enregistré grâce à Emigna !

M. Xcoder
la source
Vous pourriez faire Oau lieu de€˜
Emigna
2

R , 51 octets

function(D){for(x in D)F=outer(F,1:x,"+")
table(F)}

Essayez-le en ligne!

Prend une liste de dés et retourne un vecteur de fréquences nommé; les noms (valeurs des sommes des dés) sont imprimés au-dessus des fréquences.

R , 59 octets

function(D)table(Reduce(function(x,y)outer(x,1:y,"+"),D,0))

Essayez-le en ligne!

Une Reduceapproche plutôt que celle itérative ci-dessus.

R , 62 octets

function(D)Re(convolve(!!1:D,"if"(sum(x<-D[-1]),f(x),1),,"o"))

Essayez-le en ligne!

Une approche par convolution. Il donnera quelques avertissements selon lesquels il n'utilise que le premier élément de Dl'expression, 1:Dmais cela n'affecte pas la sortie. Si nous n'avions pas à prendre la Repartie entière de la solution, ce serait 58 octets.

Giuseppe
la source
1

APL (Dyalog Classic) , 12 10 octets

-2 merci à @ Adám

⊢∘≢⌸+/↑,⍳⎕

Essayez-le en ligne!

l'entrée est une liste de N dés

⍳⍵ est un tableau N-dimensionnel de vecteurs imbriqués - tous les lancers de dés possibles

+/↑, aplatit les tableaux et résume les lancers

⊢∘≢⌸ compte le nombre de chaque somme unique, répertoriée dans l'ordre de leur première apparition, qui coïncide heureusement avec leur ordre croissant

ngn
la source
1
-2: ⊢∘≢⌸+/↑,⍳⎕
Adám
1

Rubis , 72 octets

->d{r=[0]*d.sum
[0].product(*d.map{|e|[*1..e]}){|e|r[e.sum-1]+=1}
r-[0]}

Essayez-le en ligne!

Prend une liste de dés en entrée. Sans aucun doute, il peut être joué au golf, mais pas trop mal.

Rétablir Monica iamnotmaynard
la source
0

Propre , 154 142 136 107 100 85 + 13 = 98 octets

L'entrée est une liste de dés.

\l#t=foldr(\a-> \b=[x+y\\x<-[1..a],y<-b])[0]l
=[length[v\\v<-t|u==v]\\u<-removeDup t]

La réponse est sous la forme d'un lambda.

+13 octets deimport StdEnv , qui importe le module nécessaire pour que cela fonctionne.

Essayez-le en ligne!

Οurous
la source
0

JavaScript (ES6), 83 octets

f=(n,...a)=>n?f(...a).map((e,i)=>[...Array(n)].map(_=>r[i]=~~r[i++]+e),r=[])&&r:[1]
g=s=>o.textContent=f(...(s.match(/\d+/g)||[]).map(n=>+n)).join`, `
<input oninput=g(this.value)><p id=o>1

Prend l'entrée de chaque dé comme paramètre séparé.

Neil
la source
0

JavaScript (ES6), 76 74 octets

Prend l'entrée comme une liste de dés.

a=>(g=k=>a.map(d=>(s+=n%d|0,n/=d),s=0,n=k)|n?x:g(k+1,x[s]=-~x[s]))(0,x=[])

Cas de test

Le traitement des deux derniers cas de test nécessiterait d'activer le TCO ou d'augmenter la limite de taille de pile par défaut du moteur JS.

Formaté et commenté

NB: Ceci est une version commentée de ma soumission initiale qui utilisait réduire (). C'est 2 octets de plus mais plus facile à lire.

a =>                    // given the list of dice a
  (g = k =>             // g = recursive function taking k = counter
    a.reduce((k, d) =>  //   for each die d in a:
      (                 //     k % d represents the current face of d
        s += k % d,     //     we add it to the total s
        k / d | 0       //     and we update k to pick the face of the next die
      ),                //     initialization:
      k,                //     start with the current value of k
      s = 0             //     total = 0
    ) ?                 //   reduce() returns 1 as soon as k = product of all dice
      x                 //     in which case we're done: stop recursion and return x
    :                   //   else:
      g(                //     do a recursive call to g() with:
        k + 1,          //       k incremented
        x[s] = -~x[s]   //       x[s] incremented
      )                 //     end of recursive call
  )(0, x = [])          // initial call to g() with k = 0 and x = empty array
Arnauld
la source
0

Clojure, 96 octets

#(sort-by key(frequencies(reduce(fn[R D](for[d(range D)r R](+ r d 1)))[0](mapcat repeat % %2))))

La première entrée est une liste de nombre de dés, et la deuxième entrée est une liste de nombre de côtés sur chaque dé.

NikoNyrh
la source
0

Perl 5 , 94 octets

map$k{$_}++,map eval,glob join'+',map'{'.(join',',1..$_).'}',<>;say$k{$_}for sort{$a-$b}keys%k

Essayez-le en ligne!

Le format d'entrée est une liste de dés séparés par des retours à la ligne. Ainsi, 1d10 + 2d8 entrerait comme:

10
8
8
Xcali
la source
0

SageMath, 46 octets

lambda*a:reduce(convolution,[x*[1]for x in a])

Essayez-le en ligne

Il s'agit d'une adaptation de ma solution à l'autre défi . Il prend n'importe quel nombre de dés comme paramètres (par exemple f(4,4,6,6,6)pour 2d4+3d6) et retourne une liste.


Python 2 + NumPy , 62 octets

lambda*a:reduce(numpy.convolve,[x*[1]for x in a])
import numpy

Essayez-le en ligne!

Comme précédemment, j'ai inclus cette solution avec celle ci-dessus, car elles sont essentiellement équivalentes. Notez que cette fonction renvoie un tableau NumPy et non une liste Python, donc la sortie semble un peu différente si vous printle faites .

numpy.ones(x)est la façon "correcte" de créer un tableau à utiliser avec NumPy, et donc il pourrait être utilisé à la place de [x*[1]], mais il est malheureusement beaucoup plus long.

Mego
la source