Closest Enemy II Algorithm Puzzle with JavaScript

What is the Goal?

André Santiago
5 min readNov 25, 2018

You must create a function that can read matrix of numbers stored in an array which will be a 2D matrix that contains only the integers 1, 0, or 2. Then from the position in the matrix where a 1 is, return the number of spaces either left, right, down, or up you must move to reach an enemy which is represented by a 2.

What are the Rules?

You are able to wrap around one side of the matrix to the other. For example if array is [“0000”, “1000”, “0002”, “0002”] then this is the board:

0 0 0 0

1 0 0 0

0 0 0 2

0 0 0 2

For this board your program should return 2 because the closest enemy (2) is 2 spaces away from the 1 by moving left to wrap to the other side and then moving down once. The array will contain any number of 0’s and 2’s, but only a single 1. It may not contain any 2’s at all as well, where in that case your program should return a 0.

Test Cases

Input: [“000”, “100”, “200”] | Output: 1

Input: [“0000”, “2010”, “0000”, “2002” ] | Output: 2

Break it Down

Let’s first declare a function named closestEnemy. Afterward, we will require two arrays to determine two things: the location of the player (1) and the enemy (2). After, we need a counter for the distance traversed. In this case we will use a variable named distance set to 0. We will also store a set length of the array that’s passed in as an argument (board), and the length of 1 element within the array (ie: [“0000”, “2010”][0].length = 4). The use of this will make more sense later.

Find the Player && the Enemies

Next we need to find the location of the Player (1) and all of the Enemies (2) on the board provided. In this case, we need to iterate over the board. Remember, the board consists of a 2D matrix that contains only the integers 1, 0, or 2. In this case, we’ll be working with the following test case:

[“0000”, “2010”, “0000”, “2002” ] | Output: 2

We iterate over the board. At the start of the iteration we split each row. For example: “0000” then becomes an array: [“0”, “0”, “0”, “0”]. We also set the row’s length to rowLength for optimization purposes.

Next we iterate over this row. In the case of this first row, there is no Player or Enemy. So we move to the next row: [“2”, “0”, “1”, “0”].

This time we have an Enemy and a Player. Awesome!

Luckily, we have our conditionals in place to handle storing the index of the Player and the Enemy. Not only that, but we need to know the index of the row in which they exist in order to count the distance. So we push both into their independent arrays player and enemy.

However, remember, there can be multiple enemies on the board. So we need to continue reading the board. The next row is [“0”, “0”, “0”, “0”] which contain none, but the last row is [“2”, “0”, “0”, “2”] which contains two more enemies. So push these into the enemy array!

Remember each pair of indices are the locations within the row.

Index 0 1 2 3

[0] — 0 0 0 0

[1] — 2 0 1 0

[2] — 0 0 0 0

[3] — 2 0 0 2

For example, look at the grid above. The Player (1) is located at index 2 of row 1. The Enemies are located at 0 and 1, 0 and 3, 3 and 3.

Calculate the Distance

Great so now we have the location of our Player and the Enemies that exist on the board. We now need to calculate the path to the nearest enemy. Remember, the rules are that the player can traverse the board: left, right, up, and down. This means that there are any number of ways to reach an enemy.

Remember, we have multiple enemies on the board. So we need to check the distance between all of the enemies against the Player’s known location. Above we iterate over the enemy array and do that.

As we start the first iteration we compare the player’s known index within a row. This is then compared to the enemy’s own index within a row. This is not taking into account the distance that can be traveled up or down yet. This is simply trying to determine the closest index. For example, the Player at index 2 is close two positions away from the enemy at index 0, but is one position away from the enemy at index 3.

We’ve already determined the distance side-to-side above. So now we need to determine the distance when it comes to traveling up and down (if needed):

In this case we add it to the overall count of newDistance which we’ve declared during the first iteration. However, we have a conditional that follows that only sets the distance, which we return at the end, to the overall count that has the least amount of moves.

Finished Product

Github Gists

Please feel free to check out the commented and uncommented code:

Commented Code

Uncommented Code

--

--

André Santiago

Puerto Rican — New York City Based Software Engineer, Photographer & Powerlifter // Former Sr. Network Engineer & Incident Manager // #LatinxInTech