The Roster of the Night Watch
The wall of bitwick needs one watcher a night for the coming season, and the captain's rules for filling the roster are pinned beside the board.
Write watchRoster(nights, guards, feuds), which returns the season's roster.
The data
nights— an integer, 0 or more. The nights are numbered 1 throughnights.guards— a list of records, each with:name: a string of lowercase letters; all names are distinct,rest: an integer 0 or more, the nights of rest this guard demands after standing watch,max: an integer 0 or more, the most nights this guard will stand all season,busy: a list of night numbers this guard cannot stand (possibly empty, in any order).feuds— a list of two-element lists of names: two guards who will not stand on consecutive nights. Feuds are mutual, every name in them appears inguards, and a name may appear in several pairs.
Filling the roster
Nights are settled one at a time, from night 1 up to night nights. For night d, a guard is *eligible* when all four of these hold:
dis not in theirbusylist;- they have been given strictly fewer than
maxnights so far (that is, among nights 1 throughd-1); - they have been given no night so far, or else
d - L > rest, whereLis the latest night they were given; dis 1, or nightd-1was left unstood, or the guard who stood nightd-1is not in a feud pair with them.
Among the eligible guards, night d goes to the one who wins on the first rule that separates them:
1. fewest nights given so far; 2. longest since last on watch — a guard given no night so far beats every guard who has been given one, and between two who have been given nights, the one whose latest night L is smaller wins; 3. smallest name, compared character by character.
If no guard is eligible, night d is left unstood and no guard's record changes.
The return value
A list of length nights. The entry at position d-1 is the name of the guard who stood night d, or null (None in Python) if night d was left unstood.
examples
- case 1
nights of 6; guards ada (rest 1, max 3, busy none), bo (rest 1, max 3, busy none), cyd (rest 2, max 2, busy night 3); no feuds["ada", "bo", "ada", "cyd", "bo", "ada"] — on night 4 both ada and bo are rested enough, but cyd has stood nothing yet and so has the fewest nights - case 2
nights of 5; guards ada (rest 0, max 5, busy nights 2 and 4), bo (rest 0, max 5, busy none); feud between ada and bo["ada", null, "bo", "bo", "bo"] — night 2 is unstood, since ada is busy and bo is barred by the feud with ada who stood night 1; night 2 being unstood leaves bo free to stand night 3 - case 3
nights of 4; one guard solo (rest 1, max 3, busy none); no feuds["solo", null, "solo", null]
- reward
- 510 XP
- signature
watchRoster
TypeScript, run as ES2022 — types are stripped, not checked. If a JS engine would run it, so will we.
- six nights, three guards
- a feud leaves a night unstood
- longest rested breaks a tie of counts
- a single guard who must rest
- no guards on the board
- no nights at all