‹ back to the board

Friday, October 9

Mastermulti-constraint & composite logic

The Beast-Writs of Ivelcote Abbey

The conjurers of Ivelcote Abbey call up bands of spirit-beasts by reading a writ aloud inside the summoning ring. Before any writ is read, the Abbey posts a bounty for whoever can reckon exactly which beasts it will call and how many of each, and who can spot a writ that is miswritten. A miswritten writ is never read.

Write tallyWrit(formula). formula is a string. Return a string.

### Writ grammar

A writ is one or more parts separated by +.

  • A part is an optional *coefficient* followed by one or more *units*.
  • A unit is one of:
  • a *beast name* followed by an optional *count*;
  • (, one or more units, ), then an optional count;
  • [, one or more units, ], then an optional count.
  • A beast name is one uppercase letter A–Z followed by zero or more lowercase letters a–z. A name takes every lowercase letter that immediately follows it. So FyOst is the two names Fy and Ost, and Fyost is the single name Fyost.
  • A coefficient or count is a run of digits 0–9 that forms a positive integer with no leading zero. 1, 7 and 12 are allowed. 0 and 05 are not. It takes every digit that immediately follows. An omitted count or coefficient means 1.

Brackets nest to any depth. Each ( must be closed by ), and each [ must be closed by ]. No other character is part of the grammar, and that includes spaces.

### Counting

  • A beast name contributes its count.
  • A bracketed group's count multiplies everything inside it.
  • A part's coefficient multiplies everything in that part.
  • The totals of all parts are added together. A name that appears in several places is summed.

### Return

If formula does not match the grammar exactly, return "INVALID".

Otherwise, return the canonical writ:

  • It contains every beast name exactly once, sorted in ascending order by character code. A name therefore comes before any longer name that begins with it, so B comes before Ba.
  • Each name is written followed by its total. The total is left out when it is 1.
  • The result contains no brackets, no coefficients and no +.
  • tokenizing and evaluating
  • Master

examples

  1. case 1formula of "Ka(Fy2[OstRu]3)2""Fy4KaOst6Ru6": the [OstRu] group triples, then the whole round group doubles, and Ka stands alone
  2. case 2formula of "2FyOst+3Ost2""Fy2Ost8": the first part gives Fy 2 and Ost 2, the second gives Ost 6
  3. case 3formula of "BaB2""B2Ba": B sorts before Ba because it is a prefix of it
  4. case 4formula of "(Fy]2""INVALID": a round bracket cannot be closed by a square one
reward
540 XP
signature
tallyWrit
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…
  • nested groups multiply
  • coefficients and parts sum
  • names are sorted
  • repeated name merges
  • prefix name sorts first
  • long name versus short name
  • multi-digit counts and coefficient
  • deep nesting
  • single bare name
  • explicit ones are dropped
  • coefficient on a later part
  • mismatched bracket
  • empty writ
  • trailing plus
  • leading plus
  • double plus
  • count with leading zero
  • zero count
  • coefficient with leading zero
  • coefficient alone
  • empty group
  • digit inside opening bracket
  • lowercase start
  • unclosed bracket
  • close without open
  • space is not allowed