The Scout-Charts of Vorrenmound Hive
Beneath the barley plains east of Bitwick, a colony of horse-sized ants has dug Vorrenmound Hive, a maze of chambers inside chambers. The Pathfinders' Lodge sends scouts down in relays. Each scout returns with a chart in the Lodge's knot-script. The scribes have tied all of the relay's charts into one long line, so the same chamber is often recorded more than once. Before the next expedition descends, the Lodge needs a single clean outline, and it needs every garbled chart rejected outright.
Write outlineHive(chart), where chart is a string written in knot-script. It returns an array of strings.
Knot-script grammar. The whole of chart must be exactly one *list*:
- A list is one or more *chambers*, separated by single commas
,. - A chamber is a *name*, optionally followed by
(, a list, and). The chambers inside the parentheses are that chamber's children. - A name is one or more lowercase letters
a-z.
No other characters are allowed anywhere, and that includes spaces. The chart is malformed if any of the following is true:
- it is empty;
- it contains any other character;
- a parenthesis is empty or unbalanced;
- a comma is leading, trailing or doubled;
- a chamber is followed by more than one parenthesised group, as in
a(b)(c); - any characters are left over after the list.
If chart is malformed, return an empty array.
Merging. Sometimes two or more chambers under the same parent have the same name. At the top level, the parent is the line itself. Such chambers are one chamber, and its children are all of their children combined. After combining, the same rule applies again to those children, at every depth. Chambers with the same name but different parents are never merged. For example, in a(a) the inner a stays a child of the outer one.
Ordering. The order in which chambers appear in the input means nothing. After merging, the children of every chamber are sorted in ascending order by name, using plain character order. The top-level chambers are sorted the same way. If one name is a prefix of another, the shorter name comes first.
Output. List every chamber of the merged, sorted outline in pre-order: a chamber, then all of its children with their own descendants, then its next sibling. Each line is the chamber's name, prefixed by one - for each level of depth. Top-level chambers have no -, their children have one, their grandchildren have two, and so on.
examples
- case 1
chart of "mound(east(larder,brood),west(brood),east(brood(grub)))"["mound", "-east", "--brood", "---grub", "--larder", "-west", "--brood"]. The two east chambers merge, and so do their brood chambers. The brood under west stays separate. - case 2
chart of "ab(cd),abc"["ab", "-cd", "abc"]. "ab" sorts before "abc". - case 3
chart of "a(b)(c)"[]. This chart is malformed because a chamber has two parenthesised groups.
- reward
- 540 XP
- signature
outlineHive
TypeScript, run as ES2022 — types are stripped, not checked. If a JS engine would run it, so will we.
- relay chart with nested merges
- empty chart is malformed
- two parenthesised groups
- single chamber
- same name at different depths stays separate
- top level sorted
- empty parentheses
- trailing comma
- uppercase letter
- unclosed parenthesis
- leftover closing parenthesis
- distant duplicates merge deeply
- space is malformed
- mound example
- group without a name
- prefix names sort shorter first
- doubled comma inside