The Cellar of Sealed Casks
The inn at bitwick keeps a cellar with room for a fixed number of casks. Every cask has a name and a tier (an integer from 0 to 9, higher is finer), and every cask is either sealed or unsealed. When a cask arrives at a full cellar, something has to leave.
Build Cellar, constructed with capacity, an integer of 0 or more.
A cask is touched when it is successfully stored and when it is poured. Nothing else touches a cask. No two touches happen at the same moment, so "least recently touched" always names exactly one cask.
`store(name, tier)` — name is a string, tier an integer from 0 to 9. Returns a string or null:
- If a cask called
nameis already in the cellar: set its tier totier, touch it, returnnull. Nothing is evicted and its seal is unchanged. - Otherwise, if the cellar holds fewer than
capacitycasks: add it, unsealed, touch it, returnnull. - Otherwise the cellar is full. If at least one cask in it is unsealed, remove one of them — the unsealed cask of lowest tier, and among those the least recently touched — then add the arriving cask, unsealed and touched, and return the removed cask's name. The arriving cask's own tier plays no part in choosing which cask is removed.
- Otherwise (full, with no unsealed cask in it) the arriving cask is not stored at all, the cellar is unchanged, and the return value is
nameitself.
`pour(name)` — if that cask is in the cellar, touch it and return its tier (an integer). If it is not, change nothing and return -1.
`seal(name)` — if that cask is in the cellar, mark it sealed and return true; sealing an already-sealed cask still returns true. If it is not there, change nothing and return false. Sealing does not touch a cask.
`unseal(name)` — the same, but marking the cask unsealed.
`contents()` — returns the names of the casks currently in the cellar, as a list of strings, ordered by tier descending; casks of equal tier are ordered most recently touched first.
examples
- case 1
capacity 3; store "ale" at tier 2, store "mead" at tier 1, store "cider" at tier 2, pour "mead", store "perry" at tier 3the store of "perry" returns "mead" — mead has the lowest tier even though it was just poured — and contents() is ["perry", "cider", "ale"] - case 2
capacity 2; store "brine" at tier 0, store "stout" at tier 5, seal "brine", store "porter" at tier 9, seal "porter", store "small" at tier 1storing "porter" returns "stout" (brine is sealed and passed over); storing "small" returns "small", since every cask in the full cellar is sealed, and the cellar keeps porter and brine - case 3
capacity 0; store "ale" at tier 3, then contents()the store returns "ale" and contents() is the empty list
- reward
- 500 XP
- signature
Cellar
TypeScript, run as ES2022 — types are stripped, not checked. If a JS engine would run it, so will we.
- lowest tier loses before least recently touched
- sealed casks are passed over and a wholly sealed cellar refuses
- a cellar of capacity zero turns everything away
- restoring a name re-tiers it without evicting anything
- unsealing restores eligibility and the newcomer may rank lower