How to solve Jumping on the Clouds from Hacker Rank? JavaScript - javascript

I'm trying to solve the Jumping on the Clouds problem from Hackerrank, but even though it passes the Sample Test cases, it fails when submitting the code.
My code is as follow:
function jumpingOnClouds(c) {
var current;
var next;
var jumps = 0;
let potentialNext;
for(let i = 0; i < c.length; i++){
current=c[i];
next=c[i == c.length -1 ? 0 : i+1];
if(!next && next === 0){
jumps++;
potentialNext = c[ i == c.length -1 ? 0 : i+2];
if(potentialNext !== undefined && potentialNext === 1){
i = i + 1;
}
if(potentialNext !== undefined && potentialNext === 0){
i = i + 3;
}
}
if(next !== undefined && next === 1){
jumps++;
i = i + 2;
}
}
return jumps;
}
I can't figured what I am missing.

Your code didn't passed the "Sample Input 0". It returned 3, where 4 was expected.
I have modified your code, and it works for all input cases. I have left comments at places explaining the code.
function jumpingOnClouds(c) {
var current;
var next;
var jumps = 0;
let potentialNext;
let i = 0;
while(i < c.length){ //Use a while loop, since it gives more control on adding a dynamic value to a variable.
current = c[i];
if(i+2 < c.length && c[i+2] == 0){ //check if 2 clouds ahead from current index is jumpable or not
i+=2; //Set the current index to 2 places ahead
jumps += 1; //Make one jump
} else if(i+1 < c.length && c[i+1] == 0){ //Else Check if next cloud is jumpable or not
i+=1; //set current index to index of next cloud
jumps += 1; //Again, make one jump
} else i+= 1; //If none of above if conditions are satisfied, add 1 to index.
}
return jumps;
}
console.log(jumpingOnClouds([0, 0, 1, 0, 0, 1, 0])) //Sample Input 0
console.log(jumpingOnClouds([0, 0, 0, 0, 1, 0])) //Sample Input 1

I just finished this task and this is my code. I hope this can help you and I will explain the idea in comments. And I very appreciated if someone can tell me the more efficient code. Thank you.
function jumpOnTheClouds(c){
let path1 = []; //variable for 1 jump
let j = 0; //variable for index path1
let path2 = []; //variable for potential jump
let k = 0; //variable for index path2
let jump = 0; //variable for jump count
for(let i = 1;i < c.length;i++){ //I use for loop to count with +1 jump only, and start in index 1 because starting point always index 0
if(c[i] == 0){
path1[j] = i ; //If cloud not a thunderhead (0), path1 index j = index cloud
j++; //Set for next path1 index
}
}
for(let i = 1;i < c.length;i++){ //I use this for loop to count potential jump.
if(c[i + 1] == 0){ //Check if 2 clouds ahead not a thunderhead (0)
path2[k] = i + 1; //If 2 clouds ahead not a thunderhead (0), path2 index k = index cloud
i += 1 //Set index where we now
k++; //Set for next path2 index
}else if(c[i] == 0){
path2[k] = i; //If 2 clouds ahead is thunderhead (1), path2 index k = index cloud
k++; //Set for next path2 index
}
}
if(path1.length > path2.length){ //Screening for the less jump
jump = path2.length;
}else{
jump = path1.length;
}
return jump;
}

Related

Jarvis March implemention going into an infinite loop

I implemented Jarvis march in javascript and then submitted it, turns out in some cases it goes into an infinite loop. I tried changing almost everything and it seems like the code keeps on going into an infinite loop just for a few test cases.
This is my current code, the last for loop is to get all the points lying on the lines made by the convex hull points.
function convexHull(points, n)
{
// There must be at least 3 points
if (n < 3) return;
// Find the leftmost point
let l = 0;
let hull = [];
for (let i = 1; i < n; i++)
{
if (points[i].x < points[l].x)
l = i;
else if (points[i].x == points[l].x && points[i].y < points[l].y)
l = i;
}
// Start from leftmost point, keep moving
// counterclockwise until reach the start point
// again. This loop runs O(h) times where h is
// number of points in result or output.
let p = l, q;
do
{
// Add current point to result
hull.push(points[p]);
newhull.push(points[p]);
// Search for a point 'q' such that
// orientation(p, q, x) is counterclockwise
// for all points 'x'. The idea is to keep
// track of last visited most counterclock-
// wise point in q. If any point 'i' is more
// counterclock-wise than q, then update q.
q = (p + 1) % n;
for (let i = 0; i < n; i++)
{
// If i is more counterclockwise than
// current q, then update q
if ((orientation(points[p], points[i], points[q])
== 2))
q = i;
if(p != i && orientation(points[p], points[i], points[q]) == 0
&& onSegment(points[p], points[q], points[i])) {
q = i;
}
}
p = q;
}while (p != l); // While we don't come to first point
for(let i = 0; i < hull.length; i++) {
if(i + 1 < hull.length) {
for (let j = 0; j < points.length; j++) {
if(orientation(hull[i], points[j], hull[i+1]) == 0) {
newhull.push(points[j]);
points.splice(j, 1);
j--; }
}
}
else if(i + 1 == hull.length) {
for (let j = 0; j < points.length; j++) {
if(orientation(hull[i], points[j], hull[i+1]) == 0) {
newhull.push(points[j]);
points.splice(j, 1);
j--;
}
}
}
}
}
Any help pointing out how I could improve this or get out of an infinite loop would be much appreciated.

there are 'X' participants. The participants are to be divided into groups. Each group can have a minimum of 6 and a maximum of 10 participants

there are 'X' participants. The participants are to be divided into groups. Each group can have a minimum of 6 and a maximum of 10 participants. How would you approach this problem, and can you write code for this problem? Optimize for a minimum number of groups. Example: If there are 81 participants, then your program should split them into 9 groups, with each group having 9 participants.
If you have an array with 90 participants and want to create new arrays with a max you could do something like this:
let participants = []
for (let i = 0; i < 90; i++) {
participants.push("Participant" + i)
}
function splitArray(array, newArrayMaxLength) {
var chunks = [], i = 0, n = array.length;
while (i < n) {
chunks.push(array.slice(i, i += newArrayMaxLength));
}
return chunks;
}
console.log(splitArray(participants, 9));
When you call this function, you pass with it an argument stating the max length of the new arrays. If the numbers does not add up, there will only be a difference with one, so ideally you would not have to do anything else, if you span is between 6-10.
Please in the future include your code if you have done any :-)
This is a variation of the classical coin change problem with result as sequence instead of minimum coins required. The base solution is recursive and given below.
function minGroup(groupSize, totalParticipants) {
// Base case
if (totalParticipants == 0) return [];
// Initialize result
let groupArray = -1;
// Try every group that is smaller
// than totalParticipants
for (let i = 0; i < groupSize.length; i++) {
if (groupSize[i] <= totalParticipants) {
let sub_arr = minGroup(groupSize, totalParticipants - groupSize[i]);
// enters if new minGroup less than current or no current solution
if (sub_arr !== -1 && (sub_arr.length + 1 < groupArray.length || groupArray === -1)) {
groupArray = sub_arr.concat([groupSize[i]])
}
}
}
return groupArray
}
The solution can be improved on by Dynamic Programming with tabulation.
function minGroupDp(groupSize, totalParticipants) {
let dpTable = new Array(totalParticipants + 1);
// base case
dpTable[0] = [];
// Initialize all dpTable values as -1
for (let i = 1; i <= totalParticipants; i++) {
dpTable[i] = -1;
}
// Compute minimum groupSize required for all
// totalParticipantss from 1 to V
for (let i = 1; i <= totalParticipants; i++) {
// Go through all groupSize smaller than current total participants
for (let j = 0; j < groupSize.length; j++)
if (groupSize[j] <= i) {
let sub_arr = dpTable[i - groupSize[j]];
// enters if new minGroup less than current or no current solution
if (
sub_arr !== -1 &&
(sub_arr.length + 1 < dpTable[i].length || dpTable[i] === -1)
)
dpTable[i] = sub_arr.concat([groupSize[j]]);
}
}
return dpTable[totalParticipants];
}

- I am trying to write a code where input should be abbbcc and output should be a1b3c2

I am new to js.
I am trying to write a code where input should be abbbcc and output should be a1b3c2.
not sure how to get it
providing code below
var word = "abbbcc";
var countword = [];
for (i=0; i < word.length; i++) {
if (word[i] === charAt && word[i] != word[i+1]) {
countword.push(word[i]);
countword.push(i++);
}
else (word[i] === charAt && word[i] != word[i+1]) {
countword.push(word[i]);
for (i=0; i < word.length; i++) {
if (word[i+1] === word[i+2]) {
countword.push(i++);
}
else{
break;
}
}
}
}
console.log("result----->" + countword);
It can be done using a for loop and a counter like this.
var word = "abbbcc";
var countword = "";
var counter = 1;
for (i=0; i < word.length; i++) {
if ( word[i] != word[i+1]) {
// Save the letter and the counter
countword += word[i]+counter;
// Reset the counter
counter=1;
}else{
// Increment counter
counter++;
}
}
console.log("result-----> " + countword );
Alternative solution using Array#reduce. I've described each step, I hope you will get my point and understand how does it works.
var word = "abbbcc".split(''),
res = '',
counter = 1;
word.reduce(function(s, a, i, r) {
if (s !== a) { //if the succeeding element doesn't match the previous one
res += s + counter; //concat it to the string + the amount of appearances (counter)
counter = 1; //reset the counter
} else {
counter++; //the succeeding element matches the previous one, increment the counter
}
if (i === r.length - 1 && counter > 0) { //if the loop is over
res += s + counter; //add the last element
}
return a;
})
console.log(res);

How do you make every 9th element in Math.random array to be the same element?[javascript]

I have this bit of code here
<script language='javascript' type='text/javascript'>
var imagesArray = ["1.png","2.png","3.png","4.png","5.png","6.png","7.png","8.png","9.png","10.png","11.png","12.png","13.png","14.png","15.png","16.png","17.png","18.png","19.png","20.png","21.png" ];
var newArray = new Array(100);
for (i = 0; i < 100; i++)
{
if (i % 9 === 0)
{
}
else
{
newArray[i] = imagesArray[Math.floor(Math.random() * imagesArray.length)];
}
}
</script>
the idea behind is that i need it so that every 9th number that would be randomly chosen would remain the same, but i have no idea what do i put there so it would work.
Do you got any advice?
Thanks!
Here is a sample of what you can do :
First fill your array with Math.random() or whatever you want.
imagesArray[i] = Math.floor((Math.random() * 10) + 1);
If you want the value to be the same every 9 elements , use a loop starting at 9 and going through every 9 elements with i+9
for(var i = 9; i < yourArray.length ; i = i + 9){
imagesArray[i] = imagesArray[9];
}
Actually you can start the loop at 18 as well
Demo
Try defining a variable outside of for loop to store value at first i % 9 === 0
var newArray = new Array(100), ninth = null;
for (i = 0; i < 100; i++) {
newArray[i] = imagesArray[Math.floor(Math.random() * imagesArray.length)];
if (i % 9 === 0 && ninth === null && i === 9) {
ninth = newArray[i]
};
if (i % 9 === 0 && i >= 9) {
newArray[i] = ninth;
};
}

Battleship game: Allowing hits to be registered on ships with lengths other than 4

I'm making Battleship in JavaScript for a school project and I'm stuck.
The computer randomly generates boats and the user has to try to sink all the computer's boats by entering in coordinates. The hits on a boat are saved in an array. The array contains zeros to signify the boat's length (so boat with length 4 has an array with 4 zeros). When a boat is hit, the 0 changes to 1. If all the elements are 1, the boat sinks. Problem is my code registers the hits, but only puts it in an array when you hit the boat with length 4.
Can anyone help me? Below is the code of the "game" itself:
function game() {
inputArray = [4, 3, 2];
var boats = randomBoats(inputArray);
var currentBoat = 0;
var sunkenBoat = 0;
var numberOfTurns = 0;
while (sunkenBoat !== inputArray.length) {
var hit = false;
var target = "(" + prompt("Enter targetcoordinate (x,y)") + ")";
var targetString = target.replace(/\s+/g, '');
for (var i = 0; i !== inputArray.length; i++) {
for (var j = 0; j !== boats[i].usedPositions().length; j++) {
console.log(targetString)
if (targetString === boats[i].usedPositions()[j].toString()) {
raak = true;
boats[i].hits[j] = 1;
console.log(boats[i].hits);
currentBoat = boats[i];
} else {
currentBoat = boats[i];
}
}
}
console.log(currentBoat.hits);
console.log(allEquals(currentBoat.hits, 1));
if (hit)
alert("Hit!");
else
alert("Miss!");
if (allEquals(currentBoat.hits, 1)) {
alert("Boat with length " + currentBoat.hits.length + " has sunken!");
sunkenBoat++;
}
numberOfTurns++
}
alert("You've won! You did it in " + numberOfTurns + " turns.")
}
The issue is with the else in the inner loop, as you processed each ship (outer loop) and all positions (inner loop) your
else {
currentBoat = boats[i];
}
would always set the current boat to be the last [i];
You also don't need to process any other positions or boats when you've found a hit, so break early when you detect the hit like this:
raak = false;
for(var i = 0; i < inputArray.length && !raak; i++) {
for(var j = 0; j !== boats[i].usedPositions().length; j++) {
console.log(targetString)
if(targetString === boats[i].usedPositions()[j].toString()) {
raak = true;
boats[i].hits[j] = 1;
console.log(boats[i].hits);
currentBoat = boats[i];
break;
}
}
}

Categories

Resources