PracHub
QuestionsCoachesLearningGuidesInterview Prep

Quick Overview

This question tests practical algorithm design around greedy distribution with per-element constraints and iterative redistribution. It evaluates a candidate's ability to handle integer division edge cases, tie-breaking rules, and simulation-style problems commonly found in coding interviews for software engineering roles.

  • medium
  • Gusto
  • Coding & Algorithms
  • Software Engineer

Fairly Distribute Money With Limits

Company: Gusto

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

# Fairly Distribute Money With Limits You are given an integer `amount` representing a total sum of money to distribute, and a list of `employees`. Each employee is described by: - `name` — a unique string identifier. - `limit` — a non-negative integer giving the maximum amount that person is allowed to receive. Distribute the entire `amount` (when possible) among the employees subject to these rules: 1. **Cap rule.** No employee may receive more than their `limit`. 2. **Even distribution.** The money is shared as evenly as possible among the employees who have not yet reached their cap. 3. **Redistribution.** When an employee hits their `limit`, any money they cannot accept is redistributed among the remaining employees who still have room — again, as evenly as possible. Return a mapping from each employee `name` to the integer amount they receive. ## Distribution semantics Because the amount is an integer and must be split as evenly as possible, distribute in **whole units** so that the result is deterministic: - At each step, consider only employees whose current allocation is still below their `limit` (the "active" set). - Give each active employee an equal whole-unit share of the remaining money. If the remaining money does not divide evenly across the active set, the leftover indivisible units (`remaining % active_count` of them) are handed out one extra unit at a time to the active employees **in ascending order of `name`** (lexicographic), so that the tie-break is fully specified. - Whenever an employee reaches their `limit`, they leave the active set and their unused share returns to the pool to be redistributed in the next step. - Stop when either all money is distributed or every employee has reached their `limit`. If the total of all limits is less than `amount`, every employee receives exactly their `limit` and `amount - sum(limits)` units remain undistributed (they are simply not assigned to anyone). ## Input / Output - `amount`: integer, `0 <= amount <= 10^9`. - `employees`: a list of `(name, limit)` pairs. Names are unique. `0 <= limit <= 10^9`. The list has between `1` and `10^5` employees. Return a dictionary (map) from `name` to the integer amount that name receives. Every employee name in the input must appear in the output, including those who receive `0`. ## Examples **Example 1** ``` amount = 100 employees = [("Alice", 50), ("Bob", 50), ("Carol", 50)] ``` Output: ``` {"Alice": 34, "Bob": 33, "Carol": 33} ``` Each person could take up to 50, so no cap binds. 100 split three ways is 33 each with 1 unit left over; the leftover unit goes to the lexicographically smallest name, `Alice`. **Example 2** ``` amount = 100 employees = [("Alice", 10), ("Bob", 100), ("Carol", 100)] ``` Output: ``` {"Alice": 10, "Bob": 45, "Carol": 45} ``` An even 3-way split would give each about 33, but `Alice` is capped at 10. `Alice` takes 10, then the remaining 90 is split evenly between `Bob` and `Carol`, giving 45 each. **Example 3** ``` amount = 5 employees = [("Alice", 1), ("Bob", 1)] ``` Output: ``` {"Alice": 1, "Bob": 1} ``` Total limits sum to 2, which is less than 5. Each gets their cap of 1, and 3 units remain undistributed.

Quick Answer: This question tests practical algorithm design around greedy distribution with per-element constraints and iterative redistribution. It evaluates a candidate's ability to handle integer division edge cases, tie-breaking rules, and simulation-style problems commonly found in coding interviews for software engineering roles.

You are given an integer `amount` (the total money to distribute) and a list of `employees`, each a `(name, limit)` pair where `name` is a unique string and `limit` is the maximum that person may receive. Distribute the money in whole units, as evenly as possible, subject to a per-person cap. **Rules** 1. **Cap.** No employee may receive more than their `limit`. 2. **Even split.** At each step, give every *active* employee (one whose current allocation is still below their `limit`) an equal whole-unit share of the money that still remains. 3. **Deterministic remainder.** If the remaining money does not divide evenly across the active set, the `remaining % active_count` leftover indivisible units are handed out one extra unit at a time to active employees in **ascending lexicographic order of `name`**. 4. **Redistribution.** Whenever an employee reaches their `limit`, they leave the active set and any money they could not accept returns to the pool to be redistributed in the next step. 5. **Stop** when either all the money is distributed or every employee has reached their `limit`. If `sum(limits) < amount`, everyone gets exactly their `limit` and `amount - sum(limits)` units are left undistributed (assigned to no one). Return a mapping from each `name` to the integer amount they receive. Every input name must appear in the output, including those receiving `0`. **Constraints** - `0 <= amount <= 10^9` - `1 <= len(employees) <= 10^5`, names unique - `0 <= limit <= 10^9` **Example 1** — `amount = 100`, `employees = [("Alice",50),("Bob",50),("Carol",50)]` → `{"Alice":34,"Bob":33,"Carol":33}` (no cap binds; 100/3 = 33 each, the 1 leftover unit goes to the lexicographically smallest name `Alice`). **Example 2** — `amount = 100`, `employees = [("Alice",10),("Bob",100),("Carol",100)]` → `{"Alice":10,"Bob":45,"Carol":45}` (Alice caps at 10; the remaining 90 splits evenly between Bob and Carol). **Example 3** — `amount = 5`, `employees = [("Alice",1),("Bob",1)]` → `{"Alice":1,"Bob":1}` (total limits = 2 < 5; each gets their cap of 1 and 3 units remain undistributed).

Constraints

  • 0 <= amount <= 10^9
  • 1 <= number of employees <= 10^5
  • 0 <= limit <= 10^9
  • All names are unique strings.
  • Allocations and all intermediate sums fit in 64-bit integers.

Examples

Input: (100, [("Alice", 50), ("Bob", 50), ("Carol", 50)])

Expected Output: {"Alice": 34, "Bob": 33, "Carol": 33}

Explanation: No cap binds. 100 // 3 = 33 each, with 1 leftover unit going to the lexicographically smallest name, Alice.

Input: (100, [("Alice", 10), ("Bob", 100), ("Carol", 100)])

Expected Output: {"Alice": 10, "Bob": 45, "Carol": 45}

Explanation: Alice caps at 10; the remaining 90 is split evenly between Bob and Carol, 45 each.

Input: (5, [("Alice", 1), ("Bob", 1)])

Expected Output: {"Alice": 1, "Bob": 1}

Explanation: sum(limits) = 2 < 5. Each gets their cap of 1 and 3 units remain undistributed.

Input: (0, [("Solo", 1000)])

Expected Output: {"Solo": 0}

Explanation: Edge case: nothing to distribute, so the only employee receives 0 but still appears in the output.

Input: (7, [("Alice", 2), ("Bob", 2), ("Carol", 2)])

Expected Output: {"Alice": 2, "Bob": 2, "Carol": 2}

Explanation: Total limits = 6 < 7; everyone caps at 2 and the remaining 1 unit is left undistributed.

Input: (10, [("Bob", 3), ("Alice", 100), ("Carol", 100)])

Expected Output: {"Bob": 3, "Alice": 4, "Carol": 3}

Explanation: First round of 10/3 = 3 each caps Bob at 3; the 1 leftover unit goes to lex-smallest Alice. The 1 unit Bob couldn't take... here Bob exactly hits 3, so remaining 7 over Alice+Carol gives 4 (lex-smallest Alice) and 3.

Input: (1, [("Zed", 5), ("Amy", 5)])

Expected Output: {"Zed": 0, "Amy": 1}

Explanation: A single indivisible unit (share = 0, extra = 1) goes to the lexicographically smallest active name, Amy.

Input: (1000000000, [("X", 1000000000)])

Expected Output: {"X": 1000000000}

Explanation: Boundary: a single employee absorbs the full 10^9 since their limit allows it.

Hints

  1. Simulate in rounds. In each round, only the 'active' employees (those still below their limit) share the money that remains.
  2. Split evenly with integer division: each active employee gets floor(remaining / active_count). The leftover remaining % active_count units must go somewhere deterministic.
  3. Hand the leftover units out one at a time to active employees in ascending lexicographic order of name — pre-sorting the indices by name once makes this clean.
  4. When an employee's share would exceed their remaining room, give them only their room; the unused part stays in the pool and is redistributed next round. Stop when nothing remains or no one is active.
Last updated: Jun 24, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.