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);
Related
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);
}
I wrote a javascript version of Lagrange algorithm, but it kept going wrong when I run it, I don't know what went wrong.
I use this to calculate time.
When I pass a cSeconds as a variable, sometimes it returns a minus value which is obviously wrong...
function LagrangeForCat(cSeconds){
var y = [2592000,7776000,15552000,31104000,93312000,155520000,279936000,404352000,528768000,622080000,715392000,870912000,995328000,1119744000,1244160000,1368576000,1492992000,1617408000,1741824000,1866240000,1990656000,2115072000,2239488000,2363904000,2488320000,2612736000,2737152000,2861568000,2985984000,3110400000,3234816000,3359232000,3483648000,3608064000];
var x = [604800,1209600,1814400,2592000,5184000,7776000,15552000,23328000,31104000,46656000,62208000,93312000,124416000,155520000,186624000,217728000,248832000,279936000,311040000,342144000,373248000,404352000,435456000,466560000,497664000,528768000,559872000,590976000,622080000,653184000,684288000,715392000,746496000,777600000];
var l = 0.0;
for (var j = 0; j < 34; j++) {
var s = 1.0;
for (var i = 0; i < 34; i++) {
if (i != j)
s = s * ((cSeconds - x[i]) / (x[j] - x[i]));
}
l = l + s * y[j];
}
var result = l / (24 * 60 * 60);
var Days = Math.floor(result);
//get float seconds data
var littleData = String(result).split(".")[1];
var floatData = parseFloat("0."+littleData);
var second = floatData *60*60*24;
var hours = Math.floor(second/(60*60));
var minutes = Math.floor(second % 3600/60);
var seconds = Math.floor(second % 3600) % 60;
var returnData = {days:Days,hours: hours + ':' + minutes + ':' + seconds}
return returnData;
}
I don't believe the issue is with your code but with the data set.
I tried a few things, for instance if you have cSeconds = one of the x values, then you get the correct result (I could check that it was equal to the matching y value).
I put all the data in open office and drew the graph it was like the square root function but more extreme (the 'straight' part look very straight) then I remembered that when you interpolate you usually get a polynomial that crosses the points you want but can be very wild outside between the point.
To test my theory I modified the algorithm to control at which x/y index to start and tried for all the values:
for (let i = 0; i < 35; ++i) {
LagrangeForCat(63119321, i, 34)
}
Together with a console.log inside LagrangeForCat it gives me the interpolated y value if I use all the x/y arrays (i=0), if I ignore the first x/y point (i=1), the first two (i=2), ...
00-34 -6850462776.278063
01-34 549996977.0003194
02-34 718950902.7592317
03-34 723883771.1443908
04-34 723161627.795225
05-34 721857113.1756063
06-34 721134873.0889213
07-34 720845478.4754647
08-34 720897871.7910147
09-34 721241470.2886044
10-34 722280314.1033486
11-34 750141284.0070543
12-34 750141262.289736
13-34 750141431.2562406
14-34 750141089.6980047
15-34 750141668.8768387
16-34 750142353.3267975
17-34 750141039.138794
18-34 750141836.251831
19-34 750138039.6240234
20-34 750141696.7529297
21-34 750141120.300293
22-34 750141960.4248047
23-34 750140874.0966797
24-34 750141337.5
25-34 750141237.4694824
26-34 750141289.2150879
27-34 750141282.5408936
28-34 750141284.2094421
29-34 750141283.987999
30-34 750141284.0002298
31-34 750141284.0000689
32-34 750141283.9999985
33-34 3608064000
34-34 0
Exclude 33-34 and 34-34 (there's just not enough data to interpolate).
For the example x=63119321 you'd expect y to be between 715392000 and 870912000 you can see that if you ignore the first 2-3 values the interpolation is "believable", if you ignore more values you interpolate based off the very straight part of the curve (see how consistent the interpolation is from 11-34 onward).
I use to work on a project where interpolation was needed, to avoid those pathological cases we opted for linear interpolation trading accuracy for security (and we could generate all the x/y points we wanted). In your case I'd try to use a smaller set, for instance only two values smaller than cSeconds and two greater like this:
function LagrangeForCat(cSeconds) {
var x = [...];
var y = [...];
let begin = 0,
end = 34
for (let i = 0; i < 34; ++i) {
if (cSeconds < x[i]) {
begin = (i < 3) ? 0 : i - 2
end = (i > (x.length - 1)) ? x.length : i + 1
break
}
}
let result = 0.0;
for (let i = begin; i < end; ++i) {
let term = y[i] / (24 * 60 * 60)
for (let j = begin; j < end; ++j) {
if (i != j)
term *= (cSeconds - x[j]) / (x[i] - x[j]);
}
result += term
}
var Days = Math.floor(result);
// I didn't change the rest of the function didn't even looked at it
}
If you find this answer useful please consider marking it as answered it'd be much appreciated.
This is my array. Its length is about 9000. This is what a small bit of it looks like:
foreach_arr = ["21:07:01.535", "21:07:01.535", "21:07:26.113"]
There are a few occurences where the times diff is greater than a minute, and that is when I want to grab those times. And later use those times to get certain indices from another array. i.e "array"
I'm also using moment.js for time parsing.
Expected result: array = [8127, 9375, 13166, 14182]
Actual result: array = [8127, 13166]
Can't seem to find the issue here, I am getting 2 results when im supposed to be getting 4.
If the whole array is needed for troubleshooting, ill add it if I can.
var xx = foreach_arr.length - 1;
for(var z = 0; z < xx; z++) {
var current_row = foreach_arr[z];
var next_row = foreach_arr[z + 1];
var msElapsedTime = moment(next_row,"HH:mm:ss.SSS").diff(moment(current_row, "HH:mm:ss.SSS")) / 1000;
if(msElapsedTime > 60) {
attempt_indices.push(foreach_arr[z]);
}
}
for(var x = 0; x < attempt_indices.length; x++) {
array.push(newdata.indexOf(attempt_indices[x]));
}
Since the OP doesn't really need my code anymore, I'm posting it here to remove the downvote as much as anything else :)
const foreach_arr = ["21:07:01.535", "21:07:01.535", "21:07:26.113", '22:01:01.000'];
let processedForeach_arr = [];
let gtOneMinuteDiff = [];
foreach_arr.forEach((elem1, index1) => {
// elem1.split(':') turns foreach_arr[0] into ['21', '07', '01.535']
const splitElementArray = elem1.split(':');
let timeInMs = 0;
// this changes ['21', '07', '01.535'] into [75600000, 420000, 1535]
splitElementArray.forEach((elem2, index2) => {
if (index2 === 0) { // elem2 is hours. 3.6M ms per hour.
timeInMs += parseFloat(elem2) * 60 * 60 * 1000;
} else if (index2 === 1) { // elem2 is minutes. 60K ms per minute.
timeInMs += parseFloat(elem2) * 60 * 1000;
} else if (index2 === 2) { // elem2 is seconds. 1K ms per second.
timeInMs += parseFloat(elem2) * 1000;
} else {
throw `Expected array element formatted like HH:MM:SS.ms. Error on
element ${elem1}.`;
}
});
processedForeach_arr.push(timeInMs);
let timeDiff = processedForeach_arr[index1 - 1] - processedForeach_arr[index1];
if (Math.abs(timeDiff) > 60000) {
gtOneMinuteDiff.push(timeDiff);
}
});
To get the difference in milliseconds between foreach_arr[n] and foreach_arr[n+1], this code will
split each element of foreach_arr into 3 strings (hours, minutes, and seconds + milliseconds)
run parseFloat on each of those values to convert them to a number
convert all numbers to milliseconds and add them together
compare each consecutive value and return the difference.
Ok, I got this far and my son needs me. I'll finish out the code asap but you might beat me to it, hopefully the instructions above help.
turns out my code wasn't wrong. Just my idea of the whole proccess.
array = [8127, 13166]
is what I initialy get. With this, I use indexOf on my other array to eventually get my array as expected:
var another_test_arr = [];
for(var v = 0; v < array.length ; v++) {
var find = foreach_arr.indexOf(attempt_indices[v]);
another_test_arr.push(array[v], newdata.indexOf(foreach_arr[find + 1]));
}
Result: array = [8127, 9375, 13166, 14182]
It's kind of math problem. I want to fire specific number of setTimeout (the number is based on an array length) in a specific period of time (say, 5 seconds).
The first setTimeout should start at 0 sec. and the last at 5 sec.. All timeouts between should start with an ease-in effect, so that each timeout starts faster.
There's an example which ilustrates what I want to achieve exactly.
I'm struggling around this line:
next += timePeriod/3.52/(i+1);
which works almost perfect in demo example (for any timePeriod), but obviously it doesn't work for a different letters.length as I have used static number 3.52.
How do I calculate next?
var letters = [
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T'
];
var div = $('#container');
var timePeriod = 5000; // 5 seconds;
var perLetter = timePeriod/(letters.length-1); // it gives equal time between letters
var next = 0;
for(var i=0; i<letters.length; i++){
setTimeout(function(letter){
//div.append('<span class="letter">' + letter + '</span>');
// Used "|" instead of letter, For better redability:
div.append('<span class="letter">|</span>');
}, next, letters[i]);
// Can't find the logic here:
next += timePeriod/3.52/(i+1);
};
///////////////// FOR DEMO: ///////////////
var sec = timePeriod/1000;
var secondsInterval = setInterval(seconds, 1000);
var demoInterval = setInterval(function(){
sec >= 0 || clearInterval(demoInterval);
div.append('\'');
}, 30);
function seconds(){
sec || clearInterval(secondsInterval);
$('#sec').text(sec-- || 'DONE');
}
seconds();
.letter{
color : red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id=container></span>
<span id=sec class=letter></span>
var steps = letters.length;
var target = timePeriod;
function easeOutQuad(t, b, c, d) {
t /= d;
return -c * t*(t-2) + b;
};
var arrayOfTimeouts = new Array(steps);
var n;
var prev = 0;
for(var i = 1; i <= steps; i++){
n = easeOutQuad(i, 0.0, target, steps);
arrayOfTimeouts[i-1] = n-prev;
prev = n;
}
This one should work with any input value.
fiddle
Note that the graph appears to be slightly too fast but I believe that discrepancy to be a product of timing imperfections, as the sum of my array equals the timePeriod exactly.
more on easing equations
Here's a solution based on a geometric series. It's a bit goofy but it works. It generates an array with your timeout values.
Steps = size of your array.
Target = the total time.
var steps = 50;
var target = 5000;
var fraction = 1.5 + steps / 7;
var ratio = (fraction-1) / fraction;
var n = target / fraction;
var sum = 0;
var arrayOfTimeouts = new Array(steps);
for(var i = 0; i < steps; i++){
sum += n;
arrayOfTimeouts[i] = n;
n *= ratio;
}
console.log(arrayOfTimeouts, sum);
I'm trying to write an if/else function for a simple game but I'm new to coding.
Chapters = 0;
Books = 0;
Pens = 1;
WarehouseRoom = 50;
function ChaptersUp(number) {
if (Pens > 0) {
if ((Chapters + number) <= 9) {
Chapters = Chapters + number;
document.getElementById("Chapters").innerHTML = Chapters;
}
else {
ChaptersOver = (Chapters + number - 10);
if (Books < WarehouseRoom) {
if (ChaptersOver <= 9) {
Books = Books + 1;
Chapters = ChaptersOver;
document.getElementById("Chapters").innerHTML = Chapters;
document.getElementById("Books").innerHTML = Books;
}
else {
BooksOver = Math.floor(ChaptersOver / 10);
Books = Books + BooksOver + 1;
Chapters = (ChaptersOver - (BooksOver * 10));
document.getElementById("Chapters").innerHTML = Chapters;
document.getElementById("Books").innerHTML = Books;
}
}
}
}
}`
I want the function to run up to the point where the Warehouse is full. Currently, if I add 11 Books (110 Chapters) at a time, the function will stop operating at 55 books, but I've already went over the limit.
Question : How can I make it stop at exactly the amount equal to WarehouseRoom?
You should try a for statment.
for(int i = 1; i > warehouseFull; i++)
{
}
i is used to for the repeat and the loop will repeat till it is equal to warehouseFull. The i++ on the end is there so that once the loop is done it adds 1 to i. You could do the same backwards if you lose x amount of books. also you don't have to declare i inside the for statesmen but if you are going to use many for statement then it will make it easier so you don't have to switch letters or declare i = 0;.