Hash Bucket A/B Assignment
Background
Deterministic A/B assignment hashes each unit (user, session, cookie) into a stable bucket. The same unit always gets the same arm — that's what makes the experiment persistent for each user across visits, sessions, devices.
Problem statement
Implement assign(unit_id, experiment_id, pct_a=0.5). Hash the tuple (unit_id, experiment_id) deterministically; treat the first byte of the SHA-256 digest as a uniform value in ; assign to "A" if the byte / 256 < pct_a, otherwise "B".
Input
unit_id—str, the assignment unit.experiment_id—str, identifies the experiment.pct_a—floatin , fraction of traffic to arm A (default0.5).
Output
Returns "A" or "B".
Examples
Example 1 — same input → same arm
Input: ("user_1", "exp_1")
Output: same arm every call
Example 2 — different experiments give different arms
Input: fixed user, varying experiment_id
Output: across 20 experiments, both arms are observed
Example 3 — roughly 50/50 at default pct_a
Input: 1000 distinct users
Output: count in each arm ≈ 500 (within ±100)
Example 4 — pct_a = 0 → all B; pct_a = 1 → all A
Constraints
- Deterministic: same
(unit_id, experiment_id)→ same arm across runs. - Hashing scheme:
SHA-256(unit_id + "|" + experiment_id), take first byte. pct_ain .
Notes
- Why include experiment_id in the hash. Without it, the same user would land in the same arm for every experiment — destroying the independence between concurrent experiments.
- Bucketing granularity. Using only the first byte gives 256 buckets — enough for any reasonable split. For very fine splits (0.01% canaries), use more bytes.
▶ Run executes the 3 visible sample tests below in your browser. Submit runs the full suite — including hidden tests — on the server for an official verdict.
- •Reference example: deterministic arm for a fixed unit and experiment
- •Sample: assignment for (alice, checkout_test)
- •Example: pct_a=1.0 always assigns arm A