Algorithms

HackerRank Jumping on the Clouds Challenge

Given the sequence of up and down steps, find the number of valleys walked through

Adam

Adam


The details for the problem detailed in this post can be found at https://www.hackerrank.com/challenges/jumping-on-the-clouds/problem

The following solution is written in Javascript.

Problem

There is a new mobile game that starts with consecutively numbered clouds. Some of the clouds are thunderheads and others are cumulus. The player can jump on any cumulus cloud having a number that is equal to the number of the current cloud plus 1 or 2. The player must avoid the thunderheads. Determine the minimum number of jumps it will take to jump from the starting position to the last cloud. It is always possible to win the game.

Breaking down the challenge into blocks of requirements, we get:

  • int 0 = Safe Cloud
  • int 1 = Unsafe Cloud
  • int c[n] = Clouds - an array of binary integers
  • Jump = To any cumulus that is c[i+1] or c[i+2]

Example


    c = [0, 1, 0, 0, 0, 1, 0]
  

Index the array from 0...6. The number on each cloud is its index in the list so the player must avoid the clouds at indices 1 and 5. They could follow these two paths: 0 > 2 > 4 > 6 or 0 > 2 > 3 > 4 > 6 . The first path takes 3 jumps while the second takes 4. Return 3.

Function Description

jumpingOnClouds has the following parameter(s):

  • int c[n]: an array of binary integers

Returns

  • int: the minimum number of jumps required

Input Format

The first line contains an integer n, the total number of clouds. The second line contains n space-separated binary integers describing clouds c[i].

Sample Input 0


    7
    0 0 1 0 0 1 0
  

Sample Output 0


    4
  

Explanation

The player must avoid c[2] and c[5]. The game can be won with a minimum of 4 jumps:

Hacker Rank jumping on cloud

Sample Input 1


    6
    0 0 0 0 1 0
  

Sample Output 0


    3
  

Explanation

The player must avoid c[4]. The game can be won with a minimum of 3 jumps:

Hacker Rank jumping on cloud

Goal

For each game, you will get an array of clouds numbered 1 if they are safe or 2 if they must be avoided. Write a function that returns the minimum number of jumps required.

Constraints & Validation

  • The number of socks clouds will be more than 2 but less than 100
  • Each cloud will be 1 or 0

    2 <= n <= 100
    c[i] will consist of {0,1}
  

First Attempt Solution

The first solution I came up with created an array with the path indexes and returned the path length.


    function jumpingOnClouds(c) {

        let path = [];

        for(let i = 0; i < c.length; i++){
            if(c[i+2] == 0) {
                if(i != 0) path.push(i);
                i ++;
            } else if (c[i+1] == 0) {
                if(i != 0) path.push(i);
            }
            if(i == c.length - 1) path.push(i)
        }
        return path.length;
    }

Refactored Solution 1

While looking to refactor the code I realised that each index of c could be used as a boolean (true or false).

Using this we can replace the if statement with a ternary statement and just compute the number of jumps.


    function jumpingOnClouds(c) {

            let jumps = 0;

            for(let i = 0; i < c.length - 1;){
                i += (c[i+2] ? 1 : 2);
                jumps++;
            }
            return jumps;
        }

Refactored Solution 2

The refactored solution above made me think that you could achieve the same simplicity with a while loop.


    function jumpingOnClouds(c) {

        let jumps = 0,
            currentCloud = 0;

        while (currentCloud < c.length-1) {
            currentCloud += (c[currentCloud+2] ? 1 : 2);
            jumps++;
        }
        return jumps;
    }

Conclusion

I'm not sure which of the two refactored solutions above is more optimal, with a simple enough function like the one above I doubt there is any difference in speed, however the second solution using the while loop is definitely easier to read.