Skip to content

S1Q2 · Expand Sum of Products

⚡ Quick Reference

Function: expand_sum_of_products(expr: str) -> str

Core idea: strip spaces, extract the two bracketed groups, split each on +, then produce all four products.

def expand_sum_of_products(expr: str) -> str:
    expr = expr.replace(" ", "")
    # split on ")(" to get the two groups
    left, right = expr[1:-1].split(")(")
    a, b = left.split("+")
    c, d = right.split("+")
    return f"{a}*{c} + {a}*{d} + {b}*{c} + {b}*{d}"

Key rules: - Strip spaces first with replace(" ", "") - expr[1:-1] removes the outer ( and ) - Split on )( to separate the two factor groups - Always exactly one + per group -guaranteed by problem


Problem Statement

Problem

Write a function expand_sum_of_products(expr) that expands "(a+b)(c+d)" into "a*c + a*d + b*c + b*d". Spaces may appear anywhere in the input and must be ignored.

Examples:

Input
"(a+b)(c+d)"
Output
"a*c + a*d + b*c + b*d"
Input
"(1+5)(10+12)"
Output
"1*10 + 1*12 + 5*10 + 5*12"

Understanding the problem

The expression always has the structure (a+b)(c+d). The goal is to apply the distributive law:

(a+b)(c+d) = a·c + a·d + b·c + b·d

The trick is parsing the string correctly. After stripping spaces:

"(a+b)(c+d)"

Step 1 -remove outer chars: expr[1:-1] → "a+b)(c+d"
Step 2 -split on ")("      → ["a+b", "c+d"]
Step 3 -split each on "+"  → a="a", b="b", c="c", d="d"
Step 4 -format output      → "a*c + a*d + b*c + b*d"

expr[1:-1].split(')(')

After stripping spaces, the expression always starts with ( and ends with ). Removing both with [1:-1] gives "a+b)(c+d". Splitting this on )( neatly separates the two factor groups without needing regex.


Tracing the examples

"(a+b)(c+d)"

strip spaces → "(a+b)(c+d)"
[1:-1]       → "a+b)(c+d"
split(")(")  → ["a+b", "c+d"]
split("+")   → a="a", b="b", c="c", d="d"
output       → "a*c + a*d + b*c + b*d" 

"(1+5)(10+12)"

strip spaces → "(1+5)(10+12)"
[1:-1]       → "1+5)(10+12"
split(")(")  → ["1+5", "10+12"]
split("+")   → a="1", b="5", c="10", d="12"
output       → "1*10 + 1*12 + 5*10 + 5*12" 


Solution approaches

def expand_sum_of_products(expr: str) -> str:
    expr = expr.replace(" ", "")
    left, right = expr[1:-1].split(")(")
    a, b = left.split("+")
    c, d = right.split("+")
    return f"{a}*{c} + {a}*{d} + {b}*{c} + {b}*{d}"
def expand_sum_of_products(expr: str) -> str:
    # Remove all spaces
    expr = expr.replace(" ", "")

    # Remove outer parentheses and split into two groups
    inner = expr[1:-1]              # "a+b)(c+d"
    group1, group2 = inner.split(")(")

    # Extract individual terms
    a, b = group1.split("+")
    c, d = group2.split("+")

    # Build the four products
    terms = [f"{a}*{c}", f"{a}*{d}", f"{b}*{c}", f"{b}*{d}"]
    return " + ".join(terms)

Building the terms as a list then joining with " + " makes the output format easy to adjust.

import re

def expand_sum_of_products(expr: str) -> str:
    expr = expr.replace(" ", "")
    # Extract content of each bracket
    groups = re.findall(r'\(([^)]+)\)', expr)
    a, b = groups[0].split("+")
    c, d = groups[1].split("+")
    return f"{a}*{c} + {a}*{d} + {b}*{c} + {b}*{d}"

re.findall(r'\(([^)]+)\)', expr) extracts the content inside each pair of brackets. More robust if the expression format were to vary, but overkill for this fixed structure.

from itertools import product

def expand_sum_of_products(expr: str) -> str:
    expr = expr.replace(" ", "")
    left, right = expr[1:-1].split(")(")
    terms_l = left.split("+")
    terms_r = right.split("+")
    return " + ".join(
        map(lambda pair: f"{pair[0]}*{pair[1]}", product(terms_l, terms_r))
    )

itertools.product(terms_l, terms_r) generates all (a,c), (a,d), (b,c), (b,d) pairs in the correct order. map(lambda pair: ...) formats each pair. Scales naturally if either bracket had more than two terms.


Key takeaways

01

expr[1:-1].split(")(") to parse brackets

Removing outer brackets with slicing then splitting on )( is the cleanest way to separate two adjacent bracketed groups without regex.

02

" + ".join(terms) for output formatting

Build each product as a string in a list, then join with " + ". Cleaner than concatenating with hardcoded separators and easy to adapt.

03

itertools.product for Cartesian pairs

itertools.product(A, B) generates all (a, b) pairs -exactly what polynomial expansion requires. Use it when the number of terms per bracket might vary.