The Tapping Captive of Wrenhold Keep
By commission of the Quiet Hand, bounty payable on delivery of a true reading.
A spy of the Quiet Hand lies chained in the lowest cell of Wrenhold Keep. Each night the spy knocks a message through the stone. A listener in the next cell writes down each group of knocks as a single number. The Hand needs someone who can turn those numbers back into the message.
Write decodeKnocks(knocks).
knocksis an array of integers, each from 0 to 31 inclusive, in the order they were heard. It may be empty.- Return the decoded message as a string.
The decoder is always in one of two alphabets, letters or figures. It starts in letters and begins with an empty message. Process the groups in order:
| Group | Effect | |---|---| | 1–26 | In letters: append the uppercase letter at that position in the alphabet (1 = A, 2 = B, …, 26 = Z). In figures: append the single digit equal to the group modulo 10 (so 1 → 1, 10 → 0, 26 → 6). | | 27 | Append a space, then switch to letters. | | 28 | Switch to figures. | | 29 | Switch to letters. | | 30 | Erase: remove the last character of the message. If the message is empty, nothing happens. The alphabet is unchanged. | | 31 | Repeat: apply again the most recent earlier group that was not a 31, with exactly the effect that group has in the current state. If there is no such earlier group, nothing happens. | | 0 | End: stop decoding. All later groups are ignored. |
Further rules:
- The most recent non-31 group counts for repeat even if it had no visible effect. Examples are an erase on an empty message, or a switch to the alphabet already in use.
- A 31 never becomes the group that a later 31 refers to. A run of several 31s therefore applies the same earlier group once for each 31.
- Switching to the alphabet already in use changes nothing.
- The decoder keeps no state other than the message, the current alphabet, and the most recent non-31 group.
- Return the message exactly as built. Keep any leading, trailing or consecutive spaces.
examples
- case 1
knocks of [13, 5, 5, 20, 27, 28, 4, 27, 1, 20]"MEET 4 AT" (the space after 4 returns the decoder to letters, so 1 and 20 are A and T) - case 2
knocks of [2, 1, 4, 30, 31, 7]"BG" (BAD, erase gives BA, the repeat erases again giving B, then G) - case 3
knocks of [28, 1, 27, 30, 2]"1B" (erasing the space does not bring back figures, so 2 is B) - case 4
knocks of [3, 1, 20, 0, 19]"CAT" (everything after the 0 is ignored)
- reward
- 540 XP
- signature
decodeKnocks
TypeScript, run as ES2022 — types are stripped, not checked. If a JS engine would run it, so will we.
- plain letters
- figures with unshift on space
- repeat letters and repeat a shift
- repeat of erase erases again
- end group stops decoding
- empty input
- repeat with nothing before and erase on empty
- figures use modulo ten
- repeated space keeps letters
- erasing a space does not restore figures
- end at the very start
- long mixed message