The Golem-Hearts of Ashtarren Quarry
Deep in Ashtarren Quarry, the stonewrights of the Graven Lodge carve the hearts that wake their guardian golems. Each heart is set with runestones, and the Lodge writes the setting as a recipe: a compact line of rune-names, counts and brackets. Some recipes also draw stones back out, written after a minus sign. Before a heart is carved, the Lodge needs a plain reckoning of how many of each runestone it finally holds. The board offers a bounty to whoever writes that reckoner.
Write golemHeart(recipe).
Input. recipe is a non-empty, well-formed string with no spaces, following this grammar:
- A recipe is one or more terms separated by
+or-. The first term carries no sign. - A term is an optional coefficient followed by one or more units.
- A unit is either a rune or a bracketed group
(...)containing one or more units. Either kind may be followed by an optional count. - A rune is one uppercase letter
A-Zfollowed by zero or more lowercase lettersa-z. Runes with different names are different runes, soK,KaandKbare three distinct runes. - A coefficient and a count are positive decimal integers with no leading zeros. A missing coefficient or count means 1.
Meaning. A rune occurrence contributes its own count, multiplied by the count of every bracketed group enclosing it, multiplied by its term's coefficient. The coefficient applies to every unit of its term. A term preceded by + (or the first term) adds its contributions; a term preceded by - subtracts them. A rune's net total is the sum of all its contributions across the whole recipe and may be positive, zero or negative.
Output. Return a string listing every rune whose net total is not zero, sorted by rune name in character-code order (so K comes before Ka, which comes before Kb). Write each rune as its name followed immediately by its net total in decimal, except that a net total of exactly 1 is written as the name alone. A negative total keeps its minus sign, for example Vor-3; a total of -1 is written Vor-1. Separate entries with a single space. If every rune's net total is zero, return the empty string.
examples
- case 1
recipe of "2KaVor3""Ka2 Vor6" (the coefficient 2 covers both Ka and Vor3) - case 2
recipe of "((Ka2Vor)3Ul)2""Ka12 Ul2 Vor6" - case 3
recipe of "3Ka2-6Ka""" (six Ka set, six drawn out, nothing remains) - case 4
recipe of "Ul-Vor3""Ul Vor-3"
- reward
- 540 XP
- signature
golemHeart
TypeScript, run as ES2022 — types are stripped, not checked. If a JS engine would run it, so will we.
- single rune
- coefficient covers whole term
- group with count
- nested groups
- prefix-sharing names sort
- full cancellation is empty
- negative one keeps its digit
- partial cancellation
- multi-digit counts and coefficients
- nested group under coefficient
- explicit count of one
- negative total listed