Home Interview Work and Time — The Additive Rate Myth in DevOps Pipelines
Intermediate 10 min · March 06, 2026
Work and Time Problems

Work and Time — The Additive Rate Myth in DevOps Pipelines

Two workers don't halve time — CI/CD reveals diminishing returns from task deps.

N
Naren Founder & Principal Engineer

20+ years shipping production code across the stack, with years spent interviewing engineers. Drawn from code that ran under real load.

Follow
Verified
production tested
July 19, 2026
last updated
2,466
articles · all by Naren
Before you start⏱ 25 min
  • Solid grasp of fundamentals
  • Comfortable reading code examples
  • Basic production concepts
Quick Answer
  • Rate-first thinking Convert completion times to rates (1/N per unit time). Rates add linearly; times do not.
  • Core formula Work = Rate × Time. Combined rate = sum of individual rates. Total time = W / Σr_i.
  • Staged work Break timeline into stages, calculate fraction of work per stage, sum to 1.
  • Negative rates Outlet pipes or cleanup tasks subtract work — treat as negative rates in the sum.
  • Additive rate myth fails when work is sequential, workers have unequal throughput, or contention exists — adding agents yields diminishing returns.
✦ Definition~90s read
What is Work and Time Problems?

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.
work-time-problems-aptitude Rate-Based Pipeline Architecture Layered components for work aggregation Work Sources Developer Commits | Automated Triggers Rate Aggregator Sum Rates | Staged Work Handler Worker Pool Equal Workers | Unequal Efficiency Negative Work Module Reverse Proxy | Subtraction Logic Output Pipeline Deployment | Artifact Storage THECODEFORGE.IO
thecodeforge.io
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 import Fraction

# 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) = 6

print(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 import Fraction

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.
work-time-problems-aptitude Rate Aggregation vs Duration Myth Correct model versus common fallacies Rate Aggregation Duration Myth Work Definition Work = Rate × Time Work = People × Days Adding Workers Sum rates, adjust for stage Linear scaling assumed Negative Work Subtract rate from total Ignored or misapplied Unequal Efficiency Weighted rate per worker All workers equal Reciprocal Trap Avoid 1/Time formulas Common but broken THECODEFORGE.IO
thecodeforge.io
Work Time Problems Aptitude

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 import Fraction

# ── 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) / rate
    print(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 cycle
print(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         = 0

while tank_filled < 1:
    # Hour 1 of cycle: inlet open
    tank_filled += inlet_rate2
    hours_elapsed += 1
    if 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 += 1

print(f"\nTank fills after     : {hours_elapsed} hours")
print(f"Full cycles completed: {cycle}")
print(f"Tank level at end    : {tank_filled} ✓")
Output
==================================================
PROBLEM 1: Two inlets + one outlet
==================================================
Pipe A rate : +1/6 per hour
Pipe B rate : +1/4 per hour
Pipe C rate : -1/12 per hour (drain)
Net rate : 1/3 per hour
Time to fill: 3 hours = 3.00 hours
==================================================
PROBLEM 2: Finding the leak rate
==================================================
Inlet rate (fills) : +1/9 per hour
Observed net rate : 1/12 per hour
Leak rate (drains) : -1/36 per hour
Leak alone empties the full tank in: 36 hours
==================================================
PROBLEM 3: Alternating pipes
==================================================
Inlet rate : 1/3 per hour
Outlet rate : 2/9 per hour
Net fill per 2hr cycle: 1/9
Tank fills after : 17 hours
Full cycles completed: 8
Tank level at end : 1 ✓
⚠ Watch Out:
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 import Fraction

# ── 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 / rate
print(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/5

print(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 1

print(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 equations
assert (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 ✓")
Output
=======================================================
PROBLEM 1: Relative Efficiency
=======================================================
Raj's daily rate : 1/20 (takes 20 days)
Priya's daily rate: 1/16 (25% faster)
Priya takes : 16 days = 16.0 days
=======================================================
PROBLEM 2: Wage Split Proportional to Work Done
=======================================================
Days taken together : 6
Emi's work share : 3/5 of total job
Sam's work share : 2/5 of total job
Ratio : 3/5 : 2/5 => 3:2
Emi earns : ₹3000
Sam earns : ₹2000
Total : ₹5000 ✓
=======================================================
PROBLEM 3: Group Work (Simultaneous Equations)
=======================================================
1 man's daily rate : 1/200 (takes 200 days alone)
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 fantasy
public class WorkerRate {
    private final String name;
    private final double jobsPerDay; // measured, not derived

    public WorkerRate(String name, double jobsPerDay) {
        this.jobsPerDay = jobsPerDay;
    }

    // Combines rates correctly: rates add, reciprocals don't
    public static double combinedJobsPerDay(WorkerRate... workers) {
        double total = 0;
        for (WorkerRate w : workers) total += w.jobsPerDay;
        return total;
    }

    public static void main(String[] args) {
        WorkerRate alice = new WorkerRate("Alice", 0.05); // 20 days per job
        WorkerRate bob = new WorkerRate("Bob", 0.067);    // ~15 days per job
        double 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 extrapolation
import java.util.*;

public class TeamVelocity {
    private final int headcount;
    private final double overheadFactor; // 0.0 to 1.0, fraction of time lost to coordination

    public TeamVelocity(int headcount, double overheadFactor) {
        this.headcount = headcount;
        this.overheadFactor = overheadFactor;
    }

    public double effectiveVelocity(double baseVelocityPerPerson) {
        double raw = headcount * baseVelocityPerPerson;
        double overhead = raw * overheadFactor * (headcount - 1); // O(n^2) overhead
        return Math.max(0, raw - overhead);
    }

    public static void main(String[] args) {
        // Adding a 4th person when overhead is 10% per channel
        TeamVelocity team3 = new TeamVelocity(3, 0.10);
        TeamVelocity team4 = new TeamVelocity(4, 0.10);
        double vel3 = team3.effectiveVelocity(1.0); // 1 job/day per person base
        double 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.

CisternSimulator.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
31
32
33
34
35
36
// io.thecodeforge
// State-dependent pipe rates, not simple subtraction
public class CisternSimulator {
    private double fillRate;    // liters/min
    private double drainRate;   // liters/min
    private double level;       // current liters

    public CisternSimulator(double fillRate, double drainRate, double initialLevel) {
        this.fillRate = fillRate;
        this.drainRate = drainRate;
        this.level = initialLevel;
    }

    public void tick(double minutes) {
        // Drain rate depends on level: can't drain if empty
        double actualDrain = (level > 0) ? drainRate : 0;
        // Fill rate stops if cistern overflows (san check)
        double actualFill = fillRate;
        double net = (actualFill - actualDrain) * minutes;
        level = Math.max(0, Math.min(100, level + net));
    }

    public double getLevel() { return level; }

    public static void main(String[] args) {
        CisternSimulator cs = new CisternSimulator(5.0, 7.0, 50.0);
        for (int m = 0; m < 30; m++) {
            cs.tick(1.0);
            System.out.printf("Minute %d: level %.1f L%n", m+1, cs.getLevel());
            if (cs.getLevel() <= 0) {
                System.out.println("Cistern empty. Drain stalls.");
                break;
            }
        }
    }
}
Output
Minute 1: level 48.0 L
...
Minute 25: level 0.0 L
Cistern empty. Drain stalls.
⚠ Production Trap:
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.

Work with Alternate Days, Intermittent Workers, and Pipe-Cistern Variants

In real-world DevOps pipelines, workers (or processes) don't always work continuously. They may work on alternate days, join intermittently, or have varying schedules. This section explores how to model such scenarios using the rate-based approach.

Alternate Days: Suppose Worker A completes a job in 10 days working every day, but now works only on alternate days. The effective work rate becomes half: instead of 1/10 per day, it's 1/20 per day. If Worker B works continuously and completes the same job in 15 days, their rate is 1/15 per day. When working together with A on alternate days, the combined rate on A's working days is (1/20 + 1/15) = 7/60 per day, and on B's solo days it's 1/15 per day. To find total time, set up equation: let total days = T. A works on ceil(T/2) days, B works every day. Work done = (1/20)ceil(T/2) + (1/15)T = 1. Solve for T.

Intermittent Workers: A pipe fills a tank in 6 hours, but is turned off for 1 hour after every 2 hours of operation. Effective rate: in a 3-hour cycle, it works 2 hours, filling 2/6 = 1/3 of tank. So rate per cycle hour = (1/3)/3 = 1/9 per hour. But careful: the pattern repeats. To fill the tank, we need 3 cycles (9 hours) to fill completely? Actually after 2 cycles (6 hours), tank is 2/3 full. Then next 2 hours of work fill another 1/3, total 1, so total time = 8 hours (2 cycles of 3 hours + 2 hours). So time = 8 hours.

Pipe-Cistern Variants: Multiple pipes with different schedules. For example, Pipe A fills in 10 hours, Pipe B fills in 15 hours, but they are opened on alternate hours. Combined rate per 2-hour cycle = 1/10 + 1/15 = 1/6 per cycle? Actually in 2 hours, each works 1 hour, so total work = 1/10 + 1/15 = 1/6. So to fill 1 tank, need 6 cycles = 12 hours. But if they start together? First hour: both? No, alternate means only one works each hour. So cycle is 2 hours. So time = 12 hours.

These patterns are common in DevOps when jobs are scheduled with downtime, maintenance windows, or staggered deployments.

alternate_days.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def alternate_days_time(rate_a, rate_b, pattern):
    # pattern: 'alternate' means A works odd days, B works even days
    # rates are per day
    work_done = 0
    day = 1
    while work_done < 1:
        if day % 2 == 1:
            work_done += rate_a
        else:
            work_done += rate_b
        day += 1
    return day - 1

print(alternate_days_time(1/10, 1/15, 'alternate'))  # Output: 12
💡Modeling Intermittent Work
📊 Production Insight
In CI/CD pipelines, jobs may be throttled or have cooldown periods. Use cycle-based modeling to estimate actual completion times under such constraints.
🎯 Key Takeaway
Intermittent work patterns can be modeled by defining a repeating cycle and computing work per cycle, then solving for total time.

Efficiency Ratio: Comparing Worker Outputs

Not all workers are equally efficient. In DevOps, this translates to different processing speeds for different nodes or containers. Efficiency ratio compares the output of workers per unit time.

Definition: If Worker A is 20% more efficient than Worker B, then A does 1.2 times the work of B in the same time. If B's rate is r, A's rate is 1.2r.

Example: A and B together can complete a job in 12 days. If A is twice as efficient as B, how long would each take alone? Let B's rate = r, A's rate = 2r. Combined rate = 3r = 1/12 per day, so r = 1/36 per day. Thus A alone takes 1/(2r) = 18 days, B alone takes 36 days.

Multiple Workers: Three workers with efficiencies in ratio 2:3:5. They together complete work in 10 days. Find time for each alone. Let rates be 2k, 3k, 5k. Combined = 10k = 1/10, so k = 1/100. Then rates: 2/100, 3/100, 5/100. Times: 50, 33.33, 20 days respectively.

Efficiency in Pipes: Two pipes fill a tank. Pipe A is 50% more efficient than Pipe B. If both together fill in 8 hours, find time for each alone. Let B's rate = r, A's rate = 1.5r. Combined = 2.5r = 1/8, so r = 1/20. A alone: 1/(1.5/20) = 13.33 hours, B alone: 20 hours.

Efficiency and Wages: Often efficiency determines wages. If workers are paid proportionally to efficiency, then wages are directly proportional to work done. This connects to the earlier section on efficiency and wages.

In production, efficiency ratios help in capacity planning and resource allocation. For example, if one server processes 30% more requests per second than another, you can model combined throughput.

efficiency_ratio.pyPYTHON
1
2
3
4
5
6
7
8
9
def time_from_efficiency(efficiencies, combined_time):
    # efficiencies: list of ratios (e.g., [2,3,5])
    # combined_time: time taken together
    total_eff = sum(efficiencies)
    rates = [e / (total_eff * combined_time) for e in efficiencies]
    times = [1/r for r in rates]
    return times

print(time_from_efficiency([2,3,5], 10))  # Output: [50.0, 33.33, 20.0]
🔥Efficiency vs Rate
📊 Production Insight
Use efficiency ratios to normalize heterogeneous worker capacities in your pipeline, enabling accurate throughput predictions.
🎯 Key Takeaway
Efficiency ratios allow you to compare worker outputs and compute individual rates from combined performance data.

LCM Method vs Fraction Method: When to Use Each

Two common approaches to solve work-time problems: the LCM (Least Common Multiple) method and the Fraction method. Each has its strengths.

Fraction Method: Represent work as 1 unit. Each worker's rate is 1/time. Combined rate is sum of fractions. Time = 1 / (sum of rates). This is straightforward for simple problems but can lead to messy fractions when times are not integers or when many workers are involved.

LCM Method: Assume total work is the LCM of the individual times. For example, if A takes 6 days, B takes 8 days, LCM = 24. Then A's work per day = 24/6 = 4 units, B's = 24/8 = 3 units. Combined = 7 units/day. Time = 24/7 days. This avoids fractions and is often easier for mental math.

When to use Fraction Method: - When times are not integers or LCM is large. - When dealing with pipes and cisterns with negative work (leaks). - When efficiency ratios are given as decimals. - In programming, as it's easier to implement with floating point.

When to use LCM Method: - When times are small integers. - For quick manual calculations. - When you need to avoid fractions for clarity. - In competitive exams or interviews.

Example Comparison: A takes 10 days, B takes 15 days. LCM = 30. A's daily work = 3, B's = 2, combined = 5, time = 6 days. Fraction: 1/10 + 1/15 = 1/6, time = 6 days. Same result.

Complex Scenario: A takes 7 days, B takes 11 days. LCM = 77. A's daily = 11, B's = 7, combined = 18, time = 77/18 ≈ 4.28 days. Fraction: 1/7 + 1/11 = 18/77, time = 77/18. Both work, but LCM gives integer work units.

Production Insight: In code, the fraction method is more flexible. Use LCM only for quick estimates or when teaching.

lcm_vs_fraction.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import math

def fraction_method(times):
    rates = [1/t for t in times]
    combined_rate = sum(rates)
    return 1 / combined_rate

def lcm_method(times):
    lcm = 1
    for t in times:
        lcm = lcm * t // math.gcd(lcm, t)
    work_per_day = [lcm // t for t in times]
    total_per_day = sum(work_per_day)
    return lcm / total_per_day

print(fraction_method([10, 15]))  # 6.0
print(lcm_method([10, 15]))       # 6.0
💡Choosing the Right Method
📊 Production Insight
In automated pipelines, implement the fraction method for generality. Reserve LCM for quick mental checks or when teaching new team members.
🎯 Key Takeaway
Both LCM and fraction methods yield the same result; choose based on convenience: LCM for integer clarity, fraction for flexibility.
Problem TypeKey Equation SetupWhat You Solve For
Two workers together(1/A + 1/B) × T = 1T = combined time (AB)/(A+B)
Worker joins midwayRate₁×d + (Rate₁+Rate₂)×(T−d) = 1d = days first worker was alone
Pipe + leak (inlet known, net known)Net rate = inlet rate + leak rateLeak rate (negative), then invert
Efficiency ratio givenFaster rate = k × slower rateInvert faster rate for their solo time
Wage splitWages ∝ work done = rate × time workedEach person's share in total payment
Group work (m men + w women)Set up 2 equations, solve simultaneouslyIndividual man's and woman's daily rates
⚙ Quick Reference
10 commands from this guide
FileCommand / CodePurpose
work_rate_fundamentals.pyfrom fractions import FractionThe One Core Idea
staged_work_problem.pyfrom fractions import FractionWorkers Joining Mid-Job
pipes_and_cisterns.pyfrom fractions import FractionPipes and Cisterns
efficiency_and_wages.pyfrom fractions import FractionEfficiency and Wages
WorkerRate.javapublic class WorkerRate {The Reciprocal Trap
TeamVelocity.javapublic class TeamVelocity {The Man-Hour Myth
CisternSimulator.javapublic class CisternSimulator {Negative Work Pattern
alternate_days.pydef alternate_days_time(rate_a, rate_b, pattern):Work with Alternate Days, Intermittent Workers, and Pipe-Cis
efficiency_ratio.pydef time_from_efficiency(efficiencies, combined_time):Efficiency Ratio
lcm_vs_fraction.pydef fraction_method(times):LCM Method vs Fraction Method

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?
02
How do you solve pipes and cisterns problems with a leak?
03
Why do wages get split in the ratio of individual work rates and not equal shares?
N
Naren Founder & Principal Engineer

20+ years shipping production code across the stack, with years spent interviewing engineers. Drawn from code that ran under real load.

Follow
Verified
production tested
July 19, 2026
last updated
2,466
articles · all by Naren
🔥

That's Aptitude. Mark it forged?

10 min read · try the examples if you haven't

Previous
Simple and Compound Interest
13 / 16 · Aptitude
Next
Theoretical Probability: Definition, Formula and Examples