Quantitative Aptitude Mastery for Placements: A Rigorous University-Standard Approach
Welcome to the definitive, mathematically rigorous guide on Quantitative Aptitude tailored specifically for software engineering candidates, quantitative analysts, and corporate placements. If you are preparing for screening tests at top-tier product companies (FAANG/MAANG) or high-frequency trading firms, a superficial understanding of "tricks" is grossly insufficient.
This chapter is engineered to University Textbook Standards. We discard the notion of rote memorization. Instead, we build every concept from absolute first principles, model them mathematically, map them to computational memory models, trace their execution, analyze their asymptotic complexities, and write robust implementations across multiple programming languages to illustrate edge cases like floating-point precision loss. By the end of this exhaustive text, you will possess a profound, staff-engineer-level mastery of these topics.
Chapter 1: Percentages - The Foundation of Quantitative Logic and Scaling
1.0 Percentages Foundation: Fractions and Successive Discounts
To achieve rapid mental computation, you must memorize the mapping between fundamental fractions and their percentage equivalents.
Fraction-to-Percentage Quick Reference
| Fraction | Percentage | Fraction | Percentage | | :--- | :--- | :--- | :--- | | 1/2 | 50% | 1/8 | 12.5% | | 1/3 | 33.33% | 1/9 | 11.11% | | 1/4 | 25% | 1/10 | 10% | | 1/5 | 20% | 1/11 | 9.09% | | 1/6 | 16.66% | 1/12 | 8.33% | | 1/7 | 14.28% | | |
Successive Discount Formula using Multipliers
When multiple percentage changes occur sequentially, model them as chained multiplicative scalars rather than additive changes. Example: A discount of 20% followed by a discount of 10% is computed as: This represents a net discount of 28%, NOT 30%.
Foundation Word Problems
Problem 1: A population grows by 10% in Year 1 and decreases by 10% in Year 2. What is the net change? Solution: . The population decreased by 1%.
Problem 2: The price of a laptop is reduced by 25%. By what percentage must the new price be increased to return to the original price? Solution: . To revert, multiply by , which is an increase of or 33.33%.
Problem 3: If A's salary is 20% more than B's, by what percentage is B's salary less than A's? Solution: . Thus, . A reduction of corresponds to 16.66%.
1.1 First Principles and The "Split and Merge" Model
At its core, a percentage is a standardized linear scaling transformation. The term stems from per centum (by the hundred). Mathematically, it is a mapping function where a ratio is normalized such that its denominator is identically 100.
The "Split and Merge" Mental Model
To compute percentages rapidly without external aids, employ the "Split and Merge" mental model. Instead of multiplying complex numbers directly, decompose the multiplier into additive components based on base-10 anchors (10%, 5%, 1%).
Mental Math Example 1: Multiplication Decomposition To calculate :
- Split 12 into .
- Compute .
- Compute .
- Merge: .
Mental Math Example 2: Percentage Decomposition To calculate 16% of 250:
- Split 16% into .
- 10% of 250 = 25.
- 5% is half of 10%, so 5% of 250 = 12.5.
- 1% is a tenth of 10%, so 1% of 250 = 2.5.
- Merge: .
1.2 Algorithmic Implementations and Complexity
To compute successive percentage changes (e.g., , then ), the naive approach is to iteratively multiply. Let's analyze the time and space complexity of applying an array of percentage changes to a base value.
Proof of Net Percentage Change: Let be the initial value. For a sequence of percentage changes , the final value is:
Time Complexity: where is the number of successive changes. Space Complexity: auxiliary space.
Python Implementation: Successive Percentages
def successive_percentage_change(base: float, changes: list[float]) -> float:
"""
Computes the final value after applying successive percentage changes.
Time Complexity: O(n), Space Complexity: O(1)
"""
current_value = base
for change in changes:
# Avoid naive current_value += current_value * (change / 100) due to precision accumulation
current_value *= (1.0 + change / 100.0)
return current_value
# Execution Trace:
# Base = 100.0, changes = [20.0, -20.0]
# Iteration 1: current = 100.0 * 1.2 = 120.0
# Iteration 2: current = 120.0 * 0.8 = 96.0
print(successive_percentage_change(100.0, [20.0, -20.0])) # Output: 96.0
1.3 Edge Cases and Floating Point Traps
Edge Case 1: The "To" vs "By" Trap
- Decreased by 20% means .
- Decreased to 20% means . In code parsing or algorithmic trading logic, confusing these operators leads to catastrophic financial anomalies.
Chapter 2: Profit, Loss, and Discount - State Progressions and Transaction Trace
2.1 First Principles of Financial State
We can model Profit and Loss as a sequential state progression representing the value of an asset over time.
The states are: Procurement (Cost Price) Marking (Marked Price) Sale (Selling Price).
- Cost Price (CP): The base integer/float denoting procurement cost.
- Marked Price (MP):
- Selling Price (SP):
- Profit (P): . If negative, it is a Loss.
2.2 Advanced Problem Pattern: The Dishonest Dealer 4-Column Trace Table
The standard "Dishonest Dealer" problem is a classic interview question. Solving complex variations requires a systematic 4-column Trace Table tracking the flow of goods and money, particularly when combining markup, false weights, and procurement fraud.
Consider a dealer who marks up goods by 20%, uses a 900g weight instead of 1000g while selling, and originally received 1100g instead of 1000g while buying (procurement fraud).
| Phase | Quantity Exchanged | Monetary Value | True Cost to Dealer | True Revenue for Dealer | | :--- | :--- | :--- | :--- | :--- | | Procurement | Claims 1000g, Gets 1100g | Pays for 1000g (Assume 1000 units) | per gram | N/A | | Marking | 1000g claimed | Marks up by 20% | N/A | Claims for 1000g | | Selling | Claims 1000g, Gives 900g | Receives 1200 | Dealer's Cost for 900g: | Revenue: 1200 |
Net Profit Calculation:
- True CP for the 900g sold = 818.18 units.
- SP for the 900g sold = 1200 units.
- Profit = units.
- Profit % = .
2.3 C++ Implementation with Structs and Precision Control
#include <iostream>
#include <iomanip>
struct Transaction {
double cost_price;
double marked_price;
double selling_price;
};
class ProfitLossCalculator {
public:
static double calculate_dishonest_dealer_profit(double claimed_weight, double actual_weight) {
// Complexity: O(1) Time, O(1) Space
if (actual_weight <= 0) return 0.0; // Edge case: zero or negative weight
double profit = claimed_weight - actual_weight;
return (profit / actual_weight) * 100.0;
}
};
int main() {
double profit_pct = ProfitLossCalculator::calculate_dishonest_dealer_profit(1000.0, 900.0);
std::cout << std::fixed << std::setprecision(2);
std::cout << "Dishonest Dealer Profit: " << profit_pct << "%" << std::endl;
// Output: 11.11%
return 0;
}
Chapter 3: Time and Work - Inverse Proportions and Graph Traversal
Time and Work problems are fundamentally resource allocation problems. They can be perfectly modeled using graph traversal algorithms or parallel processing architectures.
3.1 The LCM Method as a State Space Search
When Alice completes a task in 10 days and Bob in 15 days, traditional methods use fractions (). In computer science, dealing with floating-point reciprocals is dangerous due to truncation errors. The LCM (Least Common Multiple) Method perfectly maps to integer-based state progression.
Complexity Proof of LCM Method:
- Compute LCM of given time periods: . Finding LCM of two numbers via Euclidean GCD algorithm takes . For numbers, it takes .
- Compute individual efficiencies: Total Work / . operations.
- Sum efficiencies and compute completion time: operations. Total Time Complexity: . Space Complexity: to store efficiencies.
sequenceDiagram
participant Alice
participant Bob
participant Job_Queue
Note over Job_Queue: Total Work = LCM(10, 15) = 30 units
Alice->>Job_Queue: Process 3 units/day (30/10)
Bob->>Job_Queue: Process 2 units/day (30/15)
Note over Job_Queue: Combined throughput = 5 units/day
Job_Queue-->>Alice: Job Complete in 30 / 5 = 6 days
3.2 Advanced Problem Pattern: Time & Work Timeline Trace Table
When workers join or leave mid-task, tracking state mathematically prevents logic errors. Use a timeline trace table.
Example: Alice (10 days), Bob (15 days), Charlie (20 days). Total Work = LCM(10,15,20) = 60 units. Efficiencies: Alice = +6, Bob = +4, Charlie = +3. Alice and Bob start. After 2 days, Alice leaves and Charlie joins. After 3 more days, Bob leaves. How long for Charlie to finish?
| Phase (Days) | Active Workers | Combined Efficiency (units/day) | Work Done in Phase | Remaining Work | | :--- | :--- | :--- | :--- | :--- | | Phase 1 (Day 1-2) | Alice, Bob | 6 + 4 = 10 | | | | Phase 2 (Day 3-5) | Bob, Charlie | 4 + 3 = 7 | | | | Phase 3 (Day 6+) | Charlie | 3 | (Needs days) | |
Total Time = days.
3.3 Dynamic Worker Pools (Alternating Days)
When workers alternate, the system is a periodic finite state machine.
Algorithm:
- Determine the efficiency of each worker.
- Calculate work done in one complete cycle (e.g., 2 days for 2 workers alternating).
- Use modulo arithmetic:
Cycles = Total Work // Work per Cycle. - Process
Remaining Work = Total Work % Work per Cycleby simulating the queue sequentially until exhaustion.
3.4 Java Implementation of Alternating Task Execution
public class TaskScheduler {
// Computes days required for two workers working on alternate days
public static int alternateDaysCompletion(int timeA, int timeB) {
int totalWork = lcm(timeA, timeB);
int effA = totalWork / timeA;
int effB = totalWork / timeB;
int cycleWork = effA + effB;
int fullCycles = totalWork / cycleWork;
int remainingWork = totalWork % cycleWork;
int days = fullCycles * 2; // 2 days per cycle
if (remainingWork > 0) {
if (remainingWork <= effA) {
days += 1;
} else {
days += 2;
}
}
return days;
}
private static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
private static int lcm(int a, int b) {
return a / gcd(a, b) * b; // Divide first to prevent integer overflow before multiplication
}
public static void main(String[] args) {
System.out.println("Completion Time: " + alternateDaysCompletion(10, 15) + " days");
}
}
Chapter 4: Simple Interest and Compound Interest - Linear vs Exponential Scaling
4.1 Arithmetic Progressions vs Exponential Scaling
Simple Interest (SI) is fundamentally an Arithmetic Progression (AP). The principal acts as the first term , and the common difference is the constant interest accrued per period: . It is deterministic and non-compounding, scaling linearly in time.
Simple Interest Formula:
Conversely, Compound Interest (CI) models geometric progression and exponential scaling. Interest accrued in previous periods becomes part of the new principal.
Compound Interest Formula:
The Exponential Divergence: For the first period (e.g., Year 1), SI and CI are identical. From the second period onward, CI scales exponentially faster. The difference for 2 years at rate is strictly the interest on the first year's interest: .
4.2 Rust Implementation Ensuring Memory Safety
Financial systems often utilize languages like Rust to ensure memory safety and prevent race conditions when updating ledger states.
fn calculate_simple_interest(principal: f64, rate: f64, time: f64) -> Result<f64, &'static str> {
if principal < 0.0 || rate < 0.0 || time < 0.0 {
return Err("Inputs must be non-negative");
}
// Time Complexity: O(1), Space Complexity: O(1)
let interest = (principal * rate * time) / 100.0;
Ok(interest)
}
fn main() {
match calculate_simple_interest(1000.0, 5.0, 3.0) {
Ok(interest) => println!("Total Interest: ${:.2}", interest),
Err(e) => println!("Error: {}", e),
}
}
Chapter 5: Time, Speed, and Distance - Kinematics and Relative Vectors
Time, Speed, and Distance (TSD) fundamentally deals with linear motion and relative vectors.
5.1 Relative Speed Vectors
When two entities move in the same dimension, we consolidate their velocities into a single relative vector:
- Opposite Directions (Approaching/Diverging): Velocities add up. .
- Same Direction (Chasing): Velocities subtract. .
5.2 Trains and Platform Crossings
A train crossing a stationary platform must cover a total distance equal to its own length plus the platform's length.
- Distance .
- Time .
5.3 Boats and Streams (Upstream/Downstream)
The river's current acts as an additive or subtractive scalar to the boat's base speed in still water (). Let stream speed be .
- Downstream Speed (): .
- Upstream Speed (): . Given and , you can quickly isolate variables: and .
Chapter 6: Number Theory
6.1 Number Theory Foundations
A. Prime Factorization Every integer n > 1 can be written uniquely as a product of prime powers: n = p1^a1 × p2^a2 × ... × pk^ak Example: 360 = 2³ × 3² × 5¹ Python code to find prime factorization:
def prime_factors(n):
factors = {}
d = 2
while d * d <= n:
while n % d == 0:
factors[d] = factors.get(d, 0) + 1
n //= d
d += 1
if n > 1:
factors[n] = 1
return factors
# Example: prime_factors(360) → {2: 3, 3: 2, 5: 1}
B. Modular Arithmetic Fundamentals The Wrap-Around Rule: (a + b) % m = ((a % m) + (b % m)) % m Similarly for multiplication: (a × b) % m = ((a % m) × (b % m)) % m Mnemonic: "Clock arithmetic" — after 12, it wraps to 1. Example: What is 47 mod 5? 47 = 9 × 5 + 2 → 47 mod 5 = 2
C. Cyclicity for Unit Digits Powers of any digit follow a repeating cycle:
- 2: cycle [2,4,8,6] (length 4)
- 3: cycle [3,9,7,1] (length 4)
- 4: cycle [4,6] (length 2)
- 7: cycle [7,9,3,1] (length 4) Rule: Find (exponent mod cycle_length) → look up position in cycle. Example: Unit digit of 7^53? Cycle of 7 is [7,9,3,1], length=4. 53 mod 4 = 1. Position 1 in cycle = 7.
D. Legendre's Formula (Trailing Zeros in Factorials) Number of trailing zeros in n! = ⌊n/5⌋ + ⌊n/25⌋ + ⌊n/125⌋ + ... Example: Trailing zeros in 100! = ⌊100/5⌋ + ⌊100/25⌋ = 20 + 4 = 24. Explanation: Each trailing zero requires one factor of 10 = 2 × 5. Since 2s are more common, just count 5s.
6.2 The Sieve of Eratosthenes
To efficiently compute all primes up to , the Sieve of Eratosthenes provides an optimal time complexity.
Python Implementation
def sieve_of_eratosthenes(n: int) -> list[int]:
if n < 2:
return []
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
p = 2
while p * p <= n:
if is_prime[p]:
for i in range(p * p, n + 1, p):
is_prime[i] = False
p += 1
return [p for p in range(2, n + 1) if is_prime[p]]
# Execution for N=30
print(sieve_of_eratosthenes(30))
# Output: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Trace Table for N = 30
| p | p^2 | Multiples Marked as False | Remaining Primes (Conceptual) | | :--- | :--- | :--- | :--- | | 2 | 4 | 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 | 2, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29 | | 3 | 9 | 9, 12, 15, 18, 21, 24, 27, 30 (some already marked) | 2, 3, 5, 7, 11, 13, 17, 19, 23, 25, 29 | | 4 | 16 | Skip (already marked False by 2) | | | 5 | 25 | 25, 30 (30 already marked) | 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 | | 6 | 36 | Loop terminates () | |
Chapter 7: Permutations, Combinations, and Probability - Decision Trees
Probability and combinatorics are foundational for understanding decision spaces, state space generation, and stochastic processes in software engineering. Instead of memorizing formulas, we model these as traversal operations over tree data structures.
7.1 The Fundamental Counting Principle and Decision Trees
Every combinatorics problem can be strictly modeled as a decision tree search space. If event A has possible branches and event B has possible branches, the joint sample space represents the total leaf nodes in a 2-level tree: branches.
When modeling constraints (e.g., "Event B cannot be the same as Event A"), we dynamically prune the decision tree during traversal.
7.2 Permutations vs Combinations: Algorithmic Generation
Mathematical definitions map directly to sequence generation properties:
- Permutation (Arrangement): Order matters (e.g., generating passwords, process scheduling). .
- Combination (Selection): Order does not matter (e.g., forming a worker pool). .
Recursive Combination Generation (Python) To generate all subsets of size from items, we use a backtracking algorithm that naturally eliminates duplicates by maintaining a strictly increasing sequence of indices.
def generate_combinations(arr: list[int], k: int) -> list[list[int]]:
result = []
def backtrack(start: int, current_combo: list[int]):
# Base case: reached desired size
if len(current_combo) == k:
result.append(current_combo.copy())
return
# Recursive step with pruning
for i in range(start, len(arr)):
current_combo.append(arr[i])
backtrack(i + 1, current_combo)
current_combo.pop() # Backtrack
backtrack(0, [])
return result
# O(k * (n choose k)) Time Complexity
# O(k) Space Complexity for the recursion stack
Trace Table for generate_combinations([1, 2, 3], 2)
| Step | start | i | current_combo | Action |
| :--- | :--- | :--- | :--- | :--- |
| 1 | 0 | 0 | [1] | Push 1, Recurse with start=1 |
| 2 | 1 | 1 | [1, 2] | Push 2, Recurse with start=2 |
| 3 | 2 | - | [1, 2] | Base case hit -> Append [1, 2]. Return. |
| 4 | 1 | 1 | [1] | Pop 2 (Backtrack) |
| 5 | 1 | 2 | [1, 3] | Push 3, Recurse with start=3 |
| 6 | 3 | - | [1, 3] | Base case hit -> Append [1, 3]. Return. |
| 7 | 1 | 2 | [1] | Pop 3 (Backtrack) |
| 8 | 0 | 0 | [] | Pop 1 (Backtrack to root level) |
| 9 | 0 | 1 | [2] | Push 2, Recurse with start=2... |
(Final Output: [[1, 2], [1, 3], [2, 3]])
7.3 Probability and Stochastic Testing Pitfalls
The basic probability of an event is the cardinality of the target set divided by the cardinality of the uniform sample space: .
Monte Carlo Simulations for Software Engineers In systems with intractable sample spaces, theoretical probability is approximated computationally using Monte Carlo simulations. By generating pseudo-random states thousands of times, the empirical distribution converges to the theoretical probability (Law of Large Numbers).
Stochastic Testing Pitfalls: When testing systems with random behavior (like load balancers or cache evictions), naive random assertions will fail probabilistically (flaky tests). To resolve this:
- Seed Injection: Always inject a deterministic seed into your PRNG during tests to freeze the sample space.
- Tolerance Bounds: If asserting on non-seeded Monte Carlo outcomes, assert that the result falls within a statistically significant confidence interval (e.g., ) rather than requiring exact equality.
7.4 Core Interview Questions
Q1: The Birthday Paradox (Hash Collisions) Prompt: How many people must be in a room for there to be a chance that two share a birthday? Analysis: Calculate the probability of no shared birthdays. . When , . Thus, probability of a match is . This is why 64-bit hashes collide far sooner than expected.
Q2: The Defective Server (Bayes' Theorem) Prompt: Server rack A handles 60% of traffic, with a 1% error rate. Rack B handles 40% of traffic, with a 2% error rate. Given an error occurred, what is the probability it came from Rack B? Analysis: .
Chapter 8: Mixtures & Alligations - Weighted Averages and Distribution Models
Mixtures mathematically represent the blending of independent state pools to achieve a targeted weighted equilibrium. When mixing two ingredients of varying concentrations, costs, or processing speeds, the "Alligation Cross" provides a constant-time scalar derivation of the exact required ratio.
8.1 The Alligation Cross ASCII Diagram and Algorithmic Model
Let Pool 1 have a property magnitude and Pool 2 have (where ). We require a blended system with mean magnitude .
C1 (Cheaper/Slower) C2 (Dearer/Faster)
\ /
\ /
\-----> M (Mean Target) <---/
/ \
/ \
(C2 - M) (M - C1)
Quantity Ratio 1 Quantity Ratio 2
The required volumetric ratio of Pool 1 to Pool 2 is strictly .
8.2 Algorithmic Implementation of Weighted Averages
When we expand beyond two pools, the alligation cross gives way to a generalized weighted average calculation, often executed during data aggregation and log reduction.
C++ Implementation: Computing the Aggregate Blend
#include <iostream>
#include <vector>
#include <numeric>
struct Pool {
double magnitude;
double volume;
};
class MixtureCalculator {
public:
static double calculate_weighted_average(const std::vector<Pool>& pools) {
if (pools.empty()) return 0.0;
double total_volume = 0.0;
double weighted_sum = 0.0;
for (const auto& p : pools) {
weighted_sum += (p.magnitude * p.volume);
total_volume += p.volume;
}
return total_volume > 0.0 ? (weighted_sum / total_volume) : 0.0;
}
};
// Dry Run Trace:
// Input: Pool1(mag=10, vol=5), Pool2(mag=20, vol=15)
// Loop 1: weighted_sum = 50, total_volume = 5
// Loop 2: weighted_sum = 50 + 300 = 350, total_volume = 5 + 15 = 20
// Result = 350 / 20 = 17.5
8.3 Practical Tech Analogy: Weighted Distributions in Load Balancing
Alligation is fundamentally a routing problem. Consider a load balancer directing HTTP traffic across two server clusters:
- Cluster A (Legacy) has an average response time of ms.
- Cluster B (Modern) has an average response time of ms.
- Target Service Level Agreement (SLA): Ensure average latency across all requests equals ms.
Using the Alligation Cross:
- ms (Cluster B), ms (Cluster A). Mean ms.
- Ratio for Cluster B = .
- Ratio for Cluster A = .
- Ratio (B : A) = .
Conclusion: The load balancer must route 4 out of every 5 requests to the modern cluster (80% weighted distribution) to strictly satisfy the 160 ms global SLA.
Chapter 9: Progressive Mathematical Drills (Rapid Elimination & Approximation)
These drills focus on option elimination and structural approximation rather than brute-force computation.
Level 1: Easy (Structural Approximation)
Q: A product's price increases by 10%, then decreases by 10%. The final price is: (A) Same as original (B) 1% lower (C) 1% higher (D) 10% lower Strategy: Successive percentage changes scale geometrically. . The price drops by exactly 1%. Answer: B.
Level 2: Medium (Unit Digit Elimination)
Q: ? (A) 1416768 (B) 1416766 (C) 1416758 (D) 1416762 Strategy: Do not multiply. Check the unit digit: . Only options A and C end in 8. Now estimate: . Both are close, check the tens digit via cross-multiplication: . The last two digits must be 68. Answer: A.
Level 3: Hard (Bounding and Range Elimination)
Q: The compound interest on $15,000 at 8% p.a. for 2 years is approximately: (A) 2200 (B) 2496 (C) 2650 (D) 2800 Strategy: Calculate Simple Interest as a lower bound. SI = 8% + 8% = 16% of 15,000. 16% of 15,000: 10% is 1500, 5% is 750, 1% is 150. Total SI = 2400. CI must be slightly higher than SI due to interest on interest ( of ). So CI = 2496. Answer: B.
Comprehensive Practice Bank: 25 Master Problems
This section provides 25 mathematically rigorous problems across domains, equipped with step-by-step resolution.
Percentages (1-5)
1. A number is mistakenly divided by 5 instead of being multiplied by 5. Find the percentage error in the calculation. Solution: Let the number be . Correct result = . Incorrect result = . Error = . Error % = .
2. Two numbers are respectively 20% and 50% more than a third number. The ratio of the two numbers is: Solution: Let third number be 100. First = , Second = . Ratio = .
3. In an election between two candidates, one got 55% of the total valid votes, 20% of the votes were invalid. If the total number of votes was 7500, the number of valid votes that the other candidate got was: Solution: Total votes = 7500. Valid votes = of 7500 = 6000. Other candidate gets of 6000 = 2700.
4. Fresh fruit contains 68% water and dry fruit contains 20% water. How much dry fruit can be obtained from 100 kg of fresh fruits? Solution: Solid mass in fresh fruit = . Mass = kg. In dry fruit, solid is . Let dry fruit mass be . kg.
5. The price of sugar is increased by 20%. As a result, a family decreases its consumption by 25%. Find the percentage change in the family's expenditure on sugar. Solution: Initial cost = . New cost = . Decrease is .
Profit & Loss (6-10)
6. A man sells two articles for $5000 each. On one, he gains 20% and on the other, he loses 20%. Find his net gain or loss percent. Solution: Net loss percent for selling at same price with same gain/loss percent is loss.
7. A shopkeeper marks his goods 40% above the cost price and gives a discount of 25%. Find his profit percent. Solution: Let CP = 100. MP = 140. SP = . Profit = .
8. If the cost price of 15 pens is equal to the selling price of 20 pens, find the loss percent. Solution: . Loss is .
9. A merchant has 1000 kg of sugar, part of which he sells at 8% profit and the rest at 18% profit. He gains 14% on the whole. The quantity sold at 18% profit is: Solution: Using alligation: Ratio is 4:6 = 2:3. Quantity at 18% = kg.
10. An article is sold at a certain price. By selling it at 2/3 of that price one loses 10%. Find the gain percent at original price. Solution: Let original price = SP. New price = SP. Loss = 10%, so New price = CP. . Gain = .
Time & Work (11-15)
11. A can do a piece of work in 10 days and B in 15 days. They work together for 5 days, the rest of the work was finished by C in 2 days. If they get $3000 for the whole work, how much should C get? Solution: Work = LCM(10, 15) = 30 units. A does 3/day, B does 2/day. Together they do units. C does remaining 5 units. C's share = (5/30) \times 3000 = \500$.
12. A and B can do a job in 12 days. B and C can do it in 15 days. C and A can do it in 20 days. How long would A take to do it alone? Solution: A+B=5, B+C=4, C+A=3 (Work = 60). . A = . Time for A = days.
13. 10 men can complete a piece of work in 15 days and 15 women can complete the same work in 12 days. If all the 10 men and 15 women work together, in how many days will the work get completed? Solution: 10 men = 1/15 work/day. 15 women = 1/12 work/day. Together = . Time = 20/3 = 6.66 days.
14. A is thrice as good a workman as B and therefore is able to finish a job in 60 days less than B. Working together, they can do it in: Solution: Efficiency ratio A:B = 3:1. Time ratio A:B = 1:3. Difference is 2x = 60 days. x = 30. A takes 30 days, B takes 90 days. LCM = 90. A=3, B=1. Total efficiency = 4. Time = 90/4 = 22.5 days.
15. Two pipes A and B can fill a tank in 24 minutes and 32 minutes respectively. If both the pipes are opened simultaneously, after how much time B should be closed so that the tank is full in 18 minutes? Solution: A works for 18 mins. Part filled by A = . Remaining must be filled by B. B takes minutes. Close B after 8 minutes.
Time & Distance (16-20)
16. A train 125 m long passes a man, running at 5 km/hr in the same direction in which the train is going, in 10 seconds. The speed of the train is: Solution: Relative speed = m/s = km/hr. Speed of train = km/hr.
17. A boat goes 20 km downstream in one hour and 10 km upstream in 2 hours. The speed of the boat in still water is: Solution: Downstream speed km/h. Upstream speed km/h. Boat speed = km/h.
18. Excluding stoppages, the speed of a bus is 54 kmph and including stoppages, it is 45 kmph. For how many minutes does the bus stop per hour? Solution: Loss of speed = 9 kmph. Time taken to cover 9 km at original speed = minutes.
19. A man covers half of his journey at 6 km/h and the remaining half at 3 km/h. His average speed is: Solution: Average speed = km/h.
20. Two trains running in opposite directions cross a man standing on the platform in 27 seconds and 17 seconds respectively and they cross each other in 23 seconds. The ratio of their speeds is: Solution: Using alligation: .
Number Theory (21-25)
21. Find the unit digit of . Solution: Cyclicity of 7 is 4. . The unit digit is .
22. How many trailing zeros are there in 100!? Solution: Zeros are given by the power of 5 in 100!. .
23. Find the remainder when is divided by 5. Solution: . Cyclicity is 4. . Remainder is .
24. The sum of two numbers is 528 and their HCF is 33. The number of pairs of numbers satisfying the above condition is: Solution: Let numbers be and where . . Coprime pairs summing to 16: (1,15), (3,13), (5,11), (7,9). Total 4 pairs.
25. Find the largest four-digit number exactly divisible by 12, 15, 18 and 27. Solution: LCM(12, 15, 18, 27) = 540. Largest 4 digit = 9999. remainder 279. .
Permutations, Combinations, & Probability (26-28)
26. In how many ways can a committee of 5 members be formed from 6 men and 4 women such that there are exactly 2 women? Solution: Select 2 women from 4: . Select 3 men from 6: . Total ways = .
27. What is the probability of getting a sum of 9 from two throws of a standard 6-sided die? Solution: Sample space . Target event . . .
28. An urn contains 5 red balls and 7 blue balls. If two balls are drawn at random without replacement, what is the probability both are red? Solution: Total balls = 12. Ways to draw 2 red = . Ways to draw any 2 = . Probability = .
Mixtures & Alligations (29-31)
**29. In what ratio must a grocer mix two varieties of pulses costing 20 per kg respectively so as to get a mixture worth (20 - 16.50) : (16.50 - 15) = 3.50 : 1.50 = 35 : 15 = 7:3$.
30. A vessel contains 60 liters of pure milk. 6 liters are drawn and replaced with water. This process is repeated twice more. How much milk remains? Solution: Formula for remaining pure liquid: . liters.
31. A 40-liter mixture of alcohol and water contains 10% water. How much water must be added to make it 20% water? Solution: Alcohol in original = of liters. Let be water added. New total volume = . Alcohol remains 36 liters, which is of new volume. liters.
Chapter 10: Exhaustive Interview Questions, Proofs, and Edge Cases
Question 1: The Cascading Discounts (Amazon SDE Assessment)
Prompt: A retailer offers three successive discounts of 10%, 20%, and 30%. Prove that the order of discounts does not matter and compute the equivalent single discount. Proof: Multiplication is commutative. . Equivalent multiplier = . This means the final price is of the original. Equivalent Single Discount = .
Question 2: Parallel Processors (Google Swe-SRE)
Prompt: Server A can process a data batch in 40 ms. Server B takes 60 ms. If both start simultaneously and process independently, what is the exact time required to clear 1 batch? Complexity & Execution Trace: LCM(40, 60) = 120 units. Server A throughput = 3 units/ms. Server B throughput = 2 units/ms. Combined throughput = 5 units/ms. Time = 120 / 5 = 24 ms. Edge Case: If context switching overhead adds 1 ms penalty per 10 ms of operation, you must model this as a disrupted throughput curve.
Question 3: The Overflowing Cistern (Goldman Sachs Quant)
Prompt: A cistern can be filled by pipe A in 12 hours and pipe B in 15 hours. A leak at the bottom empties it in 20 hours. If all three are open, in how many hours will the cistern be filled? Solution: Work rate = 1/12 + 1/15 - 1/20. Find LCM(12,15,20)=60. Rates = 5/60 + 4/60 - 3/60 = 6/60 = 1/10. Answer: 10 hours.
LeetCode-Style Algorithmic Problems
Question 4: K-th Factor of N (LeetCode 1492) Prompt: Given two positive integers and , return the -th factor of . If has fewer than factors, return -1. Solution:
def kthFactor(n: int, k: int) -> int:
count = 0
for i in range(1, n + 1):
if n % i == 0:
count += 1
if count == k:
return i
return -1
# Time: O(n), Space: O(1)
Question 5: Count Primes (LeetCode 204) Prompt: Return the number of prime numbers that are strictly less than . Solution:
def countPrimes(n: int) -> int:
if n < 2: return 0
sieve = [True] * n
sieve[0] = sieve[1] = False
for i in range(2, int(n**0.5) + 1):
if sieve[i]:
for j in range(i*i, n, i):
sieve[j] = False
return sum(sieve)
# Time: O(n log log n), Space: O(n)
Euler's Totient Intuition
- counts integers from 1 to that are coprime with .
- Euler's theorem: when
- This means to compute , we can reduce
- Example:
Question 6: Super Pow (LeetCode 372) Prompt: Compute where is a very large integer represented as an array. Solution:
def superPow(a: int, b: list) -> int:
MOD = 1337
def powmod(base, exp, mod):
result = 1
base %= mod
while exp > 0:
if exp % 2 == 1:
result = result * base % mod
base = base * base % mod
exp //= 2
return result
result = 1
for digit in b:
result = powmod(result, 10, MOD) * powmod(a, digit, MOD) % MOD
return result
# Time: O(n log k), Space: O(1)
Question 7: Fraction to Recurring Decimal (LeetCode 166) Prompt: Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. If the fractional part is repeating, enclose the repeating part in parentheses. Solution:
def fractionToDecimal(numerator: int, denominator: int) -> str:
if numerator % denominator == 0:
return str(numerator // denominator)
sign = '-' if (numerator < 0) ^ (denominator < 0) else ''
n, d = abs(numerator), abs(denominator)
integer_part = n // d
remainder = n % d
decimal_digits = []
seen = {} # remainder → position in decimal_digits
while remainder != 0:
if remainder in seen:
pos = seen[remainder]
decimal_digits.insert(pos, '(')
decimal_digits.append(')')
break
seen[remainder] = len(decimal_digits)
remainder *= 10
decimal_digits.append(str(remainder // d))
remainder %= d
return f"{sign}{integer_part}.{''.join(decimal_digits)}"
# Time: O(d), Space: O(d) — at most d unique remainders
Question 8: Excel Sheet Column Number (LeetCode 171) Prompt: Given a string representing a column title as it appears in an Excel sheet, return its corresponding column number (e.g., A -> 1, AB -> 28). Solution:
def titleToNumber(columnTitle: str) -> int:
result = 0
for char in columnTitle:
result = result * 26 + (ord(char) - ord('A') + 1)
return result
# Time: O(n), Space: O(1)
# Example: "ZY" → 26*26 + 25 = 701
Problem 26: Pipe and Cistern (Challenge) Prompt: Pipe A fills a tank in 10 hours. Pipe B fills it in 15 hours. A leak empties the fully filled tank in hours. When all are open, the tank fills in 12 hours. Find . Execution Trace: Let Total Capacity = LCM(10, 15, 12) = 60 units. Efficiency A = units/hr Efficiency B = units/hr Net Efficiency Required = units/hr Let leak efficiency be (which is negative). units/hr. Time to empty = Capacity / |L| = hours. Thus, .
Chapter 11: Conclusion and Meta-Analysis
Mastery of Quantitative Aptitude transcends memorizing shortcuts. By treating numerical problems as algorithmic puzzles, mapping them to data structures (DAGs, state machines), understanding their time/space constraints, and anticipating floating-point limitations, you align your mathematical intuition with engineering rigor. This is the hallmark of a Staff Engineer and the definitive standard expected in high-stakes placement interviews.
Projects
-
Project 1: Real-time Profit and Loss Analytics Dashboard Objective: Build a full-stack dashboard that tracks the cost price, marked price, and selling price of simulated inventory in real-time, computing profit/loss metrics. Step 1: Set up a Node.js backend with an Express server and a simple SQLite database to store transactions. Step 2: Implement the endpoints to record cost price, markup percentages, and discount percentages. Step 3: Use IEEE 754 standard considerations (e.g., using
Big.jsorDecimal.jsin JavaScript) to handle floating-point calculations correctly without precision loss. Step 4: Build a React frontend that dynamically fetches these transactions and plots the daily profit margin percentages using Recharts. Step 5: Write unit tests using Jest to verify that the math holds true for complex edge cases, such as successive discounts and overlapping markup calculations. -
Project 2: Task Scheduling Engine using the LCM Method Objective: Create a scheduling engine in Python that allocates tasks to worker nodes based on their processing efficiencies. Step 1: Define a Python class
WorkerNodewith a known efficiency (e.g., time to complete a standard task). Step 2: Implement the LCM (Least Common Multiple) algorithm to determine the most efficient distribution of tasks when multiple workers are processing in parallel. Step 3: Handle alternating shifts by implementing a state machine that assigns work chunks sequentially and accounts for remainder calculations modulo the cycle workload. Step 4: Create a CLI interface where users can input worker speeds and task sizes, and receive an exact timeline for job completion. Step 5: Benchmark your algorithm against a naive iterative simulation approach to prove the O(n log(max_val)) time complexity of the LCM method.
Assignments
-
Assignment 1: Successive Discount Calculator Deliverable: A Python script that takes a base price and a list of discount percentages, returning the final price and the equivalent single discount percentage. Requirements: You must not use any external math libraries. The script must handle up to 10 successive discounts and gracefully handle floating-point precision issues by rounding the final output to exactly two decimal places. Write at least five test cases including edge cases where a discount is 0% or 100%.
-
Assignment 2: The Dishonest Dealer Simulation Deliverable: A C++ function that calculates the actual profit percentage of a dealer who tampers with weights. Requirements: The function signature should accept
claimed_weightandactual_weight. It should throw anstd::invalid_argumentexception if theactual_weightis greater than or equal to theclaimed_weightor if any weight is zero or negative. Ensure memory safety and write amainfunction that demonstrates catching these exceptions. -
Assignment 3: Multi-Node Task Scheduler Deliverable: A Java program implementing the LCM method to calculate the time required for
nmachines to complete a given task. Requirements: The program should accept an array of integers representing the days each machine takes to finish the task alone. It must compute the LCM of the array, derive individual efficiencies, and return the exact fractional days (as a double) required for all machines working simultaneously. Ensure edge cases are handled.
Debugging Guide
Bug: Accumulating Floating-Point Precision Errors
Symptom: When applying successive percentage changes (e.g., +10%, -10%), the final calculated value slightly diverges from the mathematically exact value (e.g., 98.99999999 instead of 99.0).
Fix: Avoid naive float accumulation. When precision is critical (like in financial applications), use integers by scaling up (e.g., working in cents instead of dollars) or use dedicated arbitrary-precision libraries like BigDecimal in Java or decimal in Python.
Bug: Off-by-One Errors in Alternating Work Cycles Symptom: In Time and Work problems where workers alternate days, the final day count is calculated as one day more or less than required. Fix: Trace the remaining work after all full cycles have been computed. Ensure you are simulating the final partial cycle sequentially, checking worker by worker until the remaining work crosses the zero threshold. Do not just divide the remainder by the combined efficiency.
Bug: Confusing Markup on Cost Price vs Selling Price
Symptom: The profit percentage is calculated on the selling price instead of the cost price, leading to an artificially lower profit margin in reports.
Fix: Enforce strict type definitions or wrapper classes for CostPrice and SellingPrice. The canonical formula is always ((SP - CP) / CP) * 100. Add robust assertions in your financial transaction modules that validate the denominator is strictly the procurement cost.
Testing Strategy
Testing quantitative aptitude algorithms requires rigorous mathematical validation and boundary condition testing. Since these models often form the core of financial or scheduling systems, the testing strategy must be exhaustive.
Firstly, employ Property-Based Testing using libraries like Hypothesis (Python) or JUnit (Java). Instead of hardcoding test cases, define mathematical invariants. For instance, in successive discounts, assert that the final price is independent of the order of the discounts. Feed the function thousands of random permutations of discount arrays to verify that commutativity holds true under all conditions and that precision loss does not cause assertion failures.
Secondly, implement Boundary Value Analysis. Test the extreme edges of the input domain. For percentage functions, test with 0%, 100%, and negative percentages (if the domain allows markdowns). For the LCM scheduling algorithm, test with extremely large prime numbers to ensure the LCM computation does not overflow standard 32-bit integer limits, forcing the use of 64-bit integers.
Finally, utilize Regression Testing with a fixed suite of known, mathematically proven values. Include classic interview problems (like the 40ms/60ms parallel processor problem) as immutable test cases. If an optimization is made to the algorithm (e.g., using a faster GCD calculation), the regression suite must immediately run to guarantee that the absolute mathematical output remains perfectly identical to the theoretical first principles.
Production Usage
Integrating quantitative aptitude concepts into production-grade systems requires strict adherence to reliability, maintainability, and computational correctness. When processing financial scaling, interest accumulation, or resource allocation in a live environment, performance constraints become critical.
Firstly, standardizing data types is mandatory. Production systems dealing with currency, percentages, or interest calculations must explicitly forbid primitive floating-point types (float, double). Instead, teams should employ fixed-point arithmetic or use standardized financial libraries to guarantee absolute precision during serialization and deserialization across microservices.
Secondly, algorithms derived from quantitative aptitude, such as the LCM method for scheduling, are frequently utilized in load balancers and job queues. When modeling these systems, the mathematical abstractions must be backed by resilient code. For example, if you are determining cluster processing times based on varying node efficiencies, the calculations must account for network latency, node failure (which changes the state space dynamically), and context switching.
Finally, observability must be built directly into the mathematical pipelines. If a successive discount engine outputs an anomaly, telemetry logs should trace the exact series of mathematical transformations. Using event sourcing to record every state change (from Cost Price to Marked Price to Selling Price) allows engineers to replay and audit the exact calculations, ensuring that theoretical mathematical models hold true under intense, concurrent production workloads.
FAQs
Q: Why shouldn't I just memorize the shortcut formulas for percentages and simple interest? A: Rote memorization fails when you encounter complex, multi-layered problems typical in top-tier interviews and real-world engineering. Memorized formulas often come with hidden assumptions. By understanding the first principles and the underlying mathematical models, you can easily adapt to edge cases, modify the parameters dynamically, and implement the logic safely in software without falling into logical traps.
Q: How does the computer's memory model impact simple percentage calculations? A: Computers represent decimals using base-2 floating-point architecture (IEEE 754). Many common base-10 fractions (like 0.1 or 0.33) become infinite repeating fractions in base-2, leading to truncation. When calculating percentages, these tiny precision losses can accumulate inside loops, resulting in catastrophic errors in financial calculations if not explicitly handled through rounding or integer scaling.
Q: When solving Time and Work problems, why is the LCM method preferred over adding fractions? A: The LCM method transforms a problem of fractional efficiencies into a problem of integer arithmetic by finding a common multiple for the total workload. This approach mirrors state space progression in computer science. Integers are faster to compute, mathematically exact, and inherently immune to the precision loss issues associated with dividing and adding floating-point reciprocals.
Q: How does Simple Interest differ computationally from Compound Interest? A: Simple Interest is modeled as an Arithmetic Progression, where the growth is linear and the space/time complexity to calculate any future value is O(1). Compound Interest, however, is a Geometric Progression modeling exponential growth, requiring either a power function or an iterative calculation O(n) if the state at each compounding period must be logged or accessed.
Revision Notes / Cheat Sheet
| Concept / Algorithm | Core Mathematical Model | Computational Complexity | Key Implementation Detail | Common Pitfalls to Avoid | | :--- | :--- | :--- | :--- | :--- | | Successive Percentages | V_n = V_0 * Product(1 + P_i/100) | Time: O(n), Space: O(1) | Iteratively multiply factors instead of adding percentages. | Accumulating float precision errors; using naive addition. | | Profit and Loss | Directed Acyclic Graph (DAG) | Time: O(1), Space: O(1) | Clearly separate CP, MP, and SP states logically and in code. | Calculating profit percentage on SP instead of CP. | | Dishonest Dealer | Yield = (Delta / True CP) * 100 | Time: O(1), Space: O(1) | Use the actual weight delivered as the true cost price base. | Using the claimed weight as the base for percentage. | | Time and Work (LCM) | Total Work = LCM(T_1, T_2, ...) | Time: O(n log M), Space: O(n) | Convert task times into integer throughput rates. | Dealing with floating point fractions and truncations. | | Alternating Work Cycles | Modulo Arithmetic on Work Cycles | Time: O(workers), Space: O(1) | Process full cycles using division, trace remainder sequentially. | Forgetting to simulate the final partial cycle step-by-step. | | Simple Interest | Arithmetic Progression: PRT/100 | Time: O(1), Space: O(1) | Validate inputs for non-negative values before computing. | Confusing the formula with compounding geometric progression. |