← Asana Interview Insights

Asana·Software Engineer·Technical Phone Screen·Senior

Senior
Jun 2026

Summary

Asana software engineer interview with a genuinely tricky puzzle-solving problem. The question had two unknowns baked in at once and the hints they dropped during the session were pretty generous, but there was still a lot to juggle on the spot.

Questions Asked (5)

Q1

You're given N jigsaw puzzle pieces, each with four edges, and a match() function that tells you if two edges connect. The pieces form exactly one rectangular grid, but you don't know the number of rows or columns. Pieces can be rotated 0, 90, 180, or 270 degrees. Implement solve(pieces) that returns a valid arrangement including each piece's orientation.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

This one wrecked me for the first few minutes because I kept trying to figure out the grid shape and piece placement at the same time, which is just too much to hold in your head.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the problem constraints and edge cases, then propose a backtracking algorithm that places pieces one by one, using the match() function to validate connections and trying all rotations. Optimize by pruning invalid placements early and using heuristics like most constrained position first.

Pro tip: Demonstrate awareness of performance trade-offs: mention that while backtracking is straightforward, it can be exponential, so discuss optimizations like memoization or constraint propagation, and be prepared to code a clean recursive solution.

1. Clarify requirements and constraints

Ask about input size, whether match() is symmetric, if pieces are unique, and if the grid dimensions are known. Confirm output format.

2. Model the problem and choose an algorithm

Represent pieces as objects with four edges and orientation. Propose backtracking with recursive placement, trying all rotations at each step.

3. Define placement and validation logic

Determine grid dimensions by factoring N or by building incrementally. For each candidate position, check compatibility with already placed neighbors using match().

4. Implement and optimize

Write recursive solve() that places pieces row by row, backtracking on failure. Add pruning: if a piece has no valid rotation, backtrack immediately. Consider heuristics like placing corner pieces first.

5. Test and discuss trade-offs

Walk through a small example, test edge cases (1 piece, non-square grid), and discuss time/space complexity and potential optimizations.

Key Points to Mention

  • Backtracking with recursion as the core algorithm
  • Handling rotations by trying all four orientations for each piece
  • Using match() to validate edges with adjacent pieces
  • Determining grid dimensions (e.g., by factoring N or building incrementally)
  • Pruning invalid placements early to reduce search space
  • Time complexity analysis and potential optimizations (e.g., constraint propagation, memoization)

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

How do you handle the unknown grid dimensions when the total number of pieces N is known but R and C are not?

Algorithms & Data StructuresAdaptability & Ambiguity
Author's notes

Straightforward once you realize N only has a small number of factor pairs.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the problem constraints and assumptions, then propose a systematic method to determine R and C from N, such as factorization or iterative search. Emphasize the importance of handling ambiguity by considering edge cases and validating the solution.

Pro tip: Mention that you would first check if the problem guarantees a unique solution or if multiple (R, C) pairs are possible, and discuss how to handle each scenario. This shows you think about real-world ambiguity and not just the happy path.

1. Clarify the problem

Ask questions to understand if there are any constraints on R and C (e.g., R <= C, or both > 1) and whether the grid must be fully filled or can have empty cells.

2. Identify possible (R, C) pairs

Since N = R * C, list all factor pairs of N. If additional constraints exist, filter the list accordingly.

3. Choose a strategy

If multiple pairs are valid, decide how to proceed: either ask for more information, or if the problem allows, pick a reasonable default (e.g., the pair closest to a square).

4. Validate and handle edge cases

Check for edge cases like N being prime (only 1xN or Nx1), N=1, or N=0. Ensure the chosen dimensions make sense for the problem context.

5. Communicate assumptions

Clearly state any assumptions made and how they affect the solution, demonstrating adaptability to ambiguity.

Key Points to Mention

  • Factorization of N to find all possible (R, C) pairs
  • Constraints that might narrow down the possibilities (e.g., R and C must be integers, R <= C, etc.)
  • Handling multiple valid solutions by asking for clarification or choosing a heuristic
  • Edge cases: prime N, N=1, N=0, or non-integer dimensions
  • Time and space complexity of the approach (e.g., O(sqrt(N)) for factorization)
  • Real-world application: how this ambiguity might arise and how to adapt

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

Walk through your backtracking approach: how do you place pieces, recurse, and undo correctly so no piece is used twice or lost on failure?

Algorithms & Data Structures
Author's notes

I described marking a piece as used in a set, recursing, and removing it from the set on the way back up.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Structure your answer by first defining the state (e.g., board, remaining pieces) and the recursive function that attempts to place a piece at each valid position. Emphasize the invariant that each piece is used exactly once, and clearly explain how you undo the placement (backtrack) when a branch fails. Conclude with how you detect success and handle the base case.

Pro tip: Mention that you can use a boolean array or bitmask to track used pieces, and that undoing must restore the state exactly as before—this shows attention to correctness and efficiency.

1. Define the state and base case

Identify what constitutes the current state (e.g., board configuration, set of used pieces) and the condition for a complete solution (all pieces placed).

2. Iterate over choices

For the current state, iterate over all possible pieces and positions where a piece can be placed without conflict.

3. Place and recurse

Temporarily place the chosen piece, mark it as used, and recursively call the function to solve the remaining subproblem.

4. Undo (backtrack)

After the recursive call returns (whether success or failure), remove the piece from the board and unmark it as used, restoring the state to exactly what it was before the placement.

5. Return result

If the recursive call succeeds, propagate success; otherwise, continue trying other choices. If no choices work, return failure.

Key Points to Mention

  • State representation: board, used pieces (e.g., boolean array or bitmask), and current index.
  • Validity check: ensure the piece can be placed at the chosen position without conflicts.
  • Recursive call: explore the next step with the updated state.
  • Backtracking: undo the placement and unmark the piece to restore the previous state.
  • Base case: all pieces placed successfully, return true.
  • Failure handling: if no valid placement leads to a solution, return false and backtrack.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

If match() is expensive, say it involves a network call or a vision model, how do you reduce the number of calls?

Technical Trade-offsSystem Design
Author's notes

Cache results keyed by (edgeA, edgeB) pairs if edges are hashable.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the context: what match() does, its cost, and the acceptable trade-offs (latency, accuracy, freshness). Then propose a layered strategy: reduce calls via caching, batching, and pre-filtering; avoid calls via heuristics or cheaper models; and optimize remaining calls with parallelism and async processing.

Pro tip: Emphasize measuring the actual cost and call frequency first—premature optimization without data can lead to over-engineering. Also, discuss fallback strategies for when the cache misses or the cheap model fails, ensuring robustness.

1. Clarify requirements and constraints

Ask about the cost of match(), acceptable latency, accuracy requirements, and data freshness. This determines which optimization techniques are viable.

2. Reduce call volume

Implement caching (memoization, distributed cache), batching multiple requests into one call, and pre-filtering candidates using cheap heuristics to avoid unnecessary match() calls.

3. Avoid expensive calls

Use approximate methods or cheaper models for initial filtering, and only invoke the expensive match() when necessary. Consider precomputing results offline if data is static.

4. Optimize remaining calls

Parallelize independent calls, use asynchronous processing, and set timeouts/retries with backoff. Consider rate limiting and queueing to manage load.

5. Monitor and iterate

Instrument metrics (call count, latency, cache hit rate) and continuously evaluate trade-offs. Be prepared to adjust strategy based on changing requirements.

Key Points to Mention

  • Caching strategies (in-memory, distributed, TTL, invalidation)
  • Batching multiple match requests into a single call
  • Pre-filtering with cheap heuristics or approximate models
  • Asynchronous and parallel processing to hide latency
  • Fallback mechanisms and graceful degradation
  • Measuring and monitoring to validate optimizations

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q5

How would you adapt the solution if pieces can also be flipped (mirrored) in addition to rotated, or if match() can return false positives?

Adaptability & AmbiguityTechnical Trade-offs
Author's notes

Flipping just adds more orientation states per piece, 8 total instead of 4.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First clarify the problem constraints and the impact of the new conditions on the existing solution. Then systematically analyze how flipping and false positives affect correctness and performance, and propose modifications with trade-offs. Finally, discuss testing and validation strategies to ensure robustness.

Pro tip: Demonstrate awareness that false positives may require probabilistic reasoning or additional verification steps, and that flipping can be handled by normalizing orientations. Emphasize the importance of clarifying assumptions before diving into solutions.

1. Clarify the Problem

Ask questions to understand the exact meaning of flipping (e.g., mirroring across which axis?) and false positives (e.g., how often, what causes them?). Confirm the expected input/output and constraints.

2. Assess Impact on Existing Solution

Identify which parts of the current algorithm rely on rotation-only or exact matching. Determine how flipping changes the state space and how false positives could lead to incorrect results.

3. Propose Modifications

For flipping, suggest normalizing pieces to a canonical orientation (e.g., consider all 8 symmetries) or extending the matching logic to include mirrored variants. For false positives, propose adding a verification step, using probabilistic methods, or adjusting the matching threshold.

4. Analyze Trade-offs

Discuss performance implications (e.g., increased time/space complexity due to more orientations) and correctness trade-offs (e.g., stricter matching may reduce false positives but increase false negatives).

5. Testing and Validation

Outline how to test the adapted solution: unit tests for flipping scenarios, stress tests for false positives, and possibly fuzzing or property-based testing to ensure robustness.

Key Points to Mention

  • Normalization of orientations to handle flipping (e.g., canonical representation).
  • Impact on time/space complexity when considering additional symmetries.
  • Strategies to mitigate false positives: verification, thresholds, or probabilistic checks.
  • Trade-offs between precision and recall in matching.
  • Importance of clarifying assumptions with the interviewer.
  • Testing approaches to validate the adapted solution.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.