Let's solve the Where Will the Ball Fall problem using the Matrices pattern.
We'll cover the following
Statement
You have balls and a 2D grid of size representing a box. The box is open on the top and bottom sides. Each cell in the box has a diagonal that can redirect a ball to the right or the left. You must drop balls at each column’s top. The goal is to determine whether each ball will fall out of the bottom or become stuck in the box. Each cell in the grid has a value of or .
- represents that the grid will redirect the ball to the right.
- represents that the grid will redirect the ball to the left.
A ball gets stuck if it hits a V-shaped pattern between two grids or if a grid redirects the ball into either wall of the box.
The solution should return an array of size , with the element indicating the column that the ball falls out of, or it becomes if it’s stuck. If the ball drops from column and falls out from column , then in the result array, index contains value .
Constraints:
-
grid.length
-
grid[i].length
grid[i][j]
is or .
Solution
The following steps utilize the intuitive version of the algorithm, where we drop each ball from the top of the grid one by one and follow the path it can take. The ball starts moving from a certain column and jumps from one row to the next based on the value of the current cell. Let’s consider the following two examples to better understand the ball movement within the grid:
-
If the ball starts from column , row , and the value in the cell
grid[0][0]
is (topleft-bottomright diagonal), the ball will move to the next row, which is 1, and to the next column, which is also . So, the next position of the ball will be the cellgrid[1][1]
. -
If the ball starts from column , row , and the cell
grid[0][2]
contains (topright-bottomleft diagonal), the ball will go to the next row, which is , and to the previous column, which is . So, the next position of the ball will be the cellgrid[1][1]
.
We repeat the process above as the ball moves to the next rows. The termination conditions for the algorithm are as follows:
-
The ball keeps moving to the next rows until it hits the last row in the grid. This is a success case, and the column where the ball meets the final row is recorded in the output array.
-
The ball gets stuck in a row because one of the following conditions is met:
-
The ball falls to the leftmost column, and the value in the cell is . This will stop the ball from moving to the next row because the ball will hit the wall because of the topright-bottomleft diagonal.
-
The ball falls to the rightmost column, and the value in the cell is . This will stop the ball from moving to the next row because the ball will hit the wall because of the topleft-bottomright diagonal.
-
The ball is between the left-most and right-most columns, the diagonal in the current cell is topleft-bottomright, and the immediate next column stops the ball from moving to the next row because it has a topright-bottomleft diagonal, forming a shape.
-
The ball is between the leftmost and rightmost columns, the diagonal in the current cell is topright-bottomleft, and the immediate previous column stops the ball from moving to the next row because it has a topleft-bottomright diagonal, forming a V shape.
-
We can solve the problem using the iterative approach by following the steps below:
-
Declare an array,
result
, of sizegrid.length
, and initialize its elements with , assuming that each ball will be stuck in the grid. We will change the values for the columns where the balls will succeed in reaching the last row. -
Iterate the grid using nested for loops. For each column, perform the following checks:
-
For each row,
row
, do the following:-
Compute
nextColumn
by addingcurrentColumn
togrid[row][currentColumn]
. -
Check if
grid[row][nextColumn]
has the same value asgrid[row][currentColumn]
. If so, the ball can move to the next row. -
Check if the ball is not stuck at the boundary of the grid by checking if the
nextColumn
is less than zero or greater than the columns of the grid. -
Set the
currentColumn
as thenextColumn
. -
If this is the last row, set
result[col]
tonextColumn
.
-
-
Let’s look at the slide below to see how the algorithm works.