The Snail in the Well - Solo learn project - javascript

In a way of trying to solve the 23 code project of SOLOLEARN JavaScript course known widely with (The Snail in the Well) .. I produced this code which is worked with case of input = 128
and failed with input = 42. What I should modify in the code to implement the code successfully for all cases.
function main() {
var depth = parseInt(readLine(), 10);
//your code goes here
let count=0
for( let i=0;i<depth;){
i+=5
count++
}
console.log(count)
}
The Original Challenge:
P.S.
//You can replace this [parseInt(readLine(), 10);] with 42 and 128
and remove the main function to enable work at any code editor.

The below code will help you out with the problem.
function main() {
var depth = parseInt(readLine(), 10);
//your code goes here
var days = 0;
for(var distance = 0; distance <= depth;){
days = days + 1;
distance = distance + 7;
if(distance >= depth){
break;
}
else{
distance = distance - 2;
}
}
console.log(days);
}

Related

snail in the well javascript challenge

This is my first question on stack overflow although this question had been answered before I didn't get enough details to understand why the code was written that way and I didn't just want to copy and paste the solution without understanding it.
The snail climbs 7 feet each day and slips back 2 feet each night, How many days will it take the snail to get out of a well with the given depth?
Sample Input
31
Sample Output
6
this is was what i wrote but it didn't work
function main() {
var depth = parseInt(readLine(), 10);
//your code goes here
let climb = 0, days = 0;
for(climb + 7; climb < depth; days++){
climb += 2;
console.log(days);
try this:
var depth = parseInt(readline(), 10);
var day = 0;
for(let climb = 0; climb <= depth;) {
day +=1;
climb += 7;
if(climb >= depth) {
break;
}
climb -= 2;
}
console.log(day);
Just take input and write this
var day= Math.ceil((depth-2)/5);
and output that!
/* day --> 7++
night --> 2-- */
var day = 0;
var total = 0;
var input = 41;
while (input>total){
day++;
total+=7;
if (total>=input){
console.log(day);
break;
}
total = total -2
}
As mentioned in the comments, no need to loop. Just work out the math of the problem an use that.
function snailCalc (depth, dailyGain, nightlyLoss) {
var days = 1;
var netGain = dailyGain-nightlyLoss;
if(depth > dailyGain ) {
//Basic calc based on net gain taking the first day into account
days = (depth-dailyGain)/netGain;
//Add the fist day
days += 1;
//We want whole days so use Mathc.ceil
days = Math.ceil(days)
//Or we could do all that in one line
//days = Math.ceil(((depth-dailyGain)/netGain) + 1);
}
return days;
}
const gain = 7;
const loss = 2
for(var d = 1; d < 31; d++)
{
console.log(`Depth: ${d}, Days: ${snailCalc(d, gain, loss)}` )
}
Bob
function main() {
var depth = parseInt(readLine(), 10);
console.log(Math.round(depth / 5))
}
function main() {
var depth = parseInt(readLine(), 10);
//your code goes here
var days=1;
var level =0;
for(level =0;level<depth;days++){
level+=7
if(level<depth){
level-=2;
} else{
break ;
}
}console.log(days)
}
Try this, I had the same trouble a couple days ago and we find the error is that using js you need to reset the variable where you sum the result before evaluate again if the distance the snail climbed that day is greater than the depth to end the clycle.
depth = 31;
let days = 0;
let climb = 0;
while(climb < depth){
let result = climb + 7;
if(result >= depth){
days++;
break;
}
climb = result - 2;
days++;
//console.log("climb ",climb);
}
console.log(days);
You can change the function input and test the snipet:
for more you can run code and check result ↗
Eg : main(128) // 26
function main(input) {
let depth = input
let climbsUp = 7
let slipsBack = 2
let distance = climbsUp - slipsBack
let days = 0;
let rDepth = Math.round(depth / distance)
for (let i = 0; i < rDepth; i++) {
distance = distance + 5
days = ++days
if (days === 6) {
console.log('days will it take the snail to get out of a well : ' + rDepth)
} else {
console.log('days will it take the snail to get out of a well : ' + rDepth)
break;
}
}
}
main(42);
main(128);

How do I write a function to add 7 and substract 2 if it is not already 0

This is what I need to do:
The snail climbs up 7 feet each day and slips back 2 feet each night.
How many days will it take the snail to get out of a well with the given depth?
Sample Input:
31
Sample Output:
6
Explanation: Let's break down the distance the snail covers each day:
Day 1: 7-2=5
Day 2: 5+7-2=10
Day 3: 10+7-2=15
Day 4: 15+7-2=20
Day 5: 20+7-2=25
Day 6: 25+7=32
So, on Day 6 the snail will reach 32 feet and get out of the well at day, without slipping back that night.
This is the code I have written so far:
function main() {
var depth = parseInt(readLine(), 10);
//your code goes here
}
Please help me, I'm like really stuck.
This is a pretty simple question,
function main() {
var depth = parseInt(readLine(), 10);
//your code goes here
i = 0;
for (; depth > 0;) {
i++;
depth -= 7
if (depth > 0) {
depth += 2
}
}
console.log(i);
}
What this code basically does is:
It sets a i variable which is 0, than when the depth is bigger than 0, 1 is post incremented by 1 -which means 1 is added to it- this will count the days it will take. But we must consider the nights as well, as it says, it will not fall down the night if it climbs it all in the day. Thus, we put another + 2 if the -7 doesn't make it 0.
You can read about for loops here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for
I have noticed you're new to stack overflow, so please for the next time you ask, do some coding and research on your own. You mentioned you coded some bits but you just stated a function which is just same as writing nothing and asking for an answer -stack overflow is not your homework solving site!-
In a day and a night, a snail gains a total of 5 feet. The catch here is that this gain is made up of gaining 7 feet, and then slipping back 2. Another way to think about it is that the goal is 2 less than the actual goal, but advances 7-2=5 feet per day.
To formulate this to Javascript, you need to subtract 2 from the distance, divide it by 5, and ceil the result to get the number of days as an integer:
function numDays(distance) {
return Math.ceil((distance - 2) / 5);
}
function main(distance) {
var depth = parseInt(distance);
//your code goes here
var day = 0;
var total = 0;
while(total<depth){
day = day + 1;
total = total + 7;
if(total >= depth){
console.log(day);
break;
}
total = total - 2;
}
}
main(32)
main(51)
This question pretty simple but tricky ;
The depth is already defined which is " var depth = parseInt(readLine(), 10);"
So you don't have to worry declaring depth again depth.
So we need to declare variable for day and total distance at start which is
var day = 0 ; and var total = 0 ; .So here the solution :
function main() {
var depth = parseInt(readLine(), 10); //defining depth
//your code goes here
var day = 0; //defining day
var total = 0; // distance which is at zero
while(total<depth){
day += 1;
total += 7; // if the total distance is less than depth of the well the day is added by one and distance is added by 7
if(total >= depth){
break; // but if the total is equal to or greater than depth the loop will break
}
total -= 2; // 2 is deducted from every step in loop except when the loop is about to ends(where the loop breaks when total=depth).
}
}
function main() {
var depth = parseInt(readLine(), 10);
//your code goes here
var result = depth / 5;
console.log(Math.round(result));
}

How could I correctly total the points?

I am javascript learner struggling to design a small javascript game for my kids (5 to 10 years old) in which points are based on time elapsed. But, I cannot figure out a way to total the points. I have managed the code below but the result is not accurate. Probably the program is totalling all the items in array with each click. Can anybody help please? I am a newbie and there will be many mistakes or absurdities in here, I request you to be helpful politely while correcting me. Any help is appreciated..
document.getElementById("box1").onclick = function() {
clickT = Date.now();
reactT = (clickT - createdT) / 1000; //gets the time difference for reaction.
points = reactT * 1000;
points = 2000 - points;
pRecord.push(points); //add points to array.
for (i = 0; i < pRecord.length; i++) {
totalpoints += pRecord[i];
}
document.getElementById("time").innerHTML = reactT;
this.style.display = "none";
document.getElementById("score").innerHTML = totalpoints;
}
Just set totalpoints to zero before you sum the points:
document.getElementById("box1").onclick = function() {
var clickT = Date.now();
var reactT = (clickT - createdT) / 1000; //gets the time difference for reaction.
var points = reactT * 1000;
points = 2000 - points;
pRecord.push(points); //add points to array.
var totalpoints = 0;
for (var i = 0; i < pRecord.length; i++){
totalpoints += pRecord[i];
}
document.getElementById("time").innerHTML = reactT;
this.style.display = "none";
document.getElementById("score").innerHTML = totalpoints;
}
And also I don't know if you defined your variables in the outer scope, but I guess you did not, so I added var before every variable creation.
Here is an improved version of your code that also properly registers the reaction times, capping the maximum allowed reaction time to a configured value.
In your original implementation you could get bad readings if the reaction time was greater than 2 seconds.
Also, in your original code, you don`t need to divide by 1000 and then multiply back, since you end up with milliseconds anyway.
This is it:
document.getElementById("box1").addEventListener("click", function() {
clickT = Date.now();
// Gets the time difference in milliseconds for reaction.
reactT = clickT - createdT;
// Maximum allowed reaction time after which we give no more points.
var maxPoints = 2000;
// We cap the registered reaction time to the maximum allowed.
points = Math.max(reactT, maxPoints);
// We score the reaction time based
points = maxPoints - points;
// Add points to array.
pRecord.push(points);
// Compute the total points.
var totalpoints = 0;
for (i = 0; i < pRecord.length; i++){
totalpoints += pRecord[i];
}
document.getElementById("time").innerHTML = reactT;
this.style.display = "none";
document.getElementById("score").innerHTML = totalpoints;
}
You can notice that I have defined the totalpoints variable (and initialized it with 0), as otherwise, at each click, all your scores were re-added, not just the last one.
I have made the assumption that totalpoints was not already defined before the code you have pasted. Should this assumption be wrong and you have already initialized totalpoints before, in your code, then you need to replace the following piece from my code:
// Compute the total points.
var totalpoints = 0;
for (i = 0; i < pRecord.length; i++){
totalpoints += pRecord[i];
}
...with:
// Add the new points to the total.
totalpoints += points;

Seeking a statistical javascript function to return p-value from a z-score

I need to convert z-scores to percentile. I found reference to a function in the jStat library that I could use (jstat.ztest), but the jStat documentation seems to be ahead of the available library because there is no such function in the currently available version of the library.
I think there is a more recent version of the library on GitHub, which may include the ztest function, but I am a linux novice and could not figure out how to build the library from the instructions. I spent most of a day learning about git bash and cygwin trying to build the library; I finally decided I'd be better off asking here.
So, could anyone point me toward a javascript function that would do what I need?
Alternatively, could anyone point me toward a built version of the jStat library with ztest function included?
I found this in a forum online and it works like a charm.
function GetZPercent(z)
{
//z == number of standard deviations from the mean
//if z is greater than 6.5 standard deviations from the mean
//the number of significant digits will be outside of a reasonable
//range
if ( z < -6.5)
return 0.0;
if( z > 6.5)
return 1.0;
var factK = 1;
var sum = 0;
var term = 1;
var k = 0;
var loopStop = Math.exp(-23);
while(Math.abs(term) > loopStop)
{
term = .3989422804 * Math.pow(-1,k) * Math.pow(z,k) / (2 * k + 1) / Math.pow(2,k) * Math.pow(z,k+1) / factK;
sum += term;
k++;
factK *= k;
}
sum += 0.5;
return sum;
}
And I don't need to include a large library just for the one function.
Just editing the code from Paul's answer for a two-sided t-test
function GetZPercent(z)
{
//z == number of standard deviations from the mean
//if z is greater than 6.5 standard deviations from the mean
//the number of significant digits will be outside of a reasonable
//range
if ( z < -6.5)
return 0.0;
if( z > 6.5)
return 1.0;
if (z > 0) { z = -z;}
var factK = 1;
var sum = 0;
var term = 1;
var k = 0;
var loopStop = Math.exp(-23);
while(Math.abs(term) > loopStop)
{
term = .3989422804 * Math.pow(-1,k) * Math.pow(z,k) / (2 * k + 1) / Math.pow(2,k) * Math.pow(z,k+1) / factK;
sum += term;
k++;
factK *= k;
}
sum += 0.5;
return (2*sum);
}
This seems like such a simple ask but I had a hard time tracking down a library that does this instead of copying some random code snippet. Best I can tell this will calculate z-score from a percentage using the simple-statistics library.
I took their documentation about cumulativestdnormalprobability and backed into the following algorithm. Feels like there should be an easier way but who knows.
https://simplestatistics.org/docs/#cumulativestdnormalprobability
const z_score = inverseErrorFunction((percentile_value - 0.5) / 0.5) * Math.sqrt(2);
As already correctly stated by Shane, the equation is an implementation of the Taylor Expansion of the normal cdf. The sum value iterates above and below the "real" value with increasing precision. If the value is close to 1 or 0 there is a very low, but existing, probability that sum will be >1 or <0, because of the (relatively) early break by loopstop.
The deviation is further strengthened by rounding 1/Math.sqrt(2*Math.Pi) to 0.3989422804 and the precision issues of javascript float numbers. Additionally, the provided solution will not work for z-scores >7 or <-7
I updated the code to be more accurate using the decimal.js npm library and to directly return the p-value:
function GetpValueFromZ(_z, type = "twosided")
{
if(_z < -14)
{
_z = -14
}
else if(_z > 14)
{
_z = 14
}
Decimal.set({precision: 100});
let z = new Decimal(_z);
var sum = new Decimal(0);
var term = new Decimal(1);
var k = new Decimal(0);
var loopstop = new Decimal("10E-50");
var minusone = new Decimal(-1);
var two = new Decimal(2);
let pi = new Decimal("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647")
while(term.abs().greaterThan(loopstop))
{
term = new Decimal(1)
for (let i = 1; i <= k; i++) {
term = term.times(z).times(z.dividedBy(two.times(i)))
}
term = term.times(minusone.toPower(k)).dividedBy(k.times(2).plus(1))
sum = sum.plus(term);
k = k.plus(1);
}
sum = sum.times(z).dividedBy(two.times(pi).sqrt()).plus(0.5);
if(sum.lessThan(0))
sum = sum.abs();
else if(sum.greaterThan(1))
sum = two.minus(sum);
switch (type) {
case "left":
return parseFloat(sum.toExponential(40));
case "right":
return parseFloat((new Decimal(1).minus(sum)).toExponential(40));
case "twosided":
return sum.lessThan(0.5)? parseFloat(sum.times(two).toExponential(40)) : parseFloat((new Decimal(1).minus(sum).times(two)).toExponential(40))
}
}
By increasing the Decimal.js precision value and decreasing the loopstop value you can get accurate p-values for very small (or very high) z-scores for the cost of calculation time.

Javascript - Distance (in pixels) - Decision

I have a simple javascript animation, where two cowboys (iamges) 'race' each other based on a random interval number.
What I can't find out how to do is for the script to take a decision on who is the winner, meaning if a cowboy reaches a pre-defined distance first, the script will know and will show an alert on who won.
Here is a screen shot to show an example:
This is the code I have so far: http://pastebin.com/Cmt4N8c9
Can give me some directions?
Thanks,
Brian
In your move() function you should do something like
if (x >= dest_x) {
alert('player 1 won');
} else if (x2 >= dest_x2) {
alert('player 2 won');
} else {
... continue the loop ...
}
You'd most likely put that behind
document.getElementById("cowboy").style.top = y+'px';
document.getElementById("cowboy").style.left = x+'px';
document.getElementById("cowboytwo").style.top = y2+'px';
document.getElementById("cowboytwo").style.left = x2+'px';
You might want to check your code on duplicate variables too, by the way.
AFAIK dest_x and dest_x2 are both the same for example.
Simple move
/* Y is not relevant since you only move it on X axis */
var position1 = 100;
var position2 = 100;
var dest = 800; //Or any given value
function move() {
var step1 = Math.floor(1 + (10 * Math.random() ) );
var step2 = Math.floor(1 + (10 * Math.random() ) );
position1 += step1;
position2 += step2;
document.getElementById("cowboy").style.left = position1+'px';
document.getElementById("cowboytwo").style.left = position2+'px';
if(position1 < dest && position2 < dest) {
window.setTimeout('move()',100);
} else {
//We have the winner
if(position1 > dest) alert("Winner is Cowboy1");
if(position2 > dest) alert("Winner is Cowboy2");
//Its also possible that both of them pass target value at the same step
}
}

Categories

Resources