‹ back to the board

Thursday, October 15

Mastermulti-constraint & composite logic

The Drum-Engine of Duskforge Hold

Bounty of the Delvers' Lodge of Bitwick. Beneath the abandoned dwarf-hold of Duskforge stands a brass engine that still turns. Its drum holds a column of whole numbers, and it is driven by punched tapes of glyphs. A tape that faults seizes the engine, so the Lodge will pay for a reckoner that predicts what any tape will do before it is fed.

Write runTape(tape, slots). tape is a string. slots is a non-negative integer: the most values the drum can hold at once. The drum starts empty. The function returns a string, described under Return.

### Glyphs - space: a separator. It does nothing. - digits: a maximal run of consecutive digits 0-9 is one number, read in decimal (leading zeros allowed). It is pushed onto the drum. There are no negative numbers in a tape: - is always the subtraction glyph. - + - * /: pop the top value b, then pop the next value a, and push a + b, a - b, a * b, or a / b rounded down toward negative infinity (floor division). - :: push a copy of the top value. - $: swap the top two values. - !: discard the top value. - ( ... ): a repeated section. When a ( is reached, pop the top value n. Then run the glyphs between this ( and its matching ) n times in a row, each time on the drum as it currently stands. Then continue after the ). If n is zero or negative, the section is skipped entirely. Sections may nest, and a nested ( pops its own count every time it is reached.

### Faults The whole tape is checked before anything runs. Each of these is a fault: - a character that is not one of the glyphs above; - a bracket with no partner. Brackets pair in the usual nested way.

If there are several such faults, report the one with the lowest index. Only a tape that passes this check is run.

While the tape runs, the first fault ends the run. These are the run-time faults: - Too few values. A glyph needs more values than the drum holds. + - * / $ need two values, and : ! ( need one. - Division by zero. A / whose divisor b is zero. - Full drum. A push happens while the drum already holds slots values. Only a number or : can cause this.

A glyph that is never reached, for example inside a skipped section, cannot cause a run-time fault.

### Return If a fault occurs, return "ERROR i", where i is the 0-based index in tape of the offending character. For a number, that is the index of its first digit.

Otherwise, return the values left on the drum from bottom to top. Write them as decimal integers, with a leading - on negative values, separated by single spaces. If the drum is empty, return "".

All values reached in the tests stay well within safe integer range.

  • tokenizing and evaluating
  • Master

examples

  1. case 1tape "1 3(:1+)", slots 8"1 2 3 4". The 3 is popped as the count, and each pass copies the top value and adds one to the copy.
  2. case 2tape "7 10- 2/", slots 8"-2". 7 - 10 is -3, and -3 divided by 2 rounds down to -2.
  3. case 3tape "1 3(:)", slots 3"ERROR 4". The third copy by the ':' at index 4 would be a fourth value on a three-slot drum.
  4. case 4tape "+ 3 x", slots 8"ERROR 4". The stray 'x' is caught before running, so the '+' at index 0 never gets the chance to fault.
reward
540 XP
signature
runTape
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
  • floor division with negatives
  • simple repeated section
  • zero and negative counts skip
  • nested sections
  • section building on drum
  • overflow inside a section
  • swap and discard
  • empty tape
  • only spaces
  • too few values
  • division by zero
  • stray character beats run fault
  • unmatched closing bracket
  • unmatched opening bracket is the outer one
  • overflow reported at first digit
  • zero slots
  • section count missing
  • leading zeros
  • skipped body cannot fault
  • bad character in skipped body
  • repeated squaring
  • no negative literals
  • nested overflow
  • nested fill
The Drum-Engine of Duskforge Hold · bitwick