Array Code Challenge Breakdown
By: Dan Romans
Tags: Hackerrank, Algorithms, Code Challenge, JavaScript, Arrays

The problem statement describes a queue of people waiting for a ride. The queue is represented as an Array . The people in the queue are represented as elements . Each person in the queue is sequentially assigned an integer, starting from 1 at the beginning of the queue. A queue of eight people could be represented like this:

queue = [1, 2, 3, 4, 5, 6, 7, 8]

A person in the queue can bribe the person directly in front of them to switch positions. However, upon switching, both persons retain their sequential identifier, i.e. the integer assigned to that particular index. One person can only bribe the person in front of them two times. If person 5 were to bribe person 4 to switch positions, the queue would then look like this:

queue = [1, 2, 3, 5, 4, 6, 7, 8]

The challenge is to write a program that accepts an Array of integers any length greater than 1 and determines the minimum number of valid bribes which were necessary to produce the numerical order of the Array . The program should print an integer denoting the minimum number of bribes needed to produce the numerical order of the input Array or print Too chaotic if the order is invalid, i.e. it requires a person to have bribed more than 2 people. This solution will be a JavaScript function:

1 function minimumBribes(q) {

2 let swaps = 0

3

4 for (let i = 0; i < q.length; i++) {

5 let bribes = q[i] - (i + 1)

6 let maxAdvance = q[i] - 2 > 0 ? q[i] - 2 : 0

7

8 if (bribes > 2) {

9 console.log('Too chaotic')

10 return

11 }

12

13 for (let j = maxAdvance; j < i; j++) {

14 if (q[j] > q[i]) swaps++

15 }

16 }

17 console.log(swaps)

18 }

19

20 ///////////////////////////////////////////

21

22 const q = [1, 2, 5, 3, 7, 8, 6, 4]

23 minimumBribes(q)

24 // => 7

25

26 ///////////////////////////////////////////

27

28 const q = [5, 1, 2, 3, 7, 8, 6, 4]

29 minimumBribes(q)

30 // => Too chaotic

So, great, this function works, but let’s break it down and understand how. Read on.

The function is declared with the name minimumBribes and given an argument of an Array , in this case represented by the variable q . In the outermost scope, there is a variable named swaps on line 2 , assigned the value of 0 . swaps will act as the counter variable, incrementing by 1 each time a valid bribe and position swap is enacted. On line 17 the console.log() will print out the integer represented by swaps , unless the input array is invalid.

Within the same scope, there is a for loop on line 4 . The conditions of the for loop state that the counter variable i will begin at index 0 (the first element of the Array ) and increment ( i++ ) by 1 as long as i is less than the length of the Array .

Within the scope of the for loop , there are two variables declared, an if statement, and a nested for loop . The first variable, on line 5 , is named bribes , and represents the number of bribes the current person (current element) enacted. This is calculated by subtracting the current position in the queue (or the index of the Array plus 1 . * Array indices begin at 0 ) from the value of the current element being evaluated, or the identifying number of the person in that position.

For example: in the second input example on line 28 , the first element ( q[0] ) value is 5 . Person number 5 minus i + 1 ( 0 + 1 , or 1 , since this is the first iteration of the loop) is equal to 4 . The number 5 had to shift 4 positions towards the front of the line to be in its location, so person 5 made 4 bribes. Now let’s skip ahead to line 8 for a moment.

Upon each iteration of the for loop , the number of bribes is calculated. Then, on line 8 , the if statement evaluates whether the amount of bribes that person made is greater than 2 , invalidating the array. If so, the message Too chaotic is printed to the terminal, and the return statement breaks out of the loop and ends execution of the function.

If the amount of bribes is valid, then the function continues to execute. Let’s jump back to line 6 where there is a variable named maxAdvance , which represents the furthest valid position, 2 spaces ahead, that a person could have advanced through bribery. The value of maxAdvance is determined by the evaluation of a conditional operator. If the original position of the current element (person) minus 2 (spaces) is greater than 0 , then the value of maxAdvance is the current element ( q[i] ) minus 2 . Otherwise, the value of maxAdvance is 0 . The conditional operator essentially makes sure the placeholder cannot become negative, i.e. cannot move beyond the first position in the queue. There has to be a front of the line somewhere.

On line 13 , a nested for loop evaluates any bribes value that is valid, less than 3 . The conditions of the nested for loop state that the counter variable j will begin at the index determined by maxAdvance and increment ( i++ ) by 1 as long as j is less than the current index ( i ) of the outer for loop . In the body of the nested for loop , an if statement evaluates whether the person number (value of Array element) is greater than the number of the next person in the queue. If so, it means that the greater integer must have bribed its way ahead, and the counter established on line 2 , named swaps , is incremented by 1 . This evaluation will occur once or twice, according to the loop conditions, and appropriately increase and record the number of swaps.