PracHub
QuestionsLearningGuidesInterview Prep
|Home/Coding & Algorithms/Asana

Solve a Jigsaw Puzzle

Last updated: Jun 17, 2026

Quick Overview

This question evaluates algorithmic problem-solving, constraint satisfaction, search and pruning strategies, and handling combinatorial state such as piece rotation and placement.

  • medium
  • Asana
  • Coding & Algorithms
  • Software Engineer

Solve a Jigsaw Puzzle

Company: Asana

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

You are given a collection of jigsaw puzzle pieces. Each piece has four edges — `top`, `right`, `bottom`, and `left` — and a helper function `match(edgeA, edgeB)` is provided that returns `true` if two edges can be physically connected and `false` otherwise. The pieces are known to form exactly one complete rectangular grid, but the number of rows $R$ and columns $C$ is **not** given (only that $R \times C = N$, the total number of pieces). Pieces may need to be **rotated** by $0°$, $90°$, $180°$, or $270°$ to fit. Implement a function `solve(pieces)` that returns a valid rectangular arrangement of all pieces — including each piece's chosen orientation — such that every pair of horizontally- or vertically-adjacent edges matches according to `match`. You may assume: - Every piece must be used exactly once. - A valid solution is guaranteed to exist. - The puzzle has no missing pieces. - Border edges (those on the outer boundary of the grid) do not need to match anything outside the puzzle. Walk through your algorithm, the data structures you use, how you handle rotation and the unknown grid dimensions, and the time and space complexity. ```hint Where to start Two unknowns make this hard: the grid shape and each piece's rotation. Pin down the grid shape first — $N$ has only a handful of factor pairs $(R, C)$, so you can try each one. Within a fixed grid, place pieces cell-by-cell in reading order (row-major), so each new piece only has to satisfy its **already-placed** left and top neighbors. ``` ```hint Reduce the search with edge buckets A naive search tries every remaining piece in every rotation at every cell. Prune it: bucket pieces/edges so that, given the required `right` edge of the left neighbor and the required `bottom` edge of the top neighbor, you can look up only the candidates whose corresponding edge could `match`, instead of scanning all $N$ pieces. Corner and border pieces (those with one or two "outside" edges that need no match) are a natural place to anchor the search. ``` ```hint It's backtracking — make it correct first, fast second This is constraint-satisfaction / backtracking: place a candidate, recurse, and **undo** (restore the piece to the available pool) if the recursion dead-ends. A correct backtracker that exploits the "a solution exists" guarantee and prunes hard usually finishes quickly; don't reach for anything fancier until you've nailed the place/recurse/undo skeleton and the rotation bookkeeping. ``` ### Constraints & Assumptions - $N = R \times C$ pieces total; $R$ and $C$ are unknown but $R \times C = N$ exactly, with $R, C \ge 1$. - Each piece is a 4-tuple of edges; edges are opaque values compared **only** through `match` (do not assume `==`, hashing, or an ordering on edges unless you ask). - `match` is the only oracle for compatibility — assume it is reasonably cheap (treat as $O(1)$) and symmetric, i.e. `match(a, b) == match(b, a)`. Still, count `match` calls, since interviewers often probe how many you make. - You are **not** told whether matching is one-to-one. An edge could be compatible with exactly one other edge or with several; your approach must be correct either way, and you should state how this selectivity affects performance. - Rotating a piece cyclically permutes its edges: a $90°$ clockwise rotation maps `[top, right, bottom, left]` → `[left, top, right, bottom]`. - Pieces are distinguishable objects; "use each exactly once" is by identity, not by edge values. - A solution is guaranteed, so you do not need to report "no solution" — but your code should still terminate cleanly if pruning exhausts a candidate grid shape. ### Clarifying Questions to Ask - Is the solution unique, or may there be multiple valid arrangements — and do we need all of them or just one? - Can a single edge be compatible with many other edges, or is `match` close to a perfect bijection on the true neighbors? - How are pieces and edges represented? Can I compare/hash edges directly, or only through `match`? - For border edges, is there a sentinel/`null` edge I can detect, or do I infer "this is a border" purely from the grid position I'm filling? - What is the expected scale of $N$ — dozens, thousands, or millions? Does that change the acceptable complexity? - Should the returned arrangement include each piece's absolute position and rotation, or just relative adjacency? ### What a Strong Answer Covers - **Decomposition of the two unknowns**: a clear plan to resolve grid dimensions (enumerate factor pairs of $N$) separately from per-piece rotation. - A clean **model of a piece and its orientation** so reading any rotated edge is cheap, rather than physically reshuffling data per rotation. - **Cell-by-cell placement in reading order** so each placement is constrained only by already-placed left/top neighbors — turning a global problem into a sequence of local checks. - **Pruning strategy**: edge buckets / candidate lookup, anchoring on corner/border pieces, and early termination of impossible factor pairs or partial grids. - **Backtracking correctness**: marking a piece used, recursing, and properly restoring state on failure (no piece leaks, no double-use). - A correct **complexity analysis** that separates the typical/well-formed case from the adversarial worst case, plus the space used by the visited/used structures. - **Edge cases**: $1 \times N$ and $N \times 1$ strips, $N = 1$, duplicate/ambiguous edge values, symmetric pieces, and how to verify the final grid. ### Follow-up Questions - If `match` is **expensive** (e.g. a network or vision call), how do you minimize the number of calls? What can you cache or precompute? - How would you parallelize or distribute the search across many cores or machines, and where are the synchronization points? - How does the approach change if the puzzle is **not** guaranteed solvable and you must detect "no solution," or if some pieces are missing and the boundary is irregular? - How would you adapt this if pieces could also be **flipped** (mirrored), not just rotated, or if `match` can return false positives/negatives?

Quick Answer: This question evaluates algorithmic problem-solving, constraint satisfaction, search and pruning strategies, and handling combinatorial state such as piece rotation and placement.

Related Interview Questions

  • Find the K Closest Points to the Origin - Asana (medium)
  • Compute Products Excluding Each Index - Asana (medium)
  • Implement an ASCII Art Printer - Asana (medium)
  • Implement ASCII canvas and solve two data problems - Asana (medium)
|Home/Coding & Algorithms/Asana

Solve a Jigsaw Puzzle

Asana logo
Asana
Apr 2, 2026, 12:00 AM
mediumSoftware EngineerTechnical ScreenCoding & Algorithms
71
0

You are given a collection of jigsaw puzzle pieces. Each piece has four edges — top, right, bottom, and left — and a helper function match(edgeA, edgeB) is provided that returns true if two edges can be physically connected and false otherwise.

The pieces are known to form exactly one complete rectangular grid, but the number of rows RRR and columns CCC is not given (only that R×C=NR \times C = NR×C=N, the total number of pieces). Pieces may need to be rotated by 0°0°0°, 90°90°90°, 180°180°180°, or 270°270°270° to fit.

Implement a function solve(pieces) that returns a valid rectangular arrangement of all pieces — including each piece's chosen orientation — such that every pair of horizontally- or vertically-adjacent edges matches according to match.

You may assume:

  • Every piece must be used exactly once.
  • A valid solution is guaranteed to exist.
  • The puzzle has no missing pieces.
  • Border edges (those on the outer boundary of the grid) do not need to match anything outside the puzzle.

Walk through your algorithm, the data structures you use, how you handle rotation and the unknown grid dimensions, and the time and space complexity.

Constraints & Assumptions

  • N=R×CN = R \times CN=R×C pieces total; RRR and CCC are unknown but R×C=NR \times C = NR×C=N exactly, with R,C≥1R, C \ge 1R,C≥1 .
  • Each piece is a 4-tuple of edges; edges are opaque values compared only through match (do not assume == , hashing, or an ordering on edges unless you ask).
  • match is the only oracle for compatibility — assume it is reasonably cheap (treat as O(1)O(1)O(1) ) and symmetric, i.e. match(a, b) == match(b, a) . Still, count match calls, since interviewers often probe how many you make.
  • You are not told whether matching is one-to-one. An edge could be compatible with exactly one other edge or with several; your approach must be correct either way, and you should state how this selectivity affects performance.
  • Rotating a piece cyclically permutes its edges: a 90°90°90° clockwise rotation maps [top, right, bottom, left] → [left, top, right, bottom] .
  • Pieces are distinguishable objects; "use each exactly once" is by identity, not by edge values.
  • A solution is guaranteed, so you do not need to report "no solution" — but your code should still terminate cleanly if pruning exhausts a candidate grid shape.

Clarifying Questions to Ask Guidance

  • Is the solution unique, or may there be multiple valid arrangements — and do we need all of them or just one?
  • Can a single edge be compatible with many other edges, or is match close to a perfect bijection on the true neighbors?
  • How are pieces and edges represented? Can I compare/hash edges directly, or only through match ?
  • For border edges, is there a sentinel/ null edge I can detect, or do I infer "this is a border" purely from the grid position I'm filling?
  • What is the expected scale of NNN — dozens, thousands, or millions? Does that change the acceptable complexity?
  • Should the returned arrangement include each piece's absolute position and rotation, or just relative adjacency?

What a Strong Answer Covers Guidance

  • Decomposition of the two unknowns : a clear plan to resolve grid dimensions (enumerate factor pairs of NNN ) separately from per-piece rotation.
  • A clean model of a piece and its orientation so reading any rotated edge is cheap, rather than physically reshuffling data per rotation.
  • Cell-by-cell placement in reading order so each placement is constrained only by already-placed left/top neighbors — turning a global problem into a sequence of local checks.
  • Pruning strategy : edge buckets / candidate lookup, anchoring on corner/border pieces, and early termination of impossible factor pairs or partial grids.
  • Backtracking correctness : marking a piece used, recursing, and properly restoring state on failure (no piece leaks, no double-use).
  • A correct complexity analysis that separates the typical/well-formed case from the adversarial worst case, plus the space used by the visited/used structures.
  • Edge cases : 1×N1 \times N1×N and N×1N \times 1N×1 strips, N=1N = 1N=1 , duplicate/ambiguous edge values, symmetric pieces, and how to verify the final grid.

Follow-up Questions Guidance

  • If match is expensive (e.g. a network or vision call), how do you minimize the number of calls? What can you cache or precompute?
  • How would you parallelize or distribute the search across many cores or machines, and where are the synchronization points?
  • How does the approach change if the puzzle is not guaranteed solvable and you must detect "no solution," or if some pieces are missing and the boundary is irregular?
  • How would you adapt this if pieces could also be flipped (mirrored), not just rotated, or if match can return false positives/negatives?

Submit Your Answer to Earn 20XP

Sign in to leave a comment

Loading comments...

Browse More Questions

More Coding & Algorithms•More Asana•More Software Engineer•Asana Software Engineer•Asana Coding & Algorithms•Software Engineer Coding & Algorithms
PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.