‹ back to the board

Wednesday, November 11

Mastermulti-constraint & composite logic

The Spirit-Circle of Kelmorrow Tarn

Before every expedition into the marshes, the summoners of the Ashgrove Conclave chalk a binding-circle on the shore of Kelmorrow Tarn. The circle can hold only so many spirits at once. The Conclave offers a bounty to any keeper who can say, at every moment, which spirits remain bound and which are lost.

Implement the class SpiritCircle. Each spirit has a unique name (a non-empty string) and a rank (an integer). A bound spirit may also be sealed.

Methods

  • constructor(capacity): capacity is a non-negative integer, the maximum number of spirits bound at once. The circle starts empty.
  • summon(name, rank) returns a string or null.
  • If name is already bound, its rank becomes rank and this counts as a use. It stays sealed or unsealed as it was. Return null. This case never evicts anyone.
  • Otherwise, if fewer than capacity spirits are bound, bind it unsealed with rank rank. This counts as a use. Return null.
  • Otherwise the circle is full. The candidate is the unsealed bound spirit with the lowest rank. If several share that lowest rank, the candidate is the one whose most recent use is earliest.
  • If no bound spirit is unsealed, or rank is lower than the candidate's rank, the newcomer is turned away. Nothing changes, and the method returns name (the newcomer's own name).
  • Otherwise, remove the candidate and bind the newcomer unsealed. This counts as a use. Return the candidate's name.
  • call(name) returns an integer.
  • If name is bound, return its rank. This counts as a use, and the call removes the spirit's seal if it had one.
  • If name is not bound, return -1 and change nothing.
  • seal(name) returns a boolean.
  • If name is bound, it becomes sealed (it stays sealed if it already was), and the method returns true.
  • Otherwise, return false.
  • dismiss(name) returns a boolean.
  • If name is bound, remove it whether sealed or not, and return true.
  • Otherwise, return false.
  • roster() returns a list of the names currently bound, sorted in ascending order by character code.

Recency

Only the summon and call outcomes marked above as counting as a use update a spirit's most recent use. Each such use is later than every use before it. Sealing, dismissing, listing the roster, a turned-away summon and a call on an unbound name are not uses. A spirit that is dismissed or removed and later summoned again is a fresh binding: unsealed, with its new rank.

  • stateful objects with eviction rules
  • Master

examples

  1. case 1capacity 2; summon ash (rank 3), summon brine (rank 5), summon cinder (rank 4)the third summon evicts ash and returns "ash"; roster is ["brine", "cinder"]
  2. case 2capacity 2; summon quill (rank 1), summon rook (rank 9), seal quill, summon sorrow (rank 3)sorrow is turned away and summon returns "sorrow": the only unsealed spirit, rook, outranks it, and the weaker quill is sealed
  3. case 3capacity 2; summon yarrow (rank 2), summon zephyr (rank 8), seal yarrow, call yarrow, summon alder (rank 5)call returns 2 and breaks the seal, so summon alder evicts yarrow and returns "yarrow"
  4. case 4capacity 0; summon flint (rank 7)"flint" (turned away); roster stays []
reward
540 XP
signature
SpiritCircle
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…
  • lowest rank is evicted
  • equal ranks fall to least recently used
  • rank outweighs recency
  • weaker newcomer is turned away, equal rank displaces
  • sealed spirit is ignored when choosing the candidate
  • all sealed turns every newcomer away
  • calling breaks the seal
  • re-summon updates rank and recency but keeps seal
  • capacity zero holds nothing
  • dismiss frees a place and rebinding is fresh
The Spirit-Circle of Kelmorrow Tarn · bitwick