← Asana Interview Insights

Asana·Software Engineer·Onsite - Coding / Algorithms·Intermediate

Intermediate
Jun 2026

Summary

Coding round at Asana with four problems ranging from backtracking to grid simulation. The questions were varied enough that you couldn't just grind one topic and coast through. Felt like they wanted to see clean code and complexity awareness more than just a working solution.

Questions Asked (4)

Q1

Given N square tiles each with labeled edges (top, right, bottom, left), and the ability to rotate each tile, determine if the tiles can be arranged into an R x C grid where all touching internal edges match. N is small enough for backtracking.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

This one took me a while to even set up correctly.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Model the problem as a constraint satisfaction problem and use backtracking to place tiles row by row, trying all 4 rotations at each cell. At each step, only check constraints with already-placed neighbors (top and left) to prune early. If all tiles are placed successfully, return true; otherwise backtrack.

Pro tip: Precompute all 4 rotations for each tile and represent edges as integers or characters for O(1) comparisons. Also, consider sorting tiles by number of unique edges or using a frequency map to detect impossible cases early, showing you think about optimization beyond brute force.

1. Clarify and Define Constraints

Confirm grid dimensions R and C, tile edge labels, and that rotations are allowed. Ensure N = R * C and discuss edge cases like N=0 or impossible counts.

2. Choose Backtracking with Pruning

Decide to place tiles cell by cell in row-major order. At each cell, try each unused tile in all 4 rotations, checking only the top and left neighbors to prune invalid placements early.

3. Implement Recursive Search

Write a recursive function that takes the current position and a set of used tiles. If position exceeds grid, return true. For each candidate tile and rotation, if constraints match, mark used, recurse, and unmark on failure.

4. Optimize with Precomputation and Heuristics

Precompute rotations for each tile. Optionally, sort tiles or use frequency counts of edge labels to fail fast if counts are odd or mismatched. Discuss time complexity O(N! * 4^N) worst-case but pruned heavily.

5. Test and Validate

Walk through a small example (e.g., 2x2) to demonstrate correctness. Mention testing edge cases: no solution, multiple solutions, and performance for maximum N.

Key Points to Mention

  • Backtracking with constraint propagation (checking only placed neighbors)
  • Representation of tiles and rotations (e.g., array of 4 edges, rotate by shifting)
  • Pruning strategies: early mismatch detection, frequency maps of edge labels
  • Time and space complexity analysis, and why N small makes backtracking feasible
  • Handling of duplicate tiles and avoiding redundant permutations
  • Trade-offs: backtracking vs. exact cover (DLX) or SAT solver for larger N

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

Q2

Implement an ASCII canvas of size H x W. Support commands: fill a rectangle with a character, draw a horizontal line, draw a vertical line. Later commands overwrite earlier ones. Print the final canvas.

Algorithms & Data Structures
Author's notes

Pretty fun problem actually.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the input format and command semantics, then propose a 2D array (or list of lists) to represent the canvas. Process commands in order, overwriting cells as needed, and finally print the canvas row by row.

Pro tip: Mention that you can optimize by storing only the final state and avoiding unnecessary redraws, but prioritize clarity and correctness first. Also, discuss how you would handle edge cases like out-of-bounds coordinates or empty commands.

1. Clarify requirements and edge cases

Ask about the input format (e.g., command strings, function calls), coordinate system (0-indexed or 1-indexed), and behavior for out-of-bounds coordinates. Confirm that later commands overwrite earlier ones.

2. Choose data structure and initialize canvas

Use a 2D array (list of lists) of characters, initially filled with a default character (e.g., space or '.'). Ensure dimensions H x W are correctly handled.

3. Implement command handlers

Write separate functions for filling a rectangle, drawing a horizontal line, and drawing a vertical line. Each function should iterate over the specified range and set the character, overwriting existing values.

4. Process commands sequentially

Iterate through the list of commands in the given order, calling the appropriate handler for each. This ensures overwriting behavior is respected.

5. Output the final canvas

Print each row of the canvas as a string, joining characters. Ensure the output matches the expected format (e.g., no extra spaces).

Key Points to Mention

  • Use a 2D array (list of lists) for O(1) access to any cell.
  • Handle coordinates carefully: validate bounds or assume valid input based on clarification.
  • Overwriting is naturally handled by processing commands in order and setting cells directly.
  • Time complexity: O(H*W + total cells modified) which is optimal for this problem.
  • Space complexity: O(H*W) for the canvas, which is necessary for output.
  • Consider edge cases: empty canvas, commands with zero width/height, and out-of-bounds coordinates.

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

Q3

Return an array where each element is the product of all other elements in the input array. No division allowed, O(n) time, O(1) extra space beyond the output array.

Algorithms & Data Structures
Author's notes

Classic.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Use two passes: first compute prefix products (product of all elements before each index) and store them in the output array; then traverse from right to left, maintaining a running suffix product and multiply it into each output element. This achieves O(n) time and O(1) extra space because only the output array is used for storage.

Pro tip: Clarify that the output array is not counted as extra space, and mention that this approach avoids division, which is important when the array contains zeros. Also, discuss edge cases like empty array or single element.

1. Clarify constraints and edge cases

Confirm that the output array is not considered extra space and discuss handling of zeros, empty arrays, and single-element arrays.

2. Compute prefix products

Initialize the output array and fill it such that each position i holds the product of all elements before i.

3. Compute suffix products and combine

Traverse from right to left, maintaining a running suffix product, and multiply it into the output array at each index.

4. Analyze complexity and test

State that time is O(n) and extra space is O(1), then walk through a small example to verify correctness.

Key Points to Mention

  • Two-pass approach: left-to-right for prefix products, right-to-left for suffix products
  • No division used, so it works even with zeros in the array
  • O(n) time complexity because each element is visited twice
  • O(1) extra space because only the output array is used for storage
  • Handling edge cases: empty array, single element, multiple zeros
  • In-place modification of the output array to store intermediate results

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

Q4

Simulate a single move in 2048 on a 4x4 grid. Given a direction, slide and merge tiles correctly. For example, [2, 2, 2, 0] moving left becomes [4, 2, 0, 0]. Return the updated grid.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

The merge rule is the part that trips people up.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Clarify the rules: for each row (or column) in the direction of movement, extract non-zero tiles, merge adjacent equal values once (left-to-right for left/up, right-to-left for right/down), then pad with zeros. Implement a helper that processes a single line, then apply it to all lines with appropriate indexing for the given direction.

Pro tip: Mention that you'll write a helper function to process a single line, then reuse it for all rows/columns by transposing or reversing as needed—this keeps the code DRY and avoids direction-specific bugs.

1. Clarify rules and edge cases

Confirm that each tile can merge only once per move, and that merges happen in the direction of movement (e.g., leftmost pair first when moving left). Ask about handling empty grids or invalid directions.

2. Design a line-processing helper

Write a function that takes a list of 4 integers and returns the merged list for a left move: filter non-zeros, merge adjacent equals once, then pad with zeros.

3. Generalize to all directions

For left/right, apply the helper to each row (reversing for right). For up/down, apply to each column (reversing for down) by transposing or using column extraction.

4. Implement and test

Code the solution, then test with examples like [2,2,2,0] left -> [4,2,0,0], and edge cases like [2,2,2,2] left -> [4,4,0,0] and [4,4,8,8] left -> [8,16,0,0].

5. Analyze complexity and trade-offs

State that time is O(n^2) for an n x n grid (here n=4), and space is O(n) for the helper. Discuss in-place vs. new grid trade-offs.

Key Points to Mention

  • Merge each tile at most once per move (e.g., [2,2,2,2] left -> [4,4,0,0], not [8,0,0,0]).
  • Process lines in the correct order: for left/up, merge from the start; for right/down, merge from the end.
  • Use a helper function for a single line to avoid duplicating logic for rows and columns.
  • Handle direction by transforming the grid (transpose for vertical moves, reverse for opposite directions).
  • Time complexity O(n^2) and space O(n) for an n x n grid; in-place is possible but may be trickier.
  • Test edge cases: all zeros, no merges, multiple merges, and full grid.

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