◀ THE GRIND — BACKTRACKING

Matchsticks to Square

MEDIUM✓ CHIP-TIMEDLC #473 — FULL STATEMENT ↗

The drill: A pile of matchstick lengths — decide whether every stick, used exactly once and never broken, can be arranged into the four equal sides of one square.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

A pile of matchstick lengths arrives, and the drill is to decide whether every single stick — used exactly once, never broken or bent — can be arranged into the four equal sides of one square.

All sticks must be used; none can be left over, and no stick can be split across two sides. The only output needed is a yes-or-no on whether some arrangement makes all four sides equal.

There's no requirement to report which arrangement works, only whether at least one exists — a pile that can't split its total length into four equal parts is an automatic no before any arrangement is even tried.

EX 01
matchsticks = [1, 1, 1, 1]
true
MINIMUM SIZE, ALL FOUR SIDES TRIVIALLY EQUAL
EX 02
matchsticks = [7]
false
ONE STICK CAN NEVER MAKE FOUR SIDES
EX 03
matchsticks = [4, 4, 4]
false
THREE STICKS, ONE SIDE MUST STAY EMPTY
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

A necessary check costs nothing: the total length has to split evenly into four equal sides before any arrangement is even worth trying. What's the target side length once that passes?

HINT 2 THE STRUCTURE

This is bin-packing in disguise — each stick drops into one of four running totals, and every total must land on the target exactly. A stick longer than the target on its own is an instant no.

HINT 3 ONE STEP FROM THE ANSWER

Encode which sticks have been placed as a bitmask, and cache — for each bitmask already seen — how far the current side has filled, as a value mod the target length. Any order that uses the same set of sticks reaches the same partial fill, so each bitmask only needs solving once.

COACH'S BOARD — THE PATTERN, STEP BY STEP
THE SUBSET PROGRESS CACHEPATTERN · BITMASK DP OVER SUBSETSmatchsticks = [1, 1, 2, 2, 2] — target side 2
0
STEP 1

Five sticks: 1, 1, 2, 2, 2. Total 8, so each side must land on exactly 2 — that's the target every subset's progress is measured against.

STEP 1 / 7 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/matchsticks-to-square.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def makesquare(self, matchsticks: List[int]) -> bool:
        total = sum(matchsticks)
        if total % 4 != 0:
            return False
        side = total // 4
        n = len(matchsticks)
        if any(m > side for m in matchsticks):
            return False

        full = 1 << n
        # progress[mask] = how far the current side has filled, mod `side`,
        # after placing exactly the sticks in `mask`. -1 = unreachable.
        progress = [-1] * full
        progress[0] = 0
        for mask in range(full):
            if progress[mask] == -1:
                continue
            for i in range(n):
                if mask & (1 << i):
                    continue
                nxt = mask | (1 << i)
                if progress[nxt] != -1:
                    continue
                if progress[mask] + matchsticks[i] <= side:
                    progress[nxt] = (progress[mask] + matchsticks[i]) % side

        return progress[full - 1] == 0
TIME O(N · 2^N)SPACE O(2^N)PYTHON · RACE PACE · 28 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED