← Citadel Interview Insights

Citadel·Software Engineer·Technical Phone Screen·Intermediate

IntermediatePrefer not to say
Jun 2026

Summary

Citadel software engineer interview that was heavier on implementation detail than I expected. The problem looked like a fun game exercise on the surface but the encode/decode part is where they actually separated candidates.

Questions Asked (2)

Q1

Implement a working 2048 game from scratch, including board state representation, all four directional moves with proper merge logic, and random tile spawning.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

The move logic tripped me up more than I'd like to admit.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and edge cases (e.g., board size, win/lose conditions, scoring). Then outline a clean design: a 2D array for the board, a generic move function that handles all directions via rotation or transformation, and a spawn function that adds a 2 or 4 in a random empty cell. Finally, discuss trade-offs and potential optimizations.

Pro tip: Mention that you can implement a single move function by rotating the board to always slide left, then rotating back—this reduces code duplication and bugs. Also, emphasize testing edge cases like merges at the end of a row and no-op moves.

1. Clarify requirements and constraints

Ask about board size (typically 4x4), win condition (2048 tile), scoring, and whether moves that don't change the board should spawn a new tile. Confirm input/output expectations.

2. Design board representation and core operations

Use a 2D array (list of lists) to represent the board. Define helper functions: slide and merge a single row left, check for game over, and spawn a random tile.

3. Implement directional moves with rotation

Write a generic move function that rotates the board so the desired direction becomes 'left', applies slide-and-merge to each row, then rotates back. This avoids duplicating logic for up/down/left/right.

4. Implement random tile spawning and game loop

After a successful move, spawn a new tile (90% chance of 2, 10% of 4) in a random empty cell. Check for win (2048 tile) and loss (no empty cells and no merges possible).

5. Discuss trade-offs and optimizations

Talk about time/space complexity, potential optimizations (e.g., bitboards for 4x4), and how you would test the implementation (unit tests for merge logic, edge cases).

Key Points to Mention

  • Board representation: 2D array or flat list, and why.
  • Merge logic: slide all tiles, then merge adjacent equal tiles from the direction of movement, ensuring each tile merges only once per move.
  • Rotation trick: implement one move direction and rotate board for others to reduce code duplication.
  • Random tile spawning: choose uniformly from empty cells, with 90% probability for 2 and 10% for 4.
  • Game over detection: no empty cells and no adjacent equal tiles.
  • Testing: unit tests for merge cases (e.g., [2,2,2,2] -> [4,4,0,0]), no-op moves, and full game simulation.

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

Q2

Design encode and decode functions that pack the entire 2048 board state into a single 64-bit integer and recover it losslessly.

Algorithms & Data StructuresSystem Design
Author's notes

This is the part that actually matters in this interview.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First, analyze the information-theoretic requirements: each cell can be empty or one of 11 tile values (2,4,...,2048), so 12 states per cell. Since 12^16 ≈ 2^57.4, a 64-bit integer is sufficient. Then design a mixed-radix encoding where each cell contributes a base-12 digit, and use bitwise operations to pack and unpack the board losslessly.

Pro tip: Mention that you can optimize further by noting that only one new tile appears per move, but for a general lossless encoder, the mixed-radix approach is simple and provably correct. Also, discuss how to handle invalid states (e.g., tiles beyond 2048) by either rejecting or using a sentinel value.

1. Determine the state space

Calculate the number of possible states per cell: empty plus 11 tile values (2^1 to 2^11) = 12 states. With 16 cells, total states = 12^16 ≈ 2^57.4, which fits in 64 bits.

2. Choose an encoding scheme

Use a mixed-radix (base-12) encoding: assign each cell a value from 0 to 11 (0 for empty, 1 for 2, 2 for 4, ..., 11 for 2048). The board is encoded as a sum of cell_value * 12^position, where position is 0 to 15.

3. Implement encode

Iterate over the 16 cells, map each tile to its 0-11 code, and accumulate the result using multiplication by 12 or bit shifts (since 12 is not a power of two, use multiplication). Ensure the final value fits in a 64-bit unsigned integer.

4. Implement decode

Extract each cell by repeatedly taking modulo 12 and integer division by 12 (or using precomputed powers). Map the 0-11 code back to the tile value (0 -> empty, 1 -> 2, etc.) and reconstruct the board.

5. Validate and discuss edge cases

Check that the encoded value is within range and that decoding recovers the original board. Discuss handling of invalid tiles (e.g., >2048) and whether to use a sentinel or throw an error.

Key Points to Mention

  • Information theory: 12^16 < 2^64, so 64 bits is sufficient.
  • Mixed-radix encoding: each cell is a base-12 digit.
  • Mapping: empty=0, 2=1, 4=2, ..., 2048=11.
  • Bitwise operations vs. multiplication: since 12 is not a power of two, use multiplication/division or precomputed powers.
  • Lossless recovery: decode is the inverse of encode.
  • Edge cases: invalid tile values, board size fixed at 4x4, and potential for future extensions (e.g., larger boards).

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