‹ back to the board

Monday, October 5

Mastermulti-constraint & composite logic

The Pit-Marshal's Bone Dice

Posted by the Pit-Marshals of the Corvane Arena

Before every bout in the sand pits of Corvane, each champion's strike is written on a slate as a dice formula. It is then settled with carved bone dice in front of the crowd. The bookmakers will not take a single wager until a marshal has declared the lowest and highest result that formula could possibly produce. The marshals are tired of arguing it out by hand. Write the reckoner that declares the range.

The formula

formula is a string built from these parts:

  • Integer literals: one or more digits, such as 7 or 12. They are never negative on their own.
  • Dice terms: NdM, where N and M are positive integers written in digits and d is a lowercase letter. N may be omitted, so dM means 1dM. A dice term stands for rolling N dice, each with faces 1 through M, and summing them. There are no spaces inside a literal or a dice term.
  • Binary operators: +, - and *.
  • Unary minus: a - that appears where a value is expected. This is at the start of the formula, directly after (, or directly after another operator. It negates the value that follows it.
  • Parentheses ( and ) for grouping.
  • Spaces, which may appear between any of the parts above and carry no meaning.

The rules of precedence:

  • Unary minus binds tightest.
  • * binds tighter than binary + and -.
  • Binary +, - and * are all left-associative, so 3 - 2 - 1 means (3 - 2) - 1.

Every dice term in the formula is rolled separately and independently, even if the same term is written more than once. The formula is always well-formed.

The task

Write diceRange(formula). Consider every possible combination of die faces. It returns a list of two integers, [lowest, highest]: the smallest and largest value the formula can evaluate to.

  • recursive-descent parsing
  • Master

examples

  1. case 1formula of "2d6 - d4"[-2, 11] (2 - 4 at the low end, 12 - 1 at the high end)
  2. case 2formula of "(d4 - 3) * (d4 - 3)"[-2, 4] (the two d4s are rolled separately, so one factor can be -2 while the other is 1)
  3. case 3formula of "3 - 2 - 1"[0, 0] (subtraction groups from the left)
  4. case 4formula of "1d100 - (d10 * -d10)"[2, 200]
reward
540 XP
signature
diceRange
not yet run

TypeScript, run as ES2022 — types are stripped, not checked. If a JS engine would run it, so will we.

loading the editor…
  • single dice term
  • omitted count plus literal
  • subtracting a dice term swaps its ends
  • independent factors crossing zero
  • unary minus then multiply
  • bare literal
  • left associative subtraction
  • multiplication before addition
  • double unary minus
  • one-faced dice times negative group
  • symmetric ranges multiplied
  • nested negative product subtracted
  • zero times negated dice
  • multi-digit counts and faces
  • spaces around a parenthesised literal
  • unary minus on a group
The Pit-Marshal's Bone Dice · bitwick