Bereite dich darauf vor zu sterben?

22

Hintergrund

Eine Quelle der Langeweile in Tabletop-Rollenspielen ist das Würfeln mit vielen Würfeln. Das Wirken eines Zerfallszaubers mag augenblicklich sein, aber das Würfeln und Addieren von 40 Würfeln ist es mit Sicherheit nicht!

Unter rpg.stackexchange.com werden eine Reihe von Vorschlägen zur Behandlung dieses Problems erörtert . Einige von ihnen, wie das Verwenden eines Rollprogramms oder das Mitteln von Würfeln, nehmen den Spielern jedoch etwas Spaß und Gefühl der Kontrolle. Andere, wie das Werfen von 4 Würfeln und das Multiplizieren der Gesamtsumme mit 10, führen zu weitaus schwungvolleren Ergebnissen (während das Mitteln von Würfeln in die entgegengesetzte Richtung erfolgt).

Diese Frage bezieht sich auf eine Methode zur Verringerung der Anzahl der Würfelwürfe, ohne dass das Durchschnittsergebnis (Mittelwert) oder dessen Schwankung (Varianz) geändert werden.

Notation und Mathematik

In dieser Frage verwenden wir die folgende Notation, um Würfelwürfe darzustellen:

  • n d k (z. B. 40d6) bezieht sich auf die Summe von n Walzen eines k-seitigen Würfels.
  • n d k * c (z. B. 4d6 * 10) beschreibt das Multiplizieren des Ergebnisses mit einer Konstanten c.
  • Wir können auch Rollen (zB 4d6 * 10 + 40d6) und Konstanten (zB 4d6 + 10) hinzufügen.

Für einen einzelnen Würfelwurf können wir zeigen, dass:

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

Anhand der grundlegenden Eigenschaften von Mittelwert und Varianz können wir ferner schließen, dass:

  • Mittelwert : 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 )

Aufgabe

Bei drei Ganzzahlen n , k und r sollte Ihr Programm eine Methode ausgeben, mit der Sie n d k in höchstens r Rollen approximieren können , mit den folgenden Einschränkungen:

  • Die Lösung sollte den gleichen Mittelwert und die gleiche Varianz wie n d k haben .
  • Die Lösung sollte die größtmögliche Anzahl von Rollen enthalten, die kleiner oder gleich r ist , da mehr Rollen eine gleichmäßigere Verteilung ergeben.
  • Sie sollten Ihre Lösungen darauf beschränken, nur k- seitige Würfel zu verwenden, es sei denn, Sie streben den Bonus an (siehe unten).
  • Wenn es keine Lösung gibt (da r zu klein ist), sollte das Programm den String "I AM A SEXY SHOELESS GOD OF WAR!" Ausgeben.
  • Die Parameter werden als einzelne, durch Leerzeichen getrennte Zeichenfolge übergeben.
  • Sie können annehmen, dass 1 ≤ n ≤ 100, 1 ≤ rn und k einer von 4, 6, 8, 10, 12 und 20 ist (die Standardwürfel, die in Tischplatten verwendet werden).
  • Die Ausgabe sollte das in Notation beschriebene Format haben (z. B. 4d6 * 10 + 5), mit optionalen Leerzeichen um + s, aber nirgendwo anders. Einheitenmultiplikatoren sind ebenfalls optional: Sowohl 4d6 * 1 als auch 4d6 sind gültig.

Sie können ein Programm oder eine Funktion schreiben und Eingaben über STDIN (oder die nächstgelegene Alternative), ein Befehlszeilenargument oder ein Funktionsargument vornehmen. Die Ergebnisse sollten an STDOUT (oder die nächstgelegene Alternative) ausgegeben oder als Zeichenfolge zurückgegeben werden.

Beispiele

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

Wertung

Kürzester Code gewinnt. Es gelten Standardregeln.

Bonus

-33% (vor Subtraktion abgerundet), wenn Ihr Programm auch Lösungen zurückgibt, die andere gültige Würfel als k enthalten (wobei die gültigen Werte, wie oben erwähnt, 4, 6, 8, 10, 12 und 20 sind). Wenn Sie sich dazu entschließen, sollten Sie solche Lösungen bei Bedarf immer zurückgeben und Lösungen behandeln, die mehrere Arten von Stempeln verwenden. Beispiel:

>> "7 4 3"
3d6+7
Uri Granta
quelle
6
+1 Für die OotS-Referenz. ;) (Naja und weil es eine wirklich schöne Herausforderung ist.)
Martin Ender
1
Vielleicht nutzen Sie unsere neuen $ \ LaTeX $ -Funktionen, um diese Frage zu beantworten?
Orlp
2
@UriZarfaty: Ich habe Ihre Formeln für die Verwendung von LaTeX aktualisiert. Hoffe das ist in Ordnung. Wenn es dir nicht gefällt, kannst du den Post einfach zurückrollen und es wird wieder so, wie es vorher war.
Alex A.
1
Ich habe die LaTeX-Bearbeitung zurückgesetzt, da sie leider vorerst wieder deaktiviert wird .
Martin Ender
1
#SadPanda - Ich dachte, dies wäre eine Code-Abfrage mit dem Titel "Hallo. Mein Name ist Inigo Montoya. Sie haben meinen Vater getötet. Bereiten Sie sich auf den Tod vor."
Scunliffe

Antworten:

5

GolfScript ( 163 143 133 Bytes)

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

Online-Demo

Wenn keine Würfeltypen gemischt werden, reduziert sich das Problem auf die nSumme von nicht mehr als rQuadraten und kist außer für die Berechnung der Konstante am Ende irrelevant. Der Großteil dieser Antwort ist die Buchführung erforderlich , um das Ergebnis im gewünschten Format zum Ausdruck bringen: die eigentliche Berechnung ist ^\?,{^base}%{0\{.*+}/^=},die Multiplikationsfaktoren zu finden a, busw .; und ^@{-}/@)*.2/um die Konstante zu berechnen.

Präparation

~                # 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
quelle
1

Python, 487 461 452 - 33% = 303 Bytes

Da dies bisher noch niemand getan hat, gibt es hier eine Lösung, die verschiedene Arten von Würfeln handhabt. Wie die andere Lösung generiert es eine Reihe möglicher Lösungen und filtert sie herunter. Es verwendet die Tatsache, dass (k + 1) (k-1) = k ^ 2-1 und zwei halbe Lücken in der Spezifikation (oops!): Das fehlende Verbot des Druckens des redundanten Formulars 0d k * a (das spart alle 5 Bytes!) und die fehlende Laufzeitbeschränkung (es wird ziemlich schnell langsam, obwohl alle angegebenen Beispiele ausgeführt werden).

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

Für schönere Ausgabe Add if x[0]nach "%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
quelle