Preparati a morire?


22

sfondo

Una fonte di ennui nei giochi di ruolo da tavolo riguarda i tiri che coinvolgono molti dadi. Lanciare un incantesimo di disintegrazione può essere istantaneo, ma lanciare e sommare 40 dadi certamente non lo è!

Un certo numero di suggerimenti per gestirlo sono discussi su rpg.stackexchange.com . Alcuni di loro, tuttavia, come usare un programma a rulli o fare una media dei dadi, tolgono un po 'di divertimento e senso di controllo ai giocatori. Altri, come tirare 4 dadi e moltiplicare il totale per 10, rendono i risultati molto più oscillanti (mentre la media dei dadi agisce nella direzione opposta).

Questa domanda riguarda un metodo per ridurre il numero di tiri di dado senza cambiare il risultato medio (media) o la sua oscillazione (varianza).

Notazione e matematica

In questa domanda, useremo la seguente notazione per rappresentare i tiri di dado:

  • n d k (ad es. 40d6) si riferisce alla somma di n tiri di un dado a faccia k.
  • n d k * c (es. 4d6 * 10) descrive la moltiplicazione del risultato per una costante c.
  • Possiamo anche aggiungere rotoli (ad es. 4d6 * 10 + 40d6) e costanti (ad es. 4d6 + 10).

Per un singolo tiro di dado, possiamo dimostrare che:

  • Media : E [1d k ] = (k + 1) / 2
  • Varianza : Var (1d k ) = (k-1) (k + 1) / 12

Utilizzando le proprietà di base di media e varianza, possiamo inoltre dedurre che:

  • Media : E [ m d k * a + n d l * b + c ] = am .E [1d k ] + bn . [1d l ] + c
  • Varianza : Var ( m d k * a + n d l * b + c ] = a ². M .Var (1d k ) + b ². N .Var (1d l )

Compito

Dato tre numeri interi n , k e r , il programma dovrebbe produrre un modo di ravvicinare n d k al massimo in r rotoli, con le seguenti limitazioni:

  • La soluzione dovrebbe avere la stessa media e varianza di n d k .
  • La soluzione dovrebbe contenere il maggior numero possibile di rotoli inferiore o uguale a r , poiché un numero maggiore di rotoli produce una distribuzione più uniforme.
  • Dovresti limitare le tue soluzioni all'uso solo dei dadi a lato k , a meno che tu non stia mirando al Bonus (vedi sotto).
  • Se non esiste una soluzione (poiché r è troppo piccola), il programma dovrebbe generare la stringa "I AM A SEXY SHOELESS GOD OF WAR!".
  • I parametri vengono passati come una singola stringa separata da spazio.
  • Si può presumere che 1 ≤ n ≤ 100, 1 ≤ rn e che k sia uno di 4, 6, 8, 10, 12 e 20 (i dadi standard usati nei tavoli).
  • L'output dovrebbe essere nel formato descritto in Notazione (ad es. 4d6 * 10 + 5), con spazi opzionali intorno a + s ma in nessun altro luogo. Anche i moltiplicatori di unità sono opzionali: sono validi sia 4d6 * 1 che 4d6.

È possibile scrivere un programma o una funzione, prendendo l'input tramite STDIN (o l'alternativa più vicina), argomento della riga di comando o argomento della funzione. I risultati devono essere stampati su STDOUT (o alternativa più vicina) o restituiti come stringa.

Esempi

>> "10 6 10"
10d6
>> "10 6 4"
2d6*2+2d6+14
>> "10 6 3"
1d6*3+1d6+21
>> "10 6 2"
1d6*3+1d6+21
>> "10 6 1"
I AM A SEXY SHOELESS GOD OF WAR!

punteggio

Il codice più corto vince. Si applicano le regole standard.

indennità

-33% (arrotondato per difetto prima della sottrazione) se il programma restituisce anche soluzioni che includono dadi validi diversi da k (dove i valori validi, come menzionato sopra, sono 4, 6, 8, 10, 12 e 20). Se scegli di farlo, dovresti sempre restituire tali soluzioni quando appropriato e gestire soluzioni che utilizzano più tipi di matrici. Esempio:

>> "7 4 3"
3d6+7

6
+1 Per il riferimento OotS. ;) (Bene e perché in realtà è una bella sfida.)
Martin Ender,

1
Forse usi le nostre nuove funzionalità $ \ LaTeX $ per scambiare questa domanda?
orlp,

2
@UriZarfaty: ho aggiornato le tue formule per utilizzare LaTeX. Spero che vada bene. Se non ti piace, puoi semplicemente ripristinare il post e tornerà a come era prima.
Alex A.

1
Ho ripristinato la modifica di LaTeX, perché purtroppo per ora verrà nuovamente disattivata .
Martin Ender,

1
#SadPanda - Pensavo che questo sarebbe stato un riferimento alla sfida del codice "Ciao. Mi chiamo Inigo Montoya. Hai ucciso mio padre. Preparati a morire".
scunliffe,

Risposte:


5

GolfScript ( 163 143 133 byte)

~@:^\?,{^base 0-}%{0\{.*+}/^=},.{{,}$-1=..&{[[1$[1$]/,(3$@]'d*+'1/]zip}%^@{-}/@)*.2/\1&'.5'*}{];'I AM A SEXY SHOELESS GOD OF WAR!'}if

Demo online

Quando non si mescolano tipi di dadi, il problema si riduce all'espressione ncome somma di non più di rquadrati ed kè irrilevante tranne che per il calcolo della costante alla fine. La maggior parte di questa risposta è la contabilità necessaria per esprimere il risultato nel formato desiderato: il calcolo effettivo è ^\?,{^base}%{0\{.*+}/^=},di trovare i fattori di moltiplicazione a, betc .; e ^@{-}/@)*.2/per calcolare la costante.

Dissezione

~                # Stack: n k r
@:^\?,{          # Store n in ^, and for 0 to n**r
  ^base 0-       #   convert to base n and remove 0s.
}%               # Stack: k [arrays of up to r values from 1 to n-1]
{0\{.*+}/^=},    # Filter them to arrays whose sum of squares is n,
                 #   i.e. to multipliers which have the right variance
.{               # If any multiplier array passes the filter...
  {,}$-1=        #   Pick one with the greater number of rolls
                 #   Stack: k [multipliers]
  ..&{           #   Map each distinct multiplier a...
    [[           #     Gather in nested array for later zip
      1$[1$]/,(  #       Split a copy of the multipliers around a to count the as
                 #       Let's denote that count as m
                 #       Stack: k [multipliers] a [ [ m
      3$@        #       Copy k and rotate the a inside the nested array
     ]           #       Stack: k [multipliers] [ [m k a]
      'd*+'1/    #       Push an array ['d' '*' '+'] and close nested array
    ]zip         #       Giving [[m 'd'] [k '*'] [a '+']]
                 #       which will be printed as mdk*a+
  }%             #   Stack: k [multipliers] [string representations of dice]
  ^@{-}/@)*      #   Compute (n - sum(multipliers)) * (k + 1)
                 #   That's twice the constant we need to add to fix the mean
  .2/\1&'.5'*    #   And convert it to a renderable form, including .5 if needed
}{               # Otherwise clear the stack and push the error message
  ];'I AM A SEXY SHOELESS GOD OF WAR!'
}if

1

Pitone, 487 461 452 - 33% = 303 byte

Poiché nessun altro lo ha fatto, ecco una soluzione che gestisce diversi tipi di dadi. Come l'altra soluzione, genera una gamma di possibili soluzioni e le filtra. Usa il fatto che (k + 1) (k-1) = k ^ 2-1 e due semi-lacune nella specifica (oops!): La mancanza di divieto di stampare la forma ridondante 0d k * a (che salva tutti di 5 byte!) e la mancanza di limitazione del tempo di esecuzione (si rallenta abbastanza rapidamente, sebbene esegua tutti gli esempi forniti).

from itertools import*
N,K,R=map(int,input().split())
S=lambda l:sum([x[0]for x in l])
s=[x for x in product(*[[(n,k,a)for n in range(N*(K**2-1)/((k**2-1)*a**2)+1)]for a in range(1,N+1)for k in[4,6,8,10,12,20]if a**2<=N])if sum([n*(k**2-1)*a**2 for n,k,a in x])==N*K**2-N and S(x)<=R]
if s:s=max(s,key=S);print"+".join(["%sd%s*%s"%x for x in s]+[str(int(N*(K+1)/2.-sum([n*a*(k+1)/2.for n,k,a in s])))])
else:print"I AM A SEXY SHOELESS GOD OF WAR!"

Per un output più bello aggiungere if x[0]dopo "%sd%s*%s"%x for x in s:

>> "7 4 3"
3d6+7
>> "10 6 3"
1d6*1+1d8*1+1d8*2+18
>> "10 6 2"
1d6*1+1d6*3+21
>> "10 6 1"
I AM A SEXY SHOELESS GOD OF WAR!
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.