‹ back to the board

Thursday, September 24

Mastermulti-constraint & composite logic

The Weaver's Warp Card

The mill above bitwick stores every pattern on a punched warp card, and the cards that come back from the villages are written any old way. The weaver wants each one rewritten in the mill's own hand.

card is a string. Read it left to right as a sequence of blocks. A block is an optional count — one or more decimal digits, leading zeros allowed — followed by a unit. A unit is either a single lowercase letter, or one or more lowercase letters enclosed in square brackets. A block with no count has a count of 1. A block contributes its unit's letters repeated *count* times; a count of 0 contributes nothing. The card's thread is the contribution of every block, joined in order. An empty card has an empty thread.

A card is malformed if it does not split exactly into such blocks. That includes: any character other than a–z, 0–9, [, ]; a run of digits not immediately followed by a unit; a [ with no later ]; a ] with no open [; an empty pair of brackets; and anything other than lowercase letters between brackets.

Write canonicalCard(card). If the card is malformed, return the null value of your language (null in TypeScript, None in Python). Otherwise return a string: the mill's canonical writing of the thread, built like this.

  • Cut the thread into maximal runs of one repeated letter.
  • Cut each run of length L into pieces: if L is 9 or less it is a single piece of length L; otherwise take pieces of 9 from the left until 9 or fewer letters remain, and that remainder is the last piece.
  • Write a piece of length 1 or 2 as that many copies of the letter. Write a piece of length 3 to 9 as the single digit, then the letter.
  • Concatenate the pieces of every run, in order.

Every count in card has value at most 999, and the thread is at most a few thousand letters.

  • format round-tripping
  • Master

examples

  1. case 1card of "aa0ba""3a" — the zero count drops the b, so the a's on either side form one run of three
  2. case 2card of "12a""9a3a" — a run of twelve is cut into a piece of nine and a piece of three
  3. case 3card of "2[ab]bb""aba3b" — the thread is ababbb, whose runs are a, b, a, and bbb
  4. case 4card of "a[]b"null in TypeScript, None in Python — empty brackets are malformed
reward
540 XP
signature
canonicalCard
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 thread needs no counts
  • bracket group repeats
  • zero count joins its neighbours
  • run of twelve splits after nine
  • run of ten leaves a single letter
  • nineteen makes two nines and a single
  • ninety-nine is eleven nines
  • leading zeros in a count
  • runs merge across blocks
  • repeated bracket body forms one run
  • empty card
  • everything cancels
  • unmatched open bracket
  • nested bracket
  • digit inside brackets
  • count with no unit
  • empty brackets
  • stray close bracket
  • capital is not thread
The Weaver's Warp Card · bitwick