‹ back to the board

Sunday, September 6

Mastermulti-constraint & composite logic

The Apothecary's Rune-Wands

The apothecary of bitwick will not shelve a rune-wand until the counting-stone has read it. Each wand carries a single line of runes, read left to right; a line that breaks the craft's rules is faulty and the wand is worth nothing.

You are given line, a string. Split it on whitespace to get the runes (leading, trailing and repeated whitespace are ignored; a line with no runes at all is possible). Write wandValue(line), which returns the wand's value as an integer, or null in TypeScript / None in Python if the line is faulty.

## The runes

The stone keeps a stack of integers, empty at the start.

  • A number is an optional - followed by one or more digits (7, -3, 007). It pushes its value.
  • +, -, * each pop two values. Calling the deeper one a and the upper one b, they push a + b, a - b, a * b respectively.
  • dup pushes a copy of the top value.
  • swap exchanges the top two values.
  • drop removes the top value.
  • rep pops one value n, then runs the block that immediately follows it exactly n times, one run after another. If n is zero or negative the block is not run at all. Blocks may contain further reps.
  • A block is the rune [, then zero or more runes, then its matching ].

## Faulty lines

The shape of the line is judged over every rune in it, whether or not that rune is ever reached. A line is faulty if any of these hold:

  • some rune is not a number, not one of + - * dup swap drop rep, and not [ or ];
  • a [ appears anywhere other than immediately after a rep;
  • a rep is not immediately followed by a [;
  • the brackets are not balanced and properly nested.

Otherwise the line is run. It is also faulty if:

  • any rune needs more values than the stack currently holds (including rep needing its count);
  • after every rune has been run, the stack does not hold exactly one value.

When the line is not faulty, the single value left on the stack is the result.

  • tokenizing and evaluating
  • Master

examples

  1. case 1line of "2 3 + 4 *"20
  2. case 2line of "1 5 rep [ 2 * ]"32 — the count 5 is popped, then the block doubles the 1 five times
  3. case 3line of "3 rep [ 2 2 + ]"faulty (null / None) — three values are left on the stack
  4. case 4line of "0 rep [ nope ] 5"faulty (null / None) — the block never runs, but `nope` is not a rune
reward
540 XP
signature
wandValue
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…
  • plain arithmetic
  • nested repeats
  • count taken from the stack
  • zero count skips the block
  • negative count skips the block
  • empty block
  • bad rune inside a skipped block
  • stack underflow
  • two values left over
  • no runes at all
  • bracket without a repeat
  • unclosed block
  • repeat without a block
  • stray closing bracket
  • repeat with nothing to count
  • negative literal and subtraction
  • shuffling runes
  • ragged whitespace
  • plus-signed number is not a rune
  • padded digits
The Apothecary's Rune-Wands · bitwick