‹ back to the board

Tuesday, September 8

Mastermulti-constraint & composite logic

The Surveyor's Crooked Field Notes

Pinned by the door, in a surveyor's hand.

The terraces above bitwick were levelled last autumn, one line of the notebook per measurement, each line saying how high one stone sits relative to another. Rain got into the book: some lines can no longer be read as measurements at all, and some disagree with lines written earlier. The stonewright needs the differences that still hold.

Write resolveLevels(notes, queries). notes is a list of strings; queries is a list of two-element lists of strings. Return a list with one entry per query, in order — each entry an integer or null (None in Python).

Well-formed notes. Split a note on single space characters (so "a b" yields three pieces, the middle one empty). The note is well-formed only if this yields exactly five pieces t0 t1 t2 t3 t4 with:

  • t0 and t4 non-empty — the two stone names, compared exactly;
  • t1 equal to is;
  • and either t2 a run of one or more digits 0–9 (leading zeros allowed) together with t3 equal to above or below, or t2 equal to level together with t3 equal to with.

A well-formed note asserts, writing h for height in hands and n for the value of t2:

  • A is n above B: h(A) = h(B) + n
  • A is n below B: h(A) = h(B) − n
  • A is level with B: h(A) = h(B)

Accepting. Work through notes in order. Ignore any note that is not well-formed. Ignore any well-formed note whose assertion contradicts the assertions already accepted; a note that merely restates something already forced is accepted. An ignored note has no effect whatsoever.

Answering. For a query [A, B], the entry is h(A) − h(B) when the accepted notes force that value, and null when they do not. If A and B are the same string, the entry is 0, even when that name appears in no accepted note.

  • constraint resolution
  • Master

examples

  1. case 1notes of ["forge is 3 above well", "well is level with dock"], queries of [["forge", "dock"], ["forge", "kiln"]][3, null] — the forge is fixed 3 hands above the dock; nothing ties the kiln to anything
  2. case 2notes of ["a is 5 above b", "b is 5 above a", "b is 1 above c"], queries of [["a", "c"]][6] — the second note contradicts the first and is struck out, but the third is still accepted, so a sits 5 + 1 above c
  3. case 3notes of ["a is 3 under b", "a is 3 above b", "a is 3 above b extra"], queries of [["a", "b"]][null] — the first uses an unknown word, the second splits into six pieces because of the double space, the third into six pieces as well; nothing is accepted
  4. case 4notes of ["tower is 4 above tower"], queries of [["tower", "tower"], ["tower", "cellar"]][0, null] — the note contradicts itself and is dropped, yet a stone is always level with itself
reward
510 XP
signature
resolveLevels
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…
  • chain of terraces
  • a later note contradicts, the earlier one survives
  • smudged lines are struck out
  • empty notebook
  • a stone measured against itself
  • a bridge that disagrees with the joined frames
The Surveyor's Crooked Field Notes · bitwick