Distribuzione di frequenza di rotoli di dadi misti


24

Un seguito a questa sfida

Dato un set di dadi misti, genera la distribuzione di frequenza del lancio di tutti e sommando i numeri lanciati su ogni dado.

Ad esempio, si consideri 1d12 + 1d8(tirare 1 dado a 12 facce e 1 dado a 8 facce). I tiri massimo e minimo sono 20e 2, rispettivamente, simili al lancio 2d10(2 dadi a 10 facce). Tuttavia, 1d12 + 1d8risulta in una distribuzione più piatta di 2d10: [1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 7, 6, 5, 4, 3, 2, 1]contro [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1].

Regole

  • Le frequenze devono essere elencate in ordine crescente della somma a cui corrisponde la frequenza.
  • L'etichettatura delle frequenze con le somme corrispondenti è consentita, ma non richiesta (poiché le somme possono essere desunte dall'ordine richiesto).
  • Non è necessario gestire input in cui l'output supera l'intervallo rappresentabile di numeri interi per la propria lingua.
  • Gli zero iniziali o finali non sono consentiti. Nell'uscita dovrebbero apparire solo frequenze positive.
  • Puoi prendere l'input in qualsiasi formato ragionevole (elenco di dadi ( [6, 8, 8]), elenco di coppie di dadi ( [[1, 6], [2, 8]]), ecc.).
  • Le frequenze devono essere normalizzate in modo che il GCD delle frequenze sia 1 (ad es. [1, 2, 3, 2, 1]Anziché [2, 4, 6, 4, 2]).
  • Tutti i dadi avranno almeno una faccia (quindi a d1è il minimo).
  • Questo è , quindi vince il codice più breve (in byte). Le scappatoie standard sono vietate, come al solito.

Casi test

Questi casi di test sono indicati come input: output, in cui l'input è dato come un elenco di coppie che [a, b]rappresentano a bdadi a lato (quindi si [3, 8]riferisce a 3d8, e si [[1, 12], [1, 8]]riferisce a 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]

Risposte:


7

Gelatina ,  14  7 byte

-3 byte grazie a Mr. Xcoder (uso di una gamma implicita per evitare il piombo R; sostituzione di riduzione con il prodotto cartesiano diadico e appiattimento p/F€, con il prodotto cartesiano incorporato proprio per quello scopo Œp).

ŒpS€ĠL€

Un collegamento monadico che prende un elenco di facce di dadi e restituisce la distribuzione normalizzata delle somme crescenti.

Provalo online!

Come?

Passa attraverso l'elenco delle "dimensioni" dei dadi (implicitamente), le inserisce nella loro lista di facce, quindi ottiene il prodotto cartesiano di quelle liste (tutti i tiri possibili del set di dadi), quindi somma i tiri, ottiene i gruppi di uguali indici (in ordine crescente) e prende la lunghezza di ciascun gruppo.

Œ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]

Nota: esiste sempre un solo modo per ottenere il minimo (lanciando uno su ogni singolo dado) e non stiamo contando due volte i tiri, quindi non è necessario eseguire una normalizzazione GCD.


Grazie, mi chiedo se avremo mai bisogno del ÷g/$pensiero (non c'è sempre solo un modo per ottenere il minimo o il massimo?)
Jonathan Allan,

2
Pensavo che fosse un'alternativa degna di essere condivisa:ŒpS€µLƙ
Mr. Xcoder il

5

MATL , 8 byte

1i"@:gY+

L'ingresso è un array di dimensioni di stampi (eventualmente ripetute).

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

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)

5

Buccia , 7 byte

mLkΣΠmḣ

L'input è un elenco di dadi. Provalo online!

Spiegazione

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]


4

Ottava , 88 69 58 56 byte

Come menzionato nella risposta di Haskell, ciò utilizza il fatto che la distribuzione, ad esempio, di un dado a 3 facce e a 5 facce è la convoluzione discreta dei due vettori [1,1,1]e [1,1,1,1,1]. Grazie @LuisMendo per -11 byte di golf intelligente!

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

Provalo online!

Questa presentazione utilizza un approccio ricorsivo. Ma se dovessi usare un loop sarebbe leggermente più lungo:

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

4

Haskell , 80 78 64 byte

Questa soluzione è stata quasi identica a quella di @ Sherlock9 nella precedente sfida con l'approccio forse più naturale. @xnor ha una soluzione Haskell ancora più breve !

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

Spiegazione:

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

Provalo online!

Soluzione precedente:

Questo sta usando la funzione di convoluzione discreta @AndersKaseorg . L'osservazione qui è che la distribuzione, ad esempio, di un dado a 3 facce e a 5 facce è la convoluzione discreta dei due vettori [1,1,1]e [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

Provalo online!


4

Wolfram Language (Mathematica) , 26 byte

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

Provalo online!

Una modifica della mia risposta alla sfida precedente . Questo genera solo tutti i possibili risultati, li somma e ne calcola i risultati.

Per divertimento, potremmo scriverlo come Tally@*Total@*Thread@*Tuples@*Range, ma è più lungo.

Wolfram Language (Mathematica) , 41 byte

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

Provalo online!

Questo è l'approccio basato sulla convoluzione (qui, prendiamo le convoluzioni attraverso il prodotto delle funzioni di generazione - 1+x+x^2+...+x^(N-1)è la funzione di generazione per rotolare un dN - e quindi prendiamo l'elenco dei coefficienti). Lo includo perché la prima soluzione non è pratica per input di grandi dimensioni.


4

Mathematica, 44 byte

Emette le frequenze etichettate con le somme corrispondenti

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

Provalo online!

-5 byte da Martin Ender

grazie a Misha Lavrov per avermi fatto sapere che "etichettato" è valido


3

Pyth , 12 byte

lM.gs.nk*FSM

Provalo qui!

Come?

lM.gs.nk * FSM ~ Programma completo.

          SM ~ Mappa con intervallo intero unario inclusivo [1, N].
        * Prodotto cartesiano pieghevole (riduci di).
  .g ~ Raggruppa per risultato della funzione.
    sn ~ La somma dell'elenco quando appiattita.
lM ~ Lunghezza di ciascun gruppo.

3

Gelatina , 14 byte

R+Ѐ/FċЀSR$ḟ0

Provalo online!

L'input è un elenco di valori die. Potrei giocare a golf rubando ĠL€dall'altra risposta di Jelly ma poi potrei anche giocare a golf nella prima metà e finire con la stessa cosa, quindi lascerò semplicemente com'è



2

05AB1E , 11 byte

€L.«âOO{γ€g

Provalo online!

Come funziona

€ L. «ÂOO {γ € g - Programma completo.

€ L - Per ogni N nell'elenco, ottieni [1 .. N].
  . «- Piega una funzione diadica tra ciascun elemento in un elenco da destra a sinistra.
    â - E scegli il prodotto cartesiano come quella funzione.
     O - Appiattire ciascuno.
      O - Somma ciascuno.
       {γ - Ordina e raggruppa in serie di uguali valori adiacenti.
         € g - Ottieni le lunghezze di ciascuno.

Salvato 1 byte grazie a Emigna !


Si potrebbe fare Oinvece di€˜
Emigna l'

2

R , 51 byte

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

Provalo online!

Prende un elenco di dadi e restituisce un vettore denominato di frequenze; i nomi (valori delle somme dei dadi) sono stampati sopra le frequenze.

R , 59 byte

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

Provalo online!

Un Reduceapproccio piuttosto che quello iterativo sopra.

R , 62 byte

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

Provalo online!

Un approccio convoluzione. Darà alcuni avvertimenti che sta usando solo il primo elemento di Dper l'espressione 1:Dma non influenza l'output. Se non dovessimo prendere tutta la Reparte della soluzione, sarebbero 58 byte.


1

APL (Dyalog Classic) , 12 10 byte

-2 grazie a @ Adám

⊢∘≢⌸+/↑,⍳⎕

Provalo online!

l'input è un elenco di N dadi

⍳⍵ è una matrice N-dimensionale di vettori nidificati - tutti i possibili tiri di dado

+/↑, appiattisce le matrici e somma i tiri

⊢∘≢⌸ conta quante di ogni somma unica, elencate in ordine di prima apparizione, che fortunatamente coincide con il loro ordine crescente


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



0

Pulito , 154 142 136 107 100 85 + 13 = 98 byte

L'input è un elenco di dadi.

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

La risposta è in forma di lambda.

+13 byte da import StdEnv, che importa il modulo necessario affinché funzioni.

Provalo online!


0

JavaScript (ES6), 83 byte

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

Accetta l'input di ogni dado come parametro separato.


0

JavaScript (ES6), 76 74 byte

Accetta input come un elenco di dadi.

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=[])

Casi test

L'elaborazione degli ultimi due casi di test richiederebbe di abilitare il TCO o aumentare il limite di dimensioni dello stack predefinito del motore JS.

Formattato e commentato

NB: Questa è una versione commentata della mia presentazione iniziale che utilizzava il metodo di riduzione (). È più lungo di 2 byte ma è più facile da leggere.

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

0

Clojure, 96 byte

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

Il primo input è un elenco di numeri di dadi e il secondo input è un elenco di numeri di lati su ciascun dado.


0

Perl 5 , 94 byte

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

Provalo online!

Il formato di input è un elenco di dadi separati da newline. Pertanto, 1d10 + 2d8 verrebbero inseriti come:

10
8
8

0

SageMath, 46 byte

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

Provalo online

Questo è un adattamento della mia soluzione all'altra sfida . Prende un numero qualsiasi di dadi come parametri (ad esempio f(4,4,6,6,6)per 2d4+3d6) e restituisce un elenco.


Python 2 + NumPy , 62 byte

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

Provalo online!

Come prima, ho incluso questa soluzione con quella sopra, poiché sono sostanzialmente equivalenti. Nota che questa funzione restituisce un array NumPy e non un elenco Python, quindi l'output appare un po 'diverso se lo fai print.

numpy.ones(x)è il modo "corretto" per creare un array da usare con NumPy, e quindi potrebbe essere usato al posto di [x*[1]], ma purtroppo è molto più lungo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.