The Binding Circle of Ysmerra Spire
The summoners of Ysmerra Spire hold wild spirits in a chalk binding circle that has room for only so many at once. The Conclave of the Spire posts a bounty for a warden's ledger. The ledger must track which spirits are bound, which have slipped free when their term ran out, and which must be cast out when a new spirit is drawn in.
Write a class BindingCircle. Its constructor takes capacity, an integer >= 0: the most spirits that may be present at once.
Every method takes the current time t, an integer. t never decreases from one call to the next, though several calls may share the same t.
Terms. A spirit bound at time t with duration d (an integer >= 1) is *present* at every time x with t <= x < t + d. At time t + d it is gone, and a gone spirit is forgotten entirely.
Each present spirit has three properties:
- a power;
- a summon count;
- a last-touched mark.
A spirit is *touched* by a bind or by a successful summon. Recency is decided by the order in which operations were made, not by t.
Methods:
bind(name, power, duration, t)returns a string.- If
nameis present att: set its power topowerand its term to end att + duration, and mark it touched. Its summon count is unchanged. Nothing is evicted. Return"". - Otherwise, if
capacityis0: store nothing and return"". - Otherwise, if the number of spirits present at
tequalscapacity: evict one present spirit. Choose the one with the fewest summons; break ties by the one touched least recently. Then bind the new spirit with summon count0, mark it touched, and return the evicted spirit's name. - Otherwise: bind the new spirit with summon count
0, mark it touched, and return"". - Spirits that left because their term ended are never reported as evicted.
summon(name, t)returns an integer.- If
nameis present att: increase its summon count by 1, mark it touched, and return its power. - Otherwise: return
-1and change nothing. count(t)returns the number of spirits present att.
Names are non-empty strings. Powers are non-negative integers.
examples
- case 1
capacity 2; at t=0 bind Ash (power 5, duration 100); at t=1 bind Bram (power 7, duration 100); at t=2 summon Ash; at t=3 bind Cinder (power 9, duration 100)summon Ash returns 5; bind Cinder returns "Bram" (Bram has 0 summons, Ash has 1) - case 2
capacity 2; at t=0 bind Ash and bind Bram (duration 50 each); at t=1 summon Ash; at t=2 summon Bram; at t=3 bind Cinderbind Cinder returns "Ash": both have 1 summon, and Ash was touched less recently - case 3
capacity 2; at t=0 bind Ash (power 4, duration 5) and Bram (power 6, duration 100); at t=5 summon Ash; at t=6 bind Cindersummon Ash returns -1 because Ash's term ended at t=5; bind Cinder returns "", since Ash left on its own and there was room - case 4
capacity 0; bind Ash (power 1, duration 10) at t=0; summon Ash at t=1; count at t=1bind returns "", summon returns -1, count returns 0
- reward
- 540 XP
- signature
BindingCircle
TypeScript, run as ES2022 — types are stripped, not checked. If a JS engine would run it, so will we.
- fewest summons is evicted
- tie broken by least recent touch
- rebind refreshes recency and power
- expired spirits leave quietly at the boundary
- rebinding after expiry resets summons
- rebinding a present spirit keeps its summons
- rebind renews the term
- capacity zero holds nothing
- capacity one always evicts the sole spirit