This article dismantles a pervasive fallacy in DevOps pipeline optimization: the assumption that adding more workers (build agents, test runners, deployment slots) linearly reduces total work time. It reframes pipeline throughput as a rate problem — work completed per unit time — not a duration problem.
★
Imagine you and your friend are painting a fence.
The core insight is that work is a rate, not a duration, and that naive aggregation of individual worker rates leads to incorrect predictions when workers join mid-job, subtract work (e.g., cleanup tasks), or have unequal efficiency. The article draws directly from the classic 'pipes and cisterns' math used in competitive programming and operations research, applying it to real-world CI/CD scenarios like staged deployments, parallel test execution with dependencies, and multi-phase builds where late-joining workers cannot contribute to already-completed stages.
It explicitly addresses when the additive rate myth fails: when work is sequential, when workers have different throughput, or when a worker's contribution is negative (e.g., a rollback or cleanup step). For DevOps engineers, this is the difference between believing '4 agents = 4x faster' and understanding that in a pipeline with three sequential stages, the fourth agent is idle until the third stage starts.
The article is essential for anyone designing build farms, optimizing parallel test suites, or debugging why adding more runners to a CI system yields diminishing returns.
Plain-English First
Imagine you and your friend are painting a fence. You can finish it alone in 4 hours, your friend in 6 hours. If you both paint together, how long does it take? Work and Time problems are exactly this — figuring out how long a job takes when one or more workers (or pipes, or machines) are doing it together or in turns. The key insight is: instead of thinking about the whole job, think about what fraction of the job gets done every single hour.
Work and Time problems show up in almost every aptitude test, placement exam, and technical interview screening round. They're not just academic puzzles — scheduling systems, CI/CD pipeline parallelism, database query optimization, and resource planning all rely on the same underlying math. When a tech lead estimates that splitting a task across three developers will cut delivery time, they're doing work and time arithmetic in their head. Getting fluent at this isn't optional if you want to ace quantitative rounds.
The reason most people struggle with these problems is that they try to memorize a dozen different formulas for a dozen different scenarios. That's the wrong approach. Every work and time problem — no matter how twisted — collapses into one core idea: work = rate × time. Once you see that, you stop memorizing and start reasoning. The formula variations you'll see in exams are just algebraic rearrangements of that single equation.
By the end of this article you'll be able to solve problems involving single workers, combined workers, workers joining midway, pipes filling and draining tanks, and efficiency-based problems — all from first principles. You'll also see the three mistakes that cost candidates marks even after they understand the concept, and you'll walk away with a mental model that's fast enough to use under exam pressure.
Why Work-Time Problems Are Just Rate Aggregation
Work-time problems reduce to a single mechanic: given a total work unit W and a set of agents each working at a constant rate r_i (units per unit time), the combined rate is the sum of individual rates. If Alice completes a job in 6 hours, her rate is 1/6 job/hour. Bob at 3 hours gives 1/3 job/hour. Together, they finish in 1 / (1/6 + 1/3) = 2 hours. That's it — the entire class of problems is just harmonic mean of times disguised as additive rates.
In practice, the key property is that rates add linearly, but times do not. Doubling the number of identical workers halves the time only if work is perfectly parallelizable — a dangerous assumption in real systems. The formula T = W / Σ r_i holds only when agents work independently on disjoint subtasks with zero coordination overhead. Any contention, shared resources, or sequential dependencies breaks the additive rate model.
Use this model when you need a first-order estimate for embarrassingly parallel work: batch processing, stateless microservice scaling, or CI/CD pipeline stage parallelism. It fails the moment you introduce locks, network I/O contention, or a single-threaded bottleneck. In DevOps, the classic trap is assuming two build agents cut build time in half — they don't when the linker or test database is a serial choke point.
The Parallelism Fallacy
Additive rates assume zero coordination cost. In real pipelines, adding workers often yields sublinear speedup due to resource contention — Amdahl's Law applies.
Production Insight
CI pipeline with 4 build agents still taking 45 minutes per commit because all agents wait on the same shared artifact repository write lock.
Symptom: build time plateaus after 2 agents; adding more agents increases queue wait but not throughput.
Rule of thumb: measure per-agent throughput before adding agents; if rate per agent drops, you've hit a shared resource bottleneck.
Key Takeaway
Work-time is rate aggregation: sum rates, not times.
Additive rate model assumes perfect parallelism — verify independence before applying.
In real systems, always check for serial bottlenecks (Amdahl's Law) before scaling workers.
thecodeforge.io
Work as Rate, Not Duration in DevOps Pipelines
Work Time Problems Aptitude
The One Core Idea: Work as a Rate, Not a Duration
Most people read 'A can finish a job in 10 days' and think of 10 days as the answer to something. Flip that instinct. The useful number is 1/10 — the fraction of the job A completes in ONE day. That single conversion unlocks every problem in this category.
Why think in fractions? Because fractions add cleanly. If A does 1/10 of the job per day and B does 1/15 per day, together they do 1/10 + 1/15 per day. You find a common denominator, add, and invert to get the combined time. No exotic formula needed — just fraction addition.
This 'rate-first' thinking also protects you in problems where workers join at different times or where a pipe drains while another fills. You track rates, multiply by the time each rate was active, and the fractions of work done must sum to 1 (one complete job). That constraint — total work = 1 — is your equation in every single problem.
Commit this to muscle memory: if a person completes a job in N days, their daily work rate is 1/N. Everything else is algebra.
work_rate_fundamentals.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# ─────────────────────────────────────────────────────────────────# Work and Time — Core Rate Model# TheCodeForge.io# ─────────────────────────────────────────────────────────────────# PROBLEM: Alice finishes a report in 10 days, Bob in 15 days.# How long do they take working together?from fractions importFraction# Step 1 — Convert durations to daily work RATES (fraction of job per day)
alice_daily_rate = Fraction(1, 10) # Alice does 1/10 of the job each day
bob_daily_rate = Fraction(1, 15) # Bob does 1/15 of the job each day# Step 2 — Combined rate is simply the sum of individual rates# (They work in parallel, so their contributions add up each day)
combined_rate = alice_daily_rate + bob_daily_rate
print(f"Alice's daily rate : {alice_daily_rate} (= {float(alice_daily_rate):.4f} of the job)")
print(f"Bob's daily rate : {bob_daily_rate} (= {float(bob_daily_rate):.4f} of the job)")
print(f"Combined daily rate: {combined_rate} (= {float(combined_rate):.4f} of the job)")
# Step 3 — Time = Total Work / Rate# Total work is always 1 (one complete job)
total_work = Fraction(1)
days_together = total_work / combined_rate # 1 ÷ (1/6) = 6print(f"\nDays to finish together: {days_together} days")
print(f"In decimal : {float(days_together):.2f} days")
# ─────────────────────────────────────────────────────────────────# BONUS: Verify by checking work done in 6 days# ─────────────────────────────────────────────────────────────────
alice_work_done = alice_daily_rate * days_together
bob_work_done = bob_daily_rate * days_together
total_done = alice_work_done + bob_work_done
print(f"\nVerification:")
print(f" Alice's share in {days_together} days: {alice_work_done}")
print(f" Bob's share in {days_together} days : {bob_work_done}")
print(f" Total work done : {total_done} ✓") # Must equal 1
Output
Alice's daily rate : 1/10 (= 0.1000 of the job)
Bob's daily rate : 1/15 (= 0.0667 of the job)
Combined daily rate: 1/6 (= 0.1667 of the job)
Days to finish together: 6 days
In decimal : 6.00 days
Verification:
Alice's share in 6 days: 3/5
Bob's share in 6 days : 2/5
Total work done : 1 ✓
Speed Shortcut:
For two workers with times A and B, the combined time is (A × B) / (A + B). It looks like a new formula but it's just the fraction addition done in one step. Derive it once on paper and you'll never need to memorize it — you'll just know why it works.
Workers Joining Mid-Job — The Staged Work Pattern
Exam questions love to introduce complexity by having workers join or leave partway through. These look scary but the strategy is identical: track how much work each worker completes in their active window, make sure all the fractions sum to 1.
Break the timeline into stages. In each stage, identify who is working and for how long. Calculate the fraction of work done in each stage. Set the sum equal to 1 and solve for the unknown.
A classic variant: 'A works alone for some days, then B joins and they finish together.' You don't know when B joined — that's what you're solving for. Let the unknown be the number of days A worked alone. Write the equation, solve it. The algebra is simple once the setup is clear.
Another variant flips it: both start together, then one leaves. Same logic — two stages, two rate-time products, sum to 1. The only thing changing between problem variants is who is active in each stage. The mathematical skeleton never changes.
staged_work_problem.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# ─────────────────────────────────────────────────────────────────# Staged Work Problem — Worker Joins Mid-Job# TheCodeForge.io# ─────────────────────────────────────────────────────────────────# PROBLEM:# Carlos can build a website alone in 12 days.# Diana can build it alone in 8 days.# Carlos starts alone. After some days, Diana joins.# They finish the rest together. Total time = 9 days.# How many days did Carlos work alone before Diana joined?from fractions importFraction
carlos_rate = Fraction(1, 12) # Carlos completes 1/12 of the site per day
diana_rate = Fraction(1, 8) # Diana completes 1/8 of the site per day
total_days = 9# We know the project finished in 9 days total# ── Setup ────────────────────────────────────────────────────────# Let 'd' = number of days Carlos worked ALONE.# Then Diana joined and they worked TOGETHER for (9 - d) days.## Work done by Carlos alone + Work done together = 1# carlos_rate * d + (carlos_rate + diana_rate) * (9 - d) = 1## Solve for d:
combined_rate = carlos_rate + diana_rate
print(f"Carlos daily rate : {carlos_rate}")
print(f"Diana daily rate : {diana_rate}")
print(f"Combined daily rate: {combined_rate}")
# Expanding the equation:# (1/12)*d + (5/24)*(9 - d) = 1# (1/12)*d + (45/24) - (5/24)*d = 1# d*(1/12 - 5/24) = 1 - 45/24# d*(2/24 - 5/24) = 24/24 - 45/24# d*(-3/24) = -21/24# d = (-21/24) / (-3/24) = 7# Let's compute it programmatically step by step# Work equation: carlos_rate*d + combined_rate*(9-d) = 1# => d*(carlos_rate - combined_rate) = 1 - combined_rate*9
rhs = Fraction(1) - combined_rate * total_days # Right-hand side
lhs_coefficient = carlos_rate - combined_rate # Coefficient of d
days_alone = rhs / lhs_coefficient
days_together = total_days - days_alone
print(f"\nCarlos worked alone for : {days_alone} days")
print(f"Both worked together for : {days_together} days")
# ── Verification ─────────────────────────────────────────────────
work_by_carlos_alone = carlos_rate * days_alone
work_done_together = combined_rate * days_together
total = work_by_carlos_alone + work_done_together
print(f"\nVerification:")
print(f" Work done by Carlos alone : {work_by_carlos_alone}")
print(f" Work done together : {work_done_together}")
print(f" Total : {total} ✓")
Output
Carlos daily rate : 1/12
Diana daily rate : 1/8
Combined daily rate: 5/24
Carlos worked alone for : 7 days
Both worked together for : 2 days
Verification:
Work done by Carlos alone : 7/12
Work done together : 5/12
Total : 1 ✓
Interview Gold:
Whenever a problem says 'they finish in X days total,' that X is almost always the lever you use to build your equation. Write 'total work = 1' on your scratch paper first, then fill in the stages. It forces the right structure every time.
Pipes and Cisterns — When a Worker Subtracts Work
Pipes and cisterns problems are work-and-time problems wearing a disguise. An inlet pipe filling a tank is exactly like a worker doing positive work. An outlet pipe (leak) draining the tank is a worker doing negative work — it un-does progress.
The model is identical: convert each pipe's time to a rate (fraction of tank per hour), assign inlet pipes a positive rate and outlet pipes a negative rate, sum all rates, and invert to find total time.
The one extra wrinkle is the 'leak' problem: a full tank empties in X hours when the drain is open alongside the inlet. Here you know the net rate (zero progress if the tank stays full, or slow fill/drain if it doesn't) and solve for the unknown pipe's rate. Always label clearly which rates are positive and which are negative before writing any equation — that's the step where most errors creep in.
Real-world resonance: this is exactly how engineers model fluid systems, battery charge/discharge rates, and even request queues where work arrives and gets processed simultaneously.
pipes_and_cisterns.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# ─────────────────────────────────────────────────────────────────# Pipes and Cisterns — Inlet, Outlet and Leak Problems# TheCodeForge.io# ─────────────────────────────────────────────────────────────────from fractions importFraction# ── PROBLEM 1: Two inlets, one outlet ────────────────────────────# Pipe A fills the tank in 6 hours (POSITIVE — adds water)# Pipe B fills the tank in 4 hours (POSITIVE — adds water)# Pipe C drains the tank in 12 hours (NEGATIVE — removes water)# All three are open. How long to fill an empty tank?print("=" * 50)
print("PROBLEM 1: Two inlets + one outlet")
print("=" * 50)
pipe_a_rate = Fraction(1, 6) # fills 1/6 of tank per hour
pipe_b_rate = Fraction(1, 4) # fills 1/4 of tank per hour
pipe_c_rate = -Fraction(1, 12) # drains 1/12 of tank per hour (NEGATIVE)
net_rate = pipe_a_rate + pipe_b_rate + pipe_c_rate
print(f"Pipe A rate : +{pipe_a_rate} per hour")
print(f"Pipe B rate : +{pipe_b_rate} per hour")
print(f"Pipe C rate : {pipe_c_rate} per hour (drain)")
print(f"Net rate : {net_rate} per hour")
if net_rate > 0:
time_to_fill = Fraction(1) / net_rate # Total work (1 full tank) / rateprint(f"Time to fill: {time_to_fill} hours = {float(time_to_fill):.2f} hours")
else:
print("Tank will never fill — outlet is too fast!")
# ── PROBLEM 2: The leak problem ───────────────────────────────────# A tank has an inlet pipe that fills it in 9 hours.# Due to a leak at the bottom, it actually takes 12 hours to fill.# How long would the leak alone take to empty a FULL tank?print("\n" + "=" * 50)
print("PROBLEM 2: Finding the leak rate")
print("=" * 50)
inlet_rate = Fraction(1, 9) # inlet fills 1/9 per hour
net_fill_rate = Fraction(1, 12) # actual observed fill rate (with leak)# net_fill_rate = inlet_rate + leak_rate# => leak_rate = net_fill_rate - inlet_rate (will be negative)
leak_rate = net_fill_rate - inlet_rate
print(f"Inlet rate (fills) : +{inlet_rate} per hour")
print(f"Observed net rate : {net_fill_rate} per hour")
print(f"Leak rate (drains) : {leak_rate} per hour")
# leak_rate is negative — take absolute value to get drain time
leak_empty_time = Fraction(1) / abs(leak_rate)
print(f"\nLeak alone empties the full tank in: {leak_empty_time} hours")
# ── PROBLEM 3: Alternate opening (open one, close other) ─────────# Inlet fills in 3 hours. Outlet drains in 4.5 hours.# They alternate: inlet open for first hour, outlet for second, repeat.# How long to fill the empty tank?print("\n" + "=" * 50)
print("PROBLEM 3: Alternating pipes")
print("=" * 50)
inlet_rate2 = Fraction(1, 3) # fills 1/3 per hour
outlet_rate2 = Fraction(1, Fraction(9, 2)) # drains 2/9 per hour (4.5 = 9/2)
net_per_2hr_cycle = inlet_rate2 - outlet_rate2 # net fill in each 2-hour cycleprint(f"Inlet rate : {inlet_rate2} per hour")
print(f"Outlet rate : {outlet_rate2} per hour")
print(f"Net fill per 2hr cycle: {net_per_2hr_cycle}")
# After how many full 2-hour cycles is the tank nearly full?
tank_filled = Fraction(0)
hours_elapsed = 0
cycle = 0while tank_filled < 1:
# Hour 1 of cycle: inlet open
tank_filled += inlet_rate2
hours_elapsed += 1if tank_filled >= 1:
break # Tank filled during inlet hour — stop here# Hour 2 of cycle: outlet open
tank_filled -= outlet_rate2
hours_elapsed += 1
cycle += 1print(f"\nTank fills after : {hours_elapsed} hours")
print(f"Full cycles completed: {cycle}")
print(f"Tank level at end : {tank_filled} ✓")
In leak problems, candidates often compute the leak time as (inlet_time + net_time) instead of deriving it from rates. That gives a wrong answer. Always convert to rates first, subtract, then invert. The 'shortcut' formula (A×B)/(B−A) only works when there's exactly one inlet and one leak — if you have multiple pipes, it'll silently give you the wrong number.
Efficiency and Wages — When Workers Aren't Equal
Real exam problems add one more layer: workers have different efficiencies, or you need to split wages proportional to work done. This feels like a new topic but it's just the rate model extended.
If Worker X is twice as efficient as Worker Y, X's daily rate is twice Y's daily rate. You don't need a new formula — just express one rate as a multiple of the other, then solve the same equation you always write.
For wage problems: wages are split in the ratio of work done. If A does 3/5 of the job and B does 2/5, their wages split 3:2. Find the total work each person contributed, form the ratio, apply it to the total payment. You never need to find the absolute amount of work — ratios are enough.
A nasty variant is 'group work': if 6 men and 8 women complete a job in 10 days, and 26 men and 48 women complete it in 2 days, find a man's and woman's individual rates. This is just two simultaneous equations with two unknowns — set up both equations using the rate model and solve.
efficiency_and_wages.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# ─────────────────────────────────────────────────────────────────# Efficiency Ratios and Wage Distribution# TheCodeForge.io# ─────────────────────────────────────────────────────────────────from fractions importFraction# ── PROBLEM 1: Relative efficiency ───────────────────────────────# Priya is 25% more efficient than Raj.# Raj alone takes 20 days to finish a task.# How long does Priya alone take?print("=" * 55)
print("PROBLEM 1: Relative Efficiency")
print("=" * 55)
raj_rate = Fraction(1, 20) # Raj does 1/20 per day# Priya is 25% more efficient => her rate is 1.25x Raj's rate
priya_rate = raj_rate * Fraction(125, 100) # Fraction avoids float errors
priya_days = Fraction(1) / priya_rate # Time = 1 / rateprint(f"Raj's daily rate : {raj_rate} (takes 20 days)")
print(f"Priya's daily rate: {priya_rate} (25% faster)")
print(f"Priya takes : {priya_days} days = {float(priya_days):.1f} days")
# ── PROBLEM 2: Wage split by work contribution ────────────────────# Emi finishes a project in 10 days. Sam finishes it in 15 days.# They work together and earn ₹5000 total.# How much does each person earn?print("\n" + "=" * 55)
print("PROBLEM 2: Wage Split Proportional to Work Done")
print("=" * 55)
emi_rate = Fraction(1, 10)
sam_rate = Fraction(1, 15)
joint_rate = emi_rate + sam_rate
days_taken = Fraction(1) / joint_rate # 6 days together# Work done by each person over 6 days
emi_work_share = emi_rate * days_taken # = 6/10 = 3/5
sam_work_share = sam_rate * days_taken # = 6/15 = 2/5print(f"Days taken together : {days_taken}")
print(f"Emi's work share : {emi_work_share} of total job")
print(f"Sam's work share : {sam_work_share} of total job")
print(f"Ratio : {emi_work_share} : {sam_work_share} => "
f"{emi_work_share.numerator}:{sam_work_share.numerator}")
total_payment = 5000# Wages split in ratio of work done
emi_wage = total_payment * emi_work_share
sam_wage = total_payment * sam_work_share
print(f"\nEmi earns : ₹{emi_wage}")
print(f"Sam earns : ₹{sam_wage}")
print(f"Total : ₹{emi_wage + sam_wage} ✓")
# ── PROBLEM 3: Group work — simultaneous equations ────────────────# 4 men + 6 women complete a job in 8 days.# 3 men + 7 women complete it in 10 days.# Find: daily rate of 1 man and 1 woman.print("\n" + "=" * 55)
print("PROBLEM 3: Group Work (Simultaneous Equations)")
print("=" * 55)
# Let m = daily rate of 1 man, w = daily rate of 1 woman# Equation 1: (4m + 6w) * 8 = 1 => 4m + 6w = 1/8# Equation 2: (3m + 7w) * 10 = 1 => 3m + 7w = 1/10## Solve using substitution / elimination:# From eq1: 4m = 1/8 - 6w => m = (1/8 - 6w) / 4# Substitute into eq2:# 3 * [(1/8 - 6w)/4] + 7w = 1/10# (3/8 - 18w) / 4 + 7w = 1/10# 3/32 - 18w/4 + 7w = 1/10# 3/32 - 9w/2 + 7w = 1/10# 3/32 + 5w/2 = 1/10# 5w/2 = 1/10 - 3/32 = 16/160 - 15/160 = 1/160# w = (1/160) * (2/5) = 2/800 = 1/400
w = Fraction(1, 400) # one woman's daily rate
m = (Fraction(1,8) - 6*w) / 4# derived from equation 1print(f"1 man's daily rate : {m} (takes {1//m} days alone)")
print(f"1 woman's daily rate: {w} (takes {1//w} days alone)")
# Verify both original equationsassert (4*m + 6*w) * 8 == 1, "Equation 1 check failed"assert (3*m + 7*w) * 10 == 1, "Equation 2 check failed"print("Both group equations verified ✓")
1 woman's daily rate: 1/400 (takes 400 days alone)
Both group equations verified ✓
Pro Tip:
In wage problems, you never actually need to know how many days they worked. The wage split equals the work-rate ratio. For two workers with times A and B, the wage split is always B:A (swap and it's the ratio). Derive this once: emi_rate:sam_rate = (1/10):(1/15) = 15:10 = 3:2. Memorize the swap trick — it saves 30 seconds per problem.
The Reciprocal Trap: Why Formula 1/Time Breaks Down in Production
You've seen the formula: Rate = 1/Time. It's elegant. It's wrong for real work. This formula only holds when a single worker does discrete, independent units of work with zero overhead. In production, workers share resources. Two developers don't finish a feature in half the time because of communication overhead, context switching, and merge conflicts. The formula assumes infinite parallelism and zero cost for coordination. That's a fantasy. The correct mental model: Work = Rate × Time, where Rate is measured in real units (lines of code, widgets assembled, tickets closed) per unit time. Never derive Rate from Time alone. Instead, ask: "What is the measured throughput of this worker on this specific task type?" When a problem says "A can do a job in 10 days", translate that to "A's historical throughput is 0.1 jobs/day on tasks like this." That's a fact. The reciprocal is an approximation. Treat it as one.
WorkerRate.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// io.thecodeforge// Real rate tracking, not reciprocal fantasypublicclassWorkerRate {
privatefinalString name;
private final double jobsPerDay; // measured, not derivedpublicWorkerRate(String name, double jobsPerDay) {
this.jobsPerDay = jobsPerDay;
}
// Combines rates correctly: rates add, reciprocals don'tpublicstaticdoublecombinedJobsPerDay(WorkerRate... workers) {
double total = 0;
for (WorkerRate w : workers) total += w.jobsPerDay;
return total;
}
publicstaticvoidmain(String[] args) {
WorkerRate alice = new WorkerRate("Alice", 0.05); // 20 days per jobWorkerRate bob = new WorkerRate("Bob", 0.067); // ~15 days per jobdouble combined = combinedJobsPerDay(alice, bob);
System.out.printf("Combined rate: %.3f jobs/day%n", combined);
System.out.printf("Time for 1 job: %.2f days%n", 1.0 / combined);
}
}
Output
Combined rate: 0.117 jobs/day
Time for 1 job: 8.55 days
Production Trap:
Using 1/Time as a rate assumes zero overhead and perfect parallelism. In real systems, two workers rarely achieve double throughput. Always use measured historical rates when available.
Key Takeaway
Rate is measured, not derived. 1/Time is an approximation that ignores overhead. Use real throughput data.
The Man-Hour Myth: Why M1×D1×T1 = M2×D2×T2 Is a Lie
Competitors love this formula: (M1 × D1 × T1 × W2) = (M2 × D2 × T2 × W1). It implies work is a commodity that scales linearly with headcount and hours. That's the man-hour myth. It assumes every worker is identical, every hour is equally productive, and tasks are infinitely parallelizable. In production, adding people to a late project makes it later (Brooks' Law). The formula breaks because it ignores: ramp-up time for new joiners, communication overhead (n(n-1)/2 channels), task dependencies that cannot be parallelized, and varying skill levels. Instead of this formula, use staged work decomposition. Break the job into sequential phases. Estimate each phase with a realistic team velocity. Account for dependencies. The formula gives you a theoretical lower bound, not a prediction. Use it to sanity-check estimates, never to derive them. When a problem gives you M1, D1, T1, ask: "What's the actual bottleneck?"
TeamVelocity.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// io.thecodeforge// Realistic team estimation, not linear extrapolationimport java.util.*;
publicclassTeamVelocity {
privatefinalint headcount;
private final double overheadFactor; // 0.0 to 1.0, fraction of time lost to coordinationpublicTeamVelocity(int headcount, double overheadFactor) {
this.headcount = headcount;
this.overheadFactor = overheadFactor;
}
publicdoubleeffectiveVelocity(double baseVelocityPerPerson) {
double raw = headcount * baseVelocityPerPerson;
double overhead = raw * overheadFactor * (headcount - 1); // O(n^2) overheadreturnMath.max(0, raw - overhead);
}
publicstaticvoidmain(String[] args) {
// Adding a 4th person when overhead is 10% per channelTeamVelocity team3 = newTeamVelocity(3, 0.10);
TeamVelocity team4 = newTeamVelocity(4, 0.10);
double vel3 = team3.effectiveVelocity(1.0); // 1 job/day per person basedouble vel4 = team4.effectiveVelocity(1.0);
System.out.printf("Team of 3: %.2f jobs/day%n", vel3);
System.out.printf("Team of 4: %.2f jobs/day%n", vel4);
System.out.printf("Gain from +1 person: %.2f jobs/day (not 1.0)%n", vel4 - vel3);
}
}
Output
Team of 3: 2.40 jobs/day
Team of 4: 2.80 jobs/day
Gain from +1 person: 0.40 jobs/day (not 1.0)
Production Trap:
The M×D×T formula assumes linear scaling. Real teams lose 10-30% efficiency per additional member due to communication overhead. Always apply a correction factor.
Key Takeaway
Man-hours are a myth. Use effective velocity with overhead factored in. The formula is a lower bound, not a prediction.
Negative Work Pattern: The Reverse Proxy Problem in Pipes and Cisterns
Pipes and cisterns introduce 'negative work' — a pipe that fills while another drains. This maps directly to production: a caching layer that accelerates reads while a garbage collector slows writes. The trap? Assuming rates simply subtract. They do, but only at steady state. In real systems, a draining pipe (cache eviction, garbage collection) has non-linear behavior. It might drain faster when the cistern is full (cache pressure), or stall when empty. Competitors teach: Net rate = Fill rate - Drain rate. Fine for homework. In production, you need to model: Is the drain rate constant? Does it depend on current load? When does backpressure kick in? Translate this: A fill pipe is a producer thread. A drain pipe is a consumer thread. The cistern level is the queue depth. Net rate is throughput. But only if the consumer doesn't stall. When the queue empties, the consumer idles — its effective rate drops. Your formula must handle these edge cases. Always model the system with state-dependent rates. The simple subtraction works only when both pipes never stop.
Simple rate subtraction (Fill - Drain) fails when the drain pipe empties the cistern. Real systems stall. Always model state-dependent behavior: an empty consumer doesn't consume.
Key Takeaway
Negative work in pipes assumes constant rates. Real systems have idle consumers. Model state-dependent rates, not just subtraction.
Problem Type
Key Equation Setup
What You Solve For
Two workers together
(1/A + 1/B) × T = 1
T = combined time (AB)/(A+B)
Worker joins midway
Rate₁×d + (Rate₁+Rate₂)×(T−d) = 1
d = days first worker was alone
Pipe + leak (inlet known, net known)
Net rate = inlet rate + leak rate
Leak rate (negative), then invert
Efficiency ratio given
Faster rate = k × slower rate
Invert faster rate for their solo time
Wage split
Wages ∝ work done = rate × time worked
Each person's share in total payment
Group work (m men + w women)
Set up 2 equations, solve simultaneously
Individual man's and woman's daily rates
Key takeaways
1
Convert every duration to a rate (1/N per day) before doing any arithmetic
adding times directly is the single most common error in this topic.
2
Total work always equals 1 (one complete job). That constraint is your equation
write it first, then fill in the rate × time products for each stage.
3
Outlet pipes and leaks carry negative rates. Assign the sign correctly before summing, and every pipe/cistern problem becomes identical to a worker problem.
4
Wage splits equal the ratio of work done, which equals the ratio of individual rates when workers work the same duration
so the split ratio is always B:A for workers with times A and B (swap the numbers).
INTERVIEW PREP · PRACTICE MODE
Interview Questions on This Topic
FAQ · 3 QUESTIONS
Frequently Asked Questions
01
What is the formula for work and time problems when two people work together?
The combined time T = (A × B) / (A + B), where A and B are the times each person takes alone. This comes from adding their rates (1/A + 1/B) and inverting. For three or more workers, add all rates individually and invert — the two-person shortcut doesn't extend.
Was this helpful?
02
How do you solve pipes and cisterns problems with a leak?
Treat the leak as a pipe with a negative rate. Find the inlet's rate (1/fill_time), find the net observed rate (1/actual_fill_time), and subtract: leak_rate = net_rate − inlet_rate. The result is negative — its absolute value inverted gives you how long the leak alone takes to empty a full tank.
Was this helpful?
03
Why do wages get split in the ratio of individual work rates and not equal shares?
Wages compensate for work done, not time spent. If two workers spend the same time on a job but one is faster and contributes more output, they deserve more pay. The work done by each person equals their rate multiplied by time worked — so wages split in the same ratio as rates (when time is equal). This is why the wage ratio for workers with solo times A and B is always B:A.