Turn a canary's hash range into router rules
Your task
A canary puts a new version of your agent on a small slice of traffic. Your router hashes each user to a number and sends the user to the canary when that number falls in the canary's range. The router cannot match a range directly. It only matches blocks, and its memory for them is short, so you want as few blocks as you can get.
Write canary_rules(bits, start, count) that returns the fewest rules that cover the canary's range exactly.
Input and output:
bits: how many bits the hash has, a whole number from 1 to 48. Hash values are the whole numbers from 0 to2 ** bits - 1.start: the first hash value in the range, a whole number in the hash space.count: how many hash values the range holds, a whole number from 1 to2 ** bits.- Return a list of rules, each
[first, size], sorted byfirst.
Rules:
- A rule
[first, size]covers the hash values fromfirsttofirst + size - 1. Itssizemust be a power of 2, andfirstmust be a multiple ofsize. So[8, 4]is a rule, and[6, 4]is not. - The range is the
counthash values in a row fromstart. Past the last hash value it carries on from 0. - The rules must cover every value in the range and no value outside it.
- Only one set of rules is the smallest, so there is one right answer.
Examples
canary_rules(bits: int, start: int, count: int) -> list[list[int]]Example 1
Input
canary_rules(4, 5, 6)Output
[[5, 1], [6, 2], [8, 2], [10, 1]]Example 2
Input
canary_rules(3, 6, 4)Output
[[0, 2], [6, 2]]Example 3
Input
canary_rules(3, 0, 8)Output
[[0, 8]]