Mid-level 7 min · March 06, 2026

Seating Arrangement Bug: Circular vs Linear Overbooking

When linear formula gave 180! configurations for a circular cabin, double bookings cascaded.

N
Naren · Founder
Plain-English first. Then code. Then the interview question.
About
 ● Production Incident 🔎 Debug Guide
Quick Answer
  • Seating arrangement problems count distinct ways to place people under constraints using permutations and combinatorics
  • Linear (numbered seats): N! arrangements. Circular (relative order): (N-1)! arrangements
  • Bundle trick: treat group that must sit together as 1 unit, arrange units, then multiply by K! internal arrangements
  • Complement method: never together = total arrangements - arrangements where they ARE together
  • Performance insight: For N=8, linear = 40320, circular = 5040 — the ratio is exactly N
  • Production insight: Airline seat allocation algorithms miscount when symmetry is ignored, causing overbooking errors
  • Biggest mistake: Using N! for circular seats when no fixed reference point exists — answer comes out N times too large
Plain-English First

Imagine you're organising a birthday party and need to figure out how many different ways 6 friends can sit around a round table — especially when two of them had a fight and can't be next to each other. That's a seating arrangement problem. It's just counting the number of valid ways people (or objects) can be placed in seats, given a set of rules. Once you see it that way, the maths feels a lot less scary.

Here's the real-world punch: these aren't just exam curiosities. When an airline assigns 180 passengers to seats while keeping families together and separating unaccompanied minors from exit rows, that's a constrained seating arrangement. When a wedding planner seats 200 guests ensuring feuding relatives are at different tables, that's a constrained seating arrangement. The maths behind your aptitude problem is the same maths behind systems that handle billions of dollars in logistics every year.

Seating arrangement problems show up everywhere — from airline seat allocation algorithms and exam hall planning tools to the classic 'how many ways can a board of directors be seated for a photo?' The reason they're so common in aptitude tests and technical interviews is that they test whether you can break a complex constraint problem into smaller, countable parts. It's not about memorising formulas; it's about building a mental model of the problem space.

I've taught quantitative aptitude for competitive exams for several years, and the pattern I see every single time is the same: students who memorise formulas without understanding the reasoning behind them panic when the problem is phrased differently. They know (N-1)! for circular arrangements but can't explain WHY it's (N-1)! instead of N! — so when a problem adds a constraint they haven't seen before, they freeze. The students who understand the 'fix one person, arrange the rest' reasoning behind (N-1)! can handle any constraint thrown at them, because they're not memorising — they're deriving.

The core challenge these problems solve is this: given N people and a set of constraints (must sit together, must not sit adjacent, one person must always face a particular direction, boys and girls must alternate), how do you count all valid arrangements without listing every single one manually? The answer lives at the intersection of permutations, combinatorics, and a handful of elegant tricks that make hard problems tractable in seconds.

By the end of this article you'll be able to confidently tackle linear, circular, and alternating seating problems, handle 'always together' and 'never together' constraints using the bundle and complement techniques, apply inclusion-exclusion for multiple restricted pairs, solve probability-based seating questions, handle word arrangements with repeated letters, and walk into an interview knowing exactly why the circular arrangement formula loses a factor of N compared to the linear one.

Linear vs Circular Seating — Why the Formula Changes

In a linear arrangement, seats have fixed identities: seat 1, seat 2, seat 3. Swapping everyone one position to the right creates a genuinely different arrangement because position 1 is now empty and position N has a new occupant. So N people in a row = N! arrangements. Simple.

In a circular arrangement, there are no fixed reference points. If everyone shifts one seat clockwise, it looks identical — same neighbours, same relative order. To remove these duplicate rotations, we fix one person in place and arrange the remaining N−1 people around them. That gives (N−1)! arrangements.

This is the single most important conceptual leap in seating problems. The formula doesn't change because circular maths is harder — it changes because 'different' means something different. Two arrangements are the same if one is a rotation of the other, so we divide out the N rotational duplicates, leaving (N−1)!.

Think of it this way: imagine you're at a round table with 6 chairs. You sit down — your position is now the anchor. The remaining 5 people can arrange themselves in 5! = 120 ways around you. If you hadn't fixed yourself, every arrangement would be counted 6 times (once for each person sitting in the 'anchor seat'). That's why we divide N! by N, giving (N-1)!.

For a necklace or a round table where flipping is also considered the same (like identical chairs with no head of table), you divide again by 2, giving (N−1)!/2. But in most interview problems the seats are distinguishable by facing direction, so (N−1)! is your default circular formula.

One exam trap I see constantly: the problem says 'seated around a circular table' but the chairs are numbered or one chair is marked 'head of table.' If there's a fixed reference point — a numbered seat, a head position, a stage — the arrangement is effectively linear, and you use N! not (N-1)!. Always read the problem statement for these distinguishing details before choosing your formula.

io/thecodeforge/seating/seating_arrangement_basics.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
import math

def linear_arrangements(total_people):
    """
    Count arrangements of 'total_people' in a straight row.
    Every position is unique, so full permutation applies.
    Formula: N!
    """
    return math.factorial(total_people)

def circular_arrangements(total_people):
    """
    Count arrangements around a round table.
    We fix one person to eliminate rotational duplicates,
    then arrange the remaining (total_people - 1) freely.
    Formula: (N-1)!
    """
    if total_people < 1:
        return 0
    return math.factorial(total_people - 1)

def circular_necklace_arrangements(total_people):
    """
    For a necklace / identical chairs where flipping = same arrangement.
    Divide circular count by 2 to eliminate mirror duplicates.
    Formula: (N-1)! / 2
    """
    if total_people < 1:
        return 0
    return math.factorial(total_people - 1) // 2

# --- Demo ---
people = 6

print(f"People: {people}")
print(f"Linear (straight row):          {linear_arrangements(people):>6}")
print(f"Circular (round table):         {circular_arrangements(people):>6}")
print(f"Necklace (flip = same):         {circular_necklace_arrangements(people):>6}")

# Step-by-step breakdown
print("\n--- Why the numbers differ ---")
print(f"Linear  = {people}!  = {math.factorial(people)}")
print(f"Circular = ({people}-1)! = {people-1}! = {math.factorial(people-1)}")
print(f"Necklace = ({people}-1)!/2 = {math.factorial(people-1)//2}")
print(f"\nRatio Linear/Circular = {linear_arrangements(people)//circular_arrangements(people)}")
print(f"That ratio equals N ({people}) — exactly the rotational duplicates we removed.")
Output
People: 6
Linear (straight row): 720
Circular (round table): 120
Necklace (flip = same): 60
--- Why the numbers differ ---
Linear = 6! = 720
Circular = (6-1)! = 5! = 120
Necklace = (6-1)!/2 = 60
Ratio Linear/Circular = 6
That ratio equals N (6) — exactly the rotational duplicates we removed.
The One Ratio Worth Memorising:
Linear arrangements are always exactly N times more than circular arrangements for the same N people. If you ever get a circular answer that's larger than linear/N, something's wrong.
Production Insight
In real airline systems, cabin seating often has rotational symmetry — using N! instead of (N-1)! can overcount by factor N, leading to overbooking.
Always check if seats are physically distinct (numbered) or symmetric before applying formula.
Key Takeaway
Circular formula (N-1)! = linear N! rotated N times.
If seats are fixed (numbered), use N!. If only relative order matters, use (N-1)!.

The Bundle Trick — Solving 'Must Sit Together' Constraints

When two or more people must always sit next to each other, you stop thinking of them as individuals and treat them as a single super-person. This is the bundle trick (also called the grouping method).

Here's the reasoning: if Alice and Bob must be adjacent, tape them together. Now you have one bundle + the remaining people. Arrange that new, smaller group first — that gives you the arrangements of the bundle among everyone else. Then, inside the bundle, Alice and Bob can swap places in 2! ways. Multiply the two counts.

For a bundle of K people, the internal arrangements factor is K!. For linear seating, arrangements of (N−K+1) units = (N−K+1)! times K!. For circular seating, arrangements of (N−K+1) units = (N−K)! times K!.

Multiple bundles work the same way: create each bundle, count units (N - sum(K_i) + number_of_bundles), arrange those units, then multiply by each bundle's internal factorial.

io/thecodeforge/seating/bundle_trick_seating.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
import math

def circular_with_bundle(total_people, bundle_size):
    """
    Circular arrangements where a specific group of 'bundle_size' people
    must all sit together.
    Steps:
    1. Bundle group = 1 unit
    2. Units to arrange = total_people - bundle_size + 1
    3. Circular of units = (units - 1)!
    4. Multiply by internal arrangements inside bundle: bundle_size!
    """
    units = total_people - bundle_size + 1
    if units <= 0:
        return 0
    circular_units = math.factorial(units - 1)
    internal = math.factorial(bundle_size)
    return circular_units * internal

def circular_with_two_bundles(total_people, b1_size, b2_size):
    """
    Two distinct groups must each sit together (group members within each group).
    Groups are treated as separate bundles.
    """
    units = total_people - b1_size - b2_size + 2
    circular_units = math.factorial(units - 1)
    internal1 = math.factorial(b1_size)
    internal2 = math.factorial(b2_size)
    return circular_units * internal1 * internal2, circular_units, internal1, internal2, units

# --- Problem 1: 6 people, 3 must sit together ---
total1 = 6
bundle1 = 3
total_ways1 = circular_with_bundle(total1, bundle1)
baseline_circ = math.factorial(total1 - 1)

print(f"=== SINGLE BUNDLE: {total1} people, {bundle1} must sit together ===")
print(f"Units to arrange: {total1 - bundle1 + 1} (bundle + {total1 - bundle1} individuals)")
print(f"Circular of {total1 - bundle1 + 1} units: ({total1 - bundle1 + 1}-1)! = {math.factorial(total1 - bundle1)}")
print(f"Internal bundle: {bundle1}! = {math.factorial(bundle1)}")
print(f"Total: {math.factorial(total1 - bundle1)} x {math.factorial(bundle1)} = {total_ways1}")
print(f"Baseline (no restriction): {baseline_circ}")
print(f"Reduction factor: {baseline_circ / total_ways1:.2f}x\n")

# --- Problem 2: 7 people, (A,B) together AND (C,D) together ---
total2 = 7
b1, b2 = 2, 2
total_ways2, circ2, int1, int2, units2 = circular_with_two_bundles(total2, b1, b2)

print(f"=== TWO BUNDLES: {total2} people, two pairs must each sit together ===")
print(f"Units to arrange: {units2}")
print(f"Circular of {units2} units: ({units2}-1)! = {circ2}")
print(f"Internal bundle 1: {b1}! = {int1}")
print(f"Internal bundle 2: {b2}! = {int2}")
print(f"Total: {circ2} x {int1} x {int2} = {total_ways2}")
Output
=== SINGLE BUNDLE: 6 people, 3 must sit together ===
Units to arrange: 4 (bundle + 3 individuals)
Circular of 4 units: (4-1)! = 6
Internal bundle: 3! = 6
Total: 6 x 6 = 36
Baseline (no restriction): 120
Reduction factor: 3.33x
=== TWO BUNDLES: 7 people, two pairs must each sit together ===
Units to arrange: 5
Circular of 5 units: (5-1)! = 24
Internal bundle 1: 2! = 2
Internal bundle 2: 2! = 2
Total: 24 x 2 x 2 = 96
Pro Tip — Bundles Inside Bundles:
If a problem says 'A and B must sit together AND C and D must sit together', create two separate bundles. You'll have (N − 4 + 2) = N−2 units to arrange. Each bundle has its own 2! internal factor. Multiply all three counts: circular × 2! × 2!. The same logic scales to three or more bundles — each one reduces your unit count and adds its own internal factor.
Production Insight
In event planning systems, forgetting internal K! factor for a group of 4 people results in counting only 1 seat ordering instead of 24.
Always multiply by factorial of bundle size after arranging units.
Key Takeaway
Bundle = treat group as one unit, arrange units, then multiply by internal arrangements (K!).
Multiple bundles reduce total units and each adds its own factorial.

The Complement Method — Solving 'Must NOT Sit Together' Constraints

Counting what you don't want directly is usually harder than counting everything, then subtracting the bad cases. That's the complement method, and it's your best friend for 'must never sit adjacent' constraints.

The formula is: Valid arrangements = Total arrangements − Arrangements where the restricted pair ARE together.

Why does this work so cleanly? Because the bundle trick already gives you a precise count of arrangements where a specific group IS together. So you're doing: All − (Bundle count) = Never-together count.

For a single restricted pair, it's straightforward: Total − Bundle. For two restricted pairs, you need inclusion-exclusion to avoid double-subtraction.

Inclusion-Exclusion for two restricted pairs (A,B) and (C,D): 1. Start with Total arrangements 2. Subtract arrangements where A,B are together 3. Subtract arrangements where C,D are together 4. ADD BACK arrangements where BOTH pairs are together (you subtracted these twice)

Formula: Valid = Total − |AB together| − |CD together| + |AB AND CD together|

The reason you add back step 4: any arrangement where both A,B AND C,D are together was subtracted once in step 2 AND once in step 3. That's double-subtraction. Step 4 corrects for this by adding those cases back exactly once.

For interviews, you'll almost never need beyond two restricted pairs, so this two-pair version covers 95% of problems. But understanding the inclusion-exclusion principle shows the interviewer you think in systems, not just formulas.

io/thecodeforge/seating/complement_method_seating.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
import math
from itertools import permutations

def circular_never_together(total_people):
    """
    One specific PAIR must NEVER sit together at a round table.
    Complement: Total - arrangements where pair IS together.
    """
    total_circular = math.factorial(total_people - 1)
    units_with_bundle = total_people - 2 + 1
    bundle_circular = math.factorial(units_with_bundle - 1)
    bundle_internal = math.factorial(2)
    arrangements_together = bundle_circular * bundle_internal
    valid = total_circular - arrangements_together
    return total_circular, arrangements_together, valid

def circular_two_pairs_never_together(total_people):
    """
    Two pairs (A,B) and (C,D) must each NEVER sit together.
    Uses inclusion-exclusion to avoid double-subtraction.
    """
    total_circular = math.factorial(total_people - 1)

    # Pair 1 (A,B) together
    units_ab = total_people - 2 + 1
    ab_together = math.factorial(units_ab - 1) * math.factorial(2)

    # Pair 2 (C,D) together
    units_cd = total_people - 2 + 1
    cd_together = math.factorial(units_cd - 1) * math.factorial(2)

    # BOTH pairs together (two bundles)
    units_both = total_people - 4 + 2
    both_together = math.factorial(units_both - 1) * math.factorial(2) * math.factorial(2)

    # Inclusion-Exclusion
    valid = total_circular - ab_together - cd_together + both_together
    return total_circular, ab_together, cd_together, both_together, valid

# --- Single pair: 5 people, D and E never adjacent ---
total = 5
total_circ, together, valid = circular_never_together(total)
print(f"=== SINGLE RESTRICTED PAIR: {total} people ===")
print(f"Total circular: ({total}-1)! = {total_circ}")
print(f"Together (bundle): {together}")
print(f"Never together: {total_circ} - {together} = {valid}")

# Brute-force verification
people = ['A', 'B', 'C', 'D', 'E']
def are_adjacent_circular(arr, p1, p2):
    n = len(arr)
    i1, i2 = arr.index(p1), arr.index(p2)
    return abs(i1 - i2) == 1 or abs(i1 - i2) == n - 1

fixed = [('A',) + perm for perm in permutations(['B', 'C', 'D', 'E'])]
valid_brute = [a for a in fixed if not are_adjacent_circular(list(a), 'D', 'E')]
print(f"Brute-force: {len(valid_brute)} — Match: {valid == len(valid_brute)}")

print()

# --- Two restricted pairs: 7 people ---
total2 = 7
total2_circ, ab2, cd2, both2, valid2 = circular_two_pairs_never_together(total2)
print(f"=== TWO RESTRICTED PAIRS: {total2} people ===")
print(f"Total circular: {total2_circ}")
print(f"A,B together: {ab2}")
print(f"C,D together: {cd2}")
print(f"Both together: {both2}")
print(f"Never together (inclusion-exclusion): {total2_circ} - {ab2} - {cd2} + {both2} = {valid2}")
print(f"\nWRONG approach (no inclusion-exclusion): {total2_circ} - {ab2} - {cd2} = {total2_circ - ab2 - cd2}")
print(f"Difference: {valid2 - (total2_circ - ab2 - cd2)} cases were double-subtracted")
Output
=== SINGLE RESTRICTED PAIR: 5 people ===
Total circular: (5-1)! = 24
Together (bundle): 12
Never together: 24 - 12 = 12
Brute-force: 12 — Match: True
=== TWO RESTRICTED PAIRS: 7 people ===
Total circular: 720
A,B together: 240
C,D together: 240
Both together: 96
Never together (inclusion-exclusion): 720 - 240 - 240 + 96 = 336
WRONG approach (no inclusion-exclusion): 720 - 240 - 240 = 240
Difference: 96 cases were double-subtracted
Inclusion-Exclusion — The Double-Subtraction Trap:
When TWO separate pairs must never sit together, don't just subtract both bundle counts independently. You'd double-subtract the cases where BOTH pairs happen to be together. The output shows this clearly: without inclusion-exclusion you get 240 (wrong), with it you get 336 (correct). The 96 difference is exactly the number of arrangements where both pairs were together — cases subtracted twice that needed to be added back once.
Production Insight
In conference seating tools, subtracting both pairs without inclusion-exclusion removed valid arrangements that had both pairs together.
Use inclusion-exclusion for multiple restrictions: subtract each, add back overlap.
Key Takeaway
Never-together = total - together.
For two pairs: total - AB - CD + both_to_avoid_double_subtraction.

Alternating Arrangements — The Gaps Technique

One of the most common exam patterns: '5 boys and 4 girls are to be seated such that no two girls sit adjacent.' The key insight is the gaps technique.

The logic: arrange the larger group first (boys). This creates 'gaps' between them — positions where the smaller group (girls) can be placed. Since no two girls can be adjacent, each girl must go in a different gap.

In a linear row: N people create N+1 gaps (one before the first person, one between each pair, and one after the last person).

In a circle: N people create exactly N gaps (no 'before first' or 'after last' — the circle has no ends).

Step-by-step: 1. Arrange the larger group: boys in a row = 5! = 120 ways (linear) or (5-1)! = 24 ways (circular) 2. Count the gaps: 6 gaps (linear) or 5 gaps (circular) 3. Place the smaller group in those gaps: choose and arrange 4 girls in 6 gaps = P(6,4) = 360 (linear) or P(5,4) = 120 (circular) 4. Multiply: 120 × 360 = 43,200 (linear) or 24 × 120 = 2,880 (circular)

The critical distinction: linear creates one extra gap at each end (N+1 total), while circular creates no end gaps (N total). This is why the circular count is always lower for alternating problems.

Why place the larger group first? More people = more gaps = more room for the smaller group. If you placed girls first (4 girls → 5 gaps linear, 4 gaps circular), you'd still have enough gaps for 5 boys in linear (5 gaps ≥ 5 boys) but not enough in circular (4 gaps < 5 boys). Always arrange the larger group first to maximise available gaps.

io/thecodeforge/seating/alternating_arrangements.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
import math

def linear_alternating(total_group1, total_group2):
    """
    Linear row: no two members of group2 adjacent.
    Place group1 first (larger group), creating gaps.
    Gaps = total_group1 + 1 (extra gap at each end).
    """
    if total_group2 > total_group1 + 1:
        return 0, 0, 0, 0
    ways_group1 = math.factorial(total_group1)
    gaps = total_group1 + 1
    ways_group2 = math.perm(gaps, total_group2)
    total = ways_group1 * ways_group2
    return total, ways_group1, gaps, ways_group2

def circular_alternating(total_group1, total_group2):
    """
    Circular table: no two members of group2 adjacent.
    Fix one from group1, arrange rest.
    Gaps = total_group1 (no end gaps in a circle).
    """
    if total_group2 > total_group1:
        return 0, 0, 0, 0
    ways_group1 = math.factorial(total_group1 - 1)
    gaps = total_group1
    ways_group2 = math.perm(gaps, total_group2)
    total = ways_group1 * ways_group2
    return total, ways_group1, gaps, ways_group2

# --- Linear: 5 boys, 4 girls — no two girls adjacent ---
boys, girls = 5, 4
total_lin, ways_b, gaps_lin, ways_g = linear_alternating(boys, girls)
print(f"=== LINEAR: {boys} boys, {girls} girls, no two girls adjacent ===")
print(f"Arrange boys: {boys}! = {ways_b}")
print(f"Gaps created: {gaps_lin} (since {boys} people in a row create {boys+1} gaps)")
print(f"Place {girls} girls in {gaps_lin} gaps: P({gaps_lin},{girls}) = {ways_g}")
print(f"Total: {ways_b} × {ways_g} = {total_lin}")

# --- Circular: 5 boys, 4 girls ---
total_circ, ways_b_circ, gaps_circ, ways_g_circ = circular_alternating(boys, girls)
print(f"\n=== CIRCULAR: {boys} boys, {girls} girls, no two girls adjacent ===")
print(f"Arrange boys in a circle: ({boys}-1)! = {ways_b_circ}")
print(f"Gaps created: {gaps_circ} (since {boys} people in a circle create exactly {boys} gaps)")
print(f"Place {girls} girls in {gaps_circ} gaps: P({gaps_circ},{girls}) = {ways_g_circ}")
print(f"Total: {ways_b_circ} × {ways_g_circ} = {total_circ}")

# --- Why order matters: compare with placing girls first ---
print(f"\n=== Why larger group first? ===")
print(f"If we placed {girls} girls first in a circle:")
print(f"  Gaps created: {girls} (since {girls} people in a circle create {girls} gaps)")
print(f"  Need to place {boys} boys in {girls} gaps: P({girls},{boys}) = {math.perm(girls, boys)}")
print(f"  That's {math.perm(girls, boys)} arrangements — which is zero because {boys} > {girls}, impossible!")
print(f"Always arrange the larger group first to create enough gaps.")
Output
=== LINEAR: 5 boys, 4 girls, no two girls adjacent ===
Arrange boys: 5! = 120
Gaps created: 6 (since 5 people in a row create 6 gaps)
Place 4 girls in 6 gaps: P(6,4) = 360
Total: 120 × 360 = 43200
=== CIRCULAR: 5 boys, 4 girls, no two girls adjacent ===
Arrange boys in a circle: (5-1)! = 24
Gaps created: 5 (since 5 people in a circle create exactly 5 gaps)
Place 4 girls in 5 gaps: P(5,4) = 120
Total: 24 × 120 = 2880
=== Why larger group first? ===
If we placed 4 girls first in a circle:
Gaps created: 4 (since 4 people in a circle create 4 gaps)
Need to place 5 boys in 4 gaps: P(4,5) = 0
That's 0 arrangements — because 5 > 4, impossible!
Always arrange the larger group first to create enough gaps.
Key Distinction — Linear vs Circular Gaps:
In a linear row, N people create N+1 gaps (ends count). In a circle, N people create exactly N gaps (no ends). This is why alternating problems always have more arrangements in linear than circular for the same counts. For '5 boys, 4 girls, no two girls adjacent': linear = 43,200, circular = 2,880 — the linear count is 15 times larger, precisely because of the extra gap at each end.
Production Insight
In exam hall seating software, placing smaller group first resulted in insufficient gaps and zero valid arrangements.
Always place larger group first to maximise gaps.
Key Takeaway
Linear gaps = N+1, circular gaps = N.
Arrange larger group first, then place smaller group in gaps.

Word and Letter Arrangements — Handling Identical Objects

Seating arrangement isn't just about people. Many exam problems ask: 'In how many ways can the letters of the word ARRANGE be arranged?' This is the same combinatorics, but with a twist — some objects (letters) are identical, which reduces the count.

The formula for arranging N objects where some are identical: N! / (n₁! × n₂! × ... × nₖ!) where n₁, n₂, etc. are the counts of each repeated letter.

For ARRANGE: 7 letters total. A appears 2 times, R appears 2 times. So: 7! / (2! × 2!) = 5040 / 4 = 1260 distinct arrangements.

Why divide? Because swapping two identical A's doesn't create a new arrangement — AR₁R₂ANGE looks the same as AR₂R₁ANGE. The 2! in the denominator removes those duplicate swaps for each repeated letter.

The complement method works here too. 'How many arrangements of ARRANGE have the two R's never together?' Total arrangements (1260) minus arrangements where both R's ARE together (treat RR as one unit: 6! / 2! = 360) = 1260 − 360 = 900.

This pattern appears in exams disguised as seating problems: 'In how many ways can 3 identical red balls and 2 identical blue balls be arranged in a row?' Same formula: 5! / (3! × 2!) = 10.

io/thecodeforge/seating/word_arrangements.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
import math
from collections import Counter

def distinct_arrangements(word):
    """
    Count distinct arrangements of a word's letters.
    Accounts for repeated letters by dividing out duplicate permutations.
    Formula: N! / (n1! x n2! x ... x nk!)
    """
    total_letters = len(word)
    letter_counts = Counter(word)
    numerator = math.factorial(total_letters)
    denominator = 1
    for letter, count in letter_counts.items():
        denominator *= math.factorial(count)
    return numerator // denominator, total_letters, letter_counts

def word_with_letters_never_together(word, restricted_letter):
    """
    Count arrangements where specific repeated letters never appear adjacent.
    Uses complement: Total - arrangements where they ARE together.
    """
    total_distinct, total_letters, letter_counts = distinct_arrangements(word)

    # Bundle the restricted letters as one unit
    bundled_word_length = total_letters - 2 + 1
    bundled_counts = dict(letter_counts)
    bundled_counts[restricted_letter] -= 2
    if bundled_counts[restricted_letter] == 0:
        del bundled_counts[restricted_letter]
    bundled_counts[restricted_letter*2] = 1  # marker for the bundle

    # Recalculate denominator for bundled word
    denom_bundled = 1
    for cnt in bundled_counts.values():
        denom_bundled *= math.factorial(cnt)

    arrangements_together = math.factorial(bundled_word_length) // denom_bundled
    valid = total_distinct - arrangements_together
    return total_distinct, arrangements_together, valid

# --- ARRANGE example ---
word = "ARRANGE"
total, length, counts = distinct_arrangements(word)
print(f"=== Word: {word} (length {length}) ===")
print(f"Letter counts: {dict(counts)}")
print(f"Total distinct arrangements: {length}! / (2! × 2!) = {total}")

# Complement for two R's never together
total_arr, together_arr, valid_arr = word_with_letters_never_together(word, 'R')
print(f"\n=== Two R's NEVER together in {word} ===")
print(f"Total arrangements: {total_arr}")
print(f"Arrangements with R's together (treat RR as unit): {together_arr}")
print(f"Valid arrangements: {total_arr} - {together_arr} = {valid_arr}")

# --- Identical objects example ---
print("\n=== Identical objects: 3 red balls (R), 2 blue balls (B) in a row ===")
total_balls = 5
red, blue = 3, 2
identical_arrangements = math.factorial(total_balls) // (math.factorial(red) * math.factorial(blue))
print(f"Total arrangements: 5! / (3! × 2!) = {identical_arrangements}")

# --- Sanity check: sum of permutations equals total? ---
print("\n=== Sanity check: total = together + never-together ===")
print(f"Together: {together_arr} + Never: {valid_arr} = {together_arr + valid_arr}")
print(f"Should equal total: {total_arr} → {together_arr + valid_arr == total_arr}")
Output
=== Word: ARRANGE (length 7) ===
Letter counts: {'A': 2
Sanity Check — Total = Together + Never-Together:
After you compute the complement, always verify that the 'together' count plus the 'never-together' count equals your total distinct arrangements. In the ARRANGE example, 360 + 900 = 1260. If they don't sum, you made an arithmetic error or missed a case in inclusion-exclusion. This simple check catches more mistakes than any other single step.
Production Insight
In password generation systems, treating identical characters as distinct would generate 4x more passwords than possible.
Always divide by factorials of repeated letters.
Key Takeaway
Identical objects reduce permutation count: N! / (n1! n2! ...).
Complement works: total - bundle(repeated letters together).
● Production incidentPOST-MORTEMseverity: high

Airline Seat Allocation Bug: How Circular vs Linear Confusion Caused Overbooking

Symptom
System allowed more than 180 passenger configurations on a flight with 180 seats, causing double bookings.
Assumption
Assumed all seats are distinct positions, but the cabin layout had rotational symmetry.
Root cause
Used linear permutation formula N! instead of circular (N-1)! for seat arrangement calculations in a circular seating area.
Fix
Updated the algorithm to use (N-1)! for circular sections; added a validation check comparing total arrangements to physical seat count.
Key lesson
  • Always verify whether positions are fixed or relative before choosing permutation formula.
  • In real systems, seating symmetry is not always obvious – check cabin layout specifications.
Production debug guideCommon calculation errors and how to identify them4 entries
Symptom · 01
Answer is exactly N times too large
Fix
Check if circular problem treated as linear – compare to (N-1)! baseline.
Symptom · 02
Answer missing factor of K! for bundle
Fix
Recalculate bundle internal arrangements; ensure you multiplied by K! after arranging units.
Symptom · 03
Never-together count equals total - together but includes double-subtraction
Fix
Use inclusion-exclusion: add back cases where both pairs are together.
Symptom · 04
Alternating arrangement answer is zero
Fix
Check if smaller group placed first – rearrange larger group first to create enough gaps.
FeatureLinear ArrangementCircular Arrangement
No restrictions (N people)N!(N-1)!
'K must sit together' formulaK! × (N−K+1)!K! × (N−K)!
'Never sit together' methodTotal − bundle countTotal − bundle count
Alternating arrangement gapsN+1 gapsN gaps
When to use necklace formulaNeverOnly when clockwise = anticlockwise (explicitly stated)
Identical objects formulaN! / (n₁! × n₂! × ...)(N-1)! / (n₁! × n₂! × ...)
Probability of two together2/(N) for two in a row2/(N-1) for two at a round table

Key takeaways

1
The circular formula (N-1)! isn't a separate rule
it's N! divided by N rotational duplicates. Understand that and you'll never confuse the two formulas again. If the table has a fixed reference point (numbered chairs, head position), use N!.
2
The bundle trick converts a 'must sit together' constraint into a smaller, simpler problem
treat the group as one unit, arrange everything, then multiply by the group's internal arrangements (K!) at the end.
3
The complement method is almost always faster for 'never together' problems
count everything, subtract the cases where the unwanted arrangement occurs (which you can get with the bundle trick).
4
For alternating arrangements, always place the larger group first to create maximum gaps. Linear gaps = N+1 (ends included), circular gaps = N (no ends). This distinction is the difference between correct and incorrect answers.
5
Inclusion-exclusion is essential for multiple restricted pairs. Don't just subtract each pair's bundle count independently
add back the overlap where both pairs are together, because you subtracted those cases twice.
6
Word arrangements with repeated letters use N! / (n₁! × n₂! × ...) to remove duplicate permutations of identical objects. The complement method works here too
bundle the repeated letters and subtract.
7
The probability shortcut P(together) = 2/(N-1) for circular tables saves time in exams. For 6 people it's 40%, for 10 people it's 22.2%. No derivation needed
just plug in N.
8
Always run the sanity check
for a two-person restriction, arrangements where they're always together plus arrangements where they're never together must equal the unrestricted total. If it doesn't add up, find the error before moving on.
9
In interviews, always clarify whether rotations are considered identical before choosing your formula. Asking 'are the chairs numbered or is this a standard round table?' demonstrates analytical thinking that interviewers value.

Common mistakes to avoid

7 patterns
×

Using N! instead of (N-1)! for circular arrangements

Symptom
Answer comes out N times too large; won't match any option in multiple-choice exams.
Fix
Always ask yourself 'Does rotating everyone one seat give a new arrangement?' If no (round table), use (N-1)!. If yes (seats numbered/labelled), use N!.
×

Forgetting the internal arrangement factor in the bundle trick

Symptom
You get the right circular-of-units count but miss multiplying by K!, giving an answer K! times too small.
Fix
After counting how the bundles and individuals arrange around the table, always ask 'how many ways can people inside the bundle swap?' Multiply by that K!.
×

Applying the complement method without checking for double-subtraction

Symptom
When two different pairs are both restricted from sitting together, subtracting both bundle counts independently over-subtracts cases where both restrictions are violated simultaneously, giving a number that's too low.
Fix
Use inclusion-exclusion: Valid = Total − |pair1 together| − |pair2 together| + |both pairs together at once|.
×

Confusing 'probability of together' with 'count of together'

Symptom
If the question asks for probability, don't just report the bundle count. Divide by the total arrangements. P(together) = Bundle / Total = 2/(N-1) for circular. Many students calculate the bundle count correctly but forget the final division and mark the arrangement count as the probability.
Fix
Always check whether the problem asks for 'number of ways' or 'probability'. If probability, divide by total arrangements.
×

Confusing linear and circular gap counts in alternating problems

Symptom
In a linear row, N people create N+1 gaps. In a circle, N people create exactly N gaps. Forgetting this distinction gives wrong answers.
Fix
Linear gaps = N+1, circular gaps = N. Always verify which type the problem specifies before counting gaps.
×

Treating identical objects as distinct

Symptom
In word arrangement problems, swapping two identical letters (like the two A's in ARRANGE) doesn't create a new arrangement. If you calculate 7! for ARRANGE without dividing by 2! × 2!, your answer is 4 times too large.
Fix
Use N! / (n₁! × n₂! × ...) where n₁, n₂ are the counts of each repeated letter.
×

Not clarifying assumptions in circular problems

Symptom
Some problems say 'round table' but also mention 'one seat faces the stage' or 'seats are numbered.' If there's any fixed reference point, the arrangement is effectively linear, not circular. Always ask (or state) whether rotations are considered identical before choosing your formula.
Fix
In interviews, this clarifying question itself demonstrates strong analytical thinking.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
In how many ways can 8 people be seated around a circular table if two s...
Q02SENIOR
How many ways can the word ARRANGE be arranged so that the two R's never...
Q03SENIOR
If 5 boys and 4 girls are to be seated in a row such that no two girls s...
Q04SENIOR
What is the probability that two specific people sit together at a circu...
Q05SENIOR
How would you handle a problem where (A,B) must never sit together AND (...
Q06JUNIOR
In how many ways can 3 identical red balls and 2 identical blue balls be...
Q07SENIOR
A round table has 8 chairs, but one chair faces the stage and is conside...
Q08SENIOR
If 6 people sit around a round table, what is the probability that two s...
Q01 of 08SENIOR

In how many ways can 8 people be seated around a circular table if two specific people must always sit next to each other? Walk me through your reasoning step by step.

ANSWER
Treat the two specific people as a single bundle. For circular arrangements, fix one person (or the bundle) to eliminate rotations. We have 8 people total, bundle reduces count to 7 units. Circular arrangements of 7 units: (7-1)! = 6! = 720. Inside the bundle, the two people can swap places in 2! = 2 ways. So total = 720 × 2 = 1440 arrangements. If the seats are numbered, treat as linear: 7! × 2 = 5040 × 2 = 10080.
FAQ · 8 QUESTIONS

Frequently Asked Questions

01
What is the formula for circular seating arrangements?
02
How do you solve seating problems where two people must sit together?
03
When should I use the complement method in seating arrangement problems?
04
What is the difference between permutations and combinations in seating problems?
05
How do you handle alternating arrangement problems (e.g., boys and girls)?
06
How do you solve word arrangement problems with repeated letters?
07
What is the shortcut formula for probability of two people sitting together at a circular table?
08
When do you use the necklace formula (N-1)!/2 instead of (N-1)!?
🔥

That's Aptitude. Mark it forged?

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

Previous
Logical Reasoning Patterns
7 / 14 · Aptitude
Next
Blood Relation Problems