Préparez-vous à mourir?

22

Contexte

Une source d'ennui dans les jeux de rôle sur table est le traitement des jets impliquant de nombreux dés. Lancer un sort de Désintégration peut être instantané, mais lancer et additionner 40 dés ne l'est certainement pas!

Un certain nombre de suggestions pour gérer cela sont discutées sur rpg.stackexchange.com . Cependant, certains d'entre eux, comme l'utilisation d'un programme à rouleaux ou la moyenne des dés, enlèvent un peu de plaisir et de contrôle aux joueurs. D'autres, comme lancer 4 dés et multiplier le total par 10, rendent les résultats beaucoup plus dynamiques (tandis que la moyenne des dés agit dans la direction opposée).

Cette question concerne une méthode pour réduire le nombre de lancers de dés sans changer ni le résultat moyen (moyenne) ni son swinginess (variance).

Notation et mathématiques

Dans cette question, nous utiliserons la notation suivante pour représenter les lancers de dés:

  • n d k (par exemple 40d6) fait référence à la somme de n rouleaux d'un dé à faces k.
  • n d k * c (par exemple 4d6 * 10) décrit la multiplication du résultat par une constante c.
  • Nous pouvons également ajouter des rouleaux (par exemple 4d6 * 10 + 40d6) et des constantes (par exemple 4d6 + 10).

Pour un seul jet de dé, nous pouvons montrer que:

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

En utilisant les propriétés de base de la moyenne et de la variance, nous pouvons en outre déduire que:

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

Tâche

Étant donné trois entiers n , k et r , votre programme devrait produire un moyen d'approximer n d k dans au plus r rouleaux, avec les contraintes suivantes:

  • La solution doit avoir la même moyenne et la même variance que n d k .
  • La solution doit contenir le plus grand nombre possible de rouleaux inférieur ou égal à r , car plus de rouleaux produisent une distribution plus fluide.
  • Vous devez limiter vos solutions à l'utilisation uniquement de dés à faces k , sauf si vous visez le bonus (voir ci-dessous).
  • S'il n'y a pas de solution (car r est trop petit), le programme devrait sortir la chaîne "JE SUIS UN DIEU DE GUERRE SEXY SHOELESS!".
  • Les paramètres sont transmis sous la forme d'une chaîne unique séparée par des espaces.
  • Vous pouvez supposer que 1 ≤ n ≤ 100, 1 ≤ rn et que k est l'un de 4, 6, 8, 10, 12 et 20 (les dés standard utilisés sur les dessus de table).
  • La sortie doit être au format décrit dans Notation (par exemple 4d6 * 10 + 5), avec des espaces optionnels autour de + s mais nulle part ailleurs. Les multiplicateurs d'unités sont également facultatifs: les 4d6 * 1 et 4d6 sont valides.

Vous pouvez écrire un programme ou une fonction, en prenant des entrées via STDIN (ou l'alternative la plus proche), un argument de ligne de commande ou un argument de fonction. Les résultats doivent être imprimés dans STDOUT (ou l'alternative la plus proche) ou renvoyés sous forme de chaîne.

Exemples

>> "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!

Notation

Le code le plus court gagne. Des règles standard s'appliquent.

Prime

-33% (arrondi avant la soustraction) si votre programme renvoie également des solutions qui incluent des dés valides autres que k (où les valeurs valides, comme mentionné ci-dessus, sont 4, 6, 8, 10, 12 et 20). Si vous choisissez de le faire, vous devez toujours renvoyer ces solutions le cas échéant et gérer les solutions qui utilisent plusieurs types de matrices. Exemple:

>> "7 4 3"
3d6+7
Uri Granta
la source
6
+1 Pour la référence OotS. ;) (Eh bien et parce que c'est un très beau défi, en fait.)
Martin Ender
1
Peut-être utiliser nos nouvelles capacités $ \ LaTeX $ pour répondre à cette question?
orlp
2
@UriZarfaty: J'ai mis à jour vos formules pour utiliser LaTeX. J'espère que ça va. Si vous ne l'aimez pas, vous pouvez simplement annuler le message et il reviendra à ce qu'il était auparavant.
Alex A.
1
J'ai annulé l'édition de LaTeX, car malheureusement, elle sera à nouveau désactivée pour l'instant .
Martin Ender
1
#SadPanda - Je pensais que ça allait être une référence de défi de code à "Bonjour. Mon nom est Inigo Montoya. Vous avez tué mon père. Préparez-vous à mourir."
scunliffe

Réponses:

5

GolfScript ( 163 143 133 octets)

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

Démo en ligne

Lorsqu'il ne mélange pas les types de dés, le problème se nrésume à l'expression sous la forme d'une somme ne dépassant pas les rcarrés et kn'est pas pertinent, sauf pour le calcul de la constante à la fin. La majeure partie de cette réponse est la comptabilité requise pour exprimer le résultat dans le format souhaité: le calcul réel est ^\?,{^base}%{0\{.*+}/^=},de trouver les facteurs de multiplication a,b etc .; et ^@{-}/@)*.2/pour calculer la constante.

Dissection

~                # 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
Peter Taylor
la source
1

Python, 487 461 452 - 33% = 303 octets

Puisque personne d'autre ne l'a fait, voici une solution qui gère différents types de dés. Comme l'autre solution, il génère une gamme de solutions possibles et les filtre. Il utilise le fait que (k + 1) (k-1) = k ^ 2-1 et deux demi-failles dans la spécification (oups!): L'absence d'interdiction d'imprimer la forme redondante 0d k * a (ce qui économise tous les 5 octets!), et le manque de restriction de temps d'exécution (il ralentit assez rapidement, bien qu'il exécute tous les exemples donnés).

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!"

Pour une sortie plus jolie, ajoutez if x[0]après "%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!
Uri Granta
la source