Tetris-ing an array
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
“Tetris-ing an array” usually refers to compacting, packing, or rearranging elements so gaps are removed and values are moved according to constraints, similar to pieces dropping in Tetris. This pattern appears in memory compaction, inventory slot systems, game grids, and data cleanup tasks. The first step is to define exact movement rules: stable compaction (preserve order), gravity by column, or best-fit packing. Without a clear rule set, implementations become brittle and impossible to test. This article covers practical array “tetris” strategies and their trade-offs.
Core Sections
1. Stable one-dimensional compaction
If the goal is to move non-empty values left and keep relative order, use two-pointer compaction.
This is O(n) and in-place.
2. Column gravity in 2D grids
For board-style behavior, compact each column downward.
This mimics pieces falling straight down while preserving vertical order within a column.
3. Packing with constraints
Some problems require fitting variable-width items into bins/rows. In that case, use greedy packing (first-fit, best-fit) and accept that globally optimal packing may be NP-hard.
This is often sufficient for UI layout or basic scheduling.
4. Complexity and correctness concerns
Compaction and gravity are usually O(n) or O(rows*cols). Bugs often come from overwriting unread values, forgetting to clear residual slots, or violating stability assumptions.
Use property-based tests where possible:
- number of non-empty items unchanged
- no non-empty appears after an empty in compacted 1D array
- column multiset preserved after gravity
5. Visualization for debugging
For grid operations, print intermediate states step-by-step. Visual diffs catch index mistakes quickly, especially off-by-one errors near boundaries.
6. Production considerations
If “tetris” logic runs at high frequency (games, real-time dashboards), avoid repeated allocations and branch-heavy code in hot loops. Pre-allocate buffers, prefer in-place transforms, and benchmark with realistic board sizes.
Validation and production readiness
A reliable solution should include explicit validation and observability, not just a working snippet. Add representative test inputs for normal flow, malformed input, and boundary values so behavior is stable under change. Where timing or throughput matters, keep a small benchmark scenario and run it after refactors to catch accidental slowdowns early. If external systems are involved, include retry, timeout, and failure-path tests to verify the system degrades gracefully rather than hanging or failing silently.
Operationally, document assumptions close to the implementation: dependency versions, environment requirements, timezone or locale expectations, and any platform-specific behavior. Add structured logs for key decision points and failures so production incidents are diagnosable without reproducing every condition locally. For teams, define a minimal rollout checklist that covers backward compatibility, monitoring alerts, and rollback steps. These checks reduce incidents caused by integration gaps, which are more common than syntax errors in real deployments.
Common Pitfalls
- Implementing movement rules without defining stability and direction explicitly.
- Overwriting values during in-place moves due to incorrect read/write ordering.
- Forgetting to reset vacated positions after compaction.
- Assuming greedy packing always gives optimal arrangement.
- Testing only one board shape and missing edge conditions.
Summary
Array “tetris” tasks become manageable when you define the movement contract first: stable compaction, column gravity, or constrained packing. Two-pointer and column-wise strategies are efficient and reliable for most use cases. Add invariant-based tests and simple visualization to catch indexing bugs early. With clear rules and performance-aware implementation, these transformations stay correct and scalable.
Related reading
- Tetris Piece Rotation Algorithm
- Text clustering within a log file
- Text, string-based chord recognition algorithms?
- tf.distribute.MirroredStrategy implementation with sessions not with Keras?
- tf.SequenceExample with multidimensional arrays
- The best shortest path algorithm
- tf.data vs keras.utils.sequence performance
- TF.Keras model.predict is slower than straight Numpy?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.