The Gate of Twenty-Six Dials
The north gate of bitwick is held shut by twenty-six brass dials, lettered a through z. Every dial stands at 0 when the gate is locked. A traveller hands the gatekeeper an inscription; the gate opens to the single number the inscription reads out.
readGate(expr) takes the inscription as a string and returns its value as an integer.
Tokens. expr holds only digits, lowercase letters a-z, the characters + - * ^ = ,, round brackets, and spaces. Spaces may sit anywhere between tokens and mean nothing. A run of digits is a non-negative literal. A single letter names a dial and reads its current value.
Forms, listed from loosest-binding to tightest:
x , y— left-associative. Evaluatex, theny; the value is the value ofy.d = x— right-associative. Store the value ofxin diald; the value is that stored number.x + yandx - y— left-associative sum and difference.x * y— left-associative product.- x— prefix negation, and it may be stacked.x ^ y— right-associative.xraised to the powery.
So prefix negation binds looser than ^, and ^ binds tighter than every other form. Brackets ( ... ) may enclose any inscription, including one that contains , or =, and a bracketed inscription is an operand like any other.
Order of evaluation. Operands are evaluated left to right, and a write to a dial takes effect at once, so any operand evaluated later reads what an earlier one stored.
Guarantees. expr is non-empty and well-formed. The complete left operand of every = is a bare dial letter. Every exponent (the right operand of ^) evaluates to an integer from 0 to 12, and every value that arises stays within ±1000000000.
Return the integer value of the whole inscription.
examples
- case 1
expr of "-2 ^ 2"-4 (the raising happens first, then the negation) - case 2
expr of "a = b = 3, a + b"6 - case 3
expr of "a = 2, a * (a = 3) + a"9 (the left factor read 2, the right factor stored 3, and the final a reads 3) - case 4
expr of "q"0 (a dial never written still stands at 0)
- reward
- 540 XP
- signature
readGate
TypeScript, run as ES2022 — types are stripped, not checked. If a JS engine would run it, so will we.
- plain precedence
- power outranks negation and leans right
- assignment chains rightward
- a write seen by a later operand
- unwritten dial reads zero
- single literal
- stacked negation and bracketed product
- no spaces, repeated writes
- sequence inside brackets
- assignment looser than arithmetic
- zero exponent and negated factor