I am new to JS, so I have couple of questions.
In JS, how can we calculate memory consume by code/code-block and which block is taking what time. Any articles/blogs will be big help.
Below code execute successfully but exceeds execution time. How can i reduce the execution time of the code. Any tips will be helpful.
Problem Statement : given a range L to T. Find such numbers whose all digits are a multiple of K.
Input for code:
The first line contains the number of test cases.
Next lines contain integers. (L T K)
5
5 10 5
20 40 2
300 600 3
process.stdin.resume();
process.stdin.setEncoding("utf-8");
var stdin_input = "";
process.stdin.on("data", function (input) {
stdin_input += input; // Reading input from STDIN
});
process.stdin.on("end", function () {
main(stdin_input);
});
function main(input) {
// process.stdout.write("Hi, " + input + ".\n"); // Writing output to STDOUT
input = input.split('\n');
// console.log(input);
let T = parseInt(input[0])+1;
for(var i=1;i<T;i++){
let d=input[i].split(' ');
calc(parseInt( d[0]),parseInt( d[1]),parseInt( d[2]));
}
}
function calc(T,L,k){
ar=[];
for(let i = T;i<=L;i++){
if((i>0 && i<10)&& (i%k==0) ){
ar.push(i);
} else {
splitNumber(i,k) ? ar.push(i):'';
}
}
console.log(ar.length);
}
function splitNumber(num,k)
{
let bool=false;
num= splitToDigit(num);
for(let i =0;i<num.length;i++){
if(num[i]%k == 0 ){
bool=true;
} else{ return false; }
}
return bool;
}
function splitToDigit(n){
return [...n + ''].map(Number);
}
Related
I am working on sequential and parallel programming in javascript, I was able to solve sequential programming but didn't have an idea of how to do the same using parallel programming.
For Sequential problem was :
This is an example of sequential processing where it will start at 1 and go till 3 and add 21 to it. Then it will start at 1 and go till 2 and add 10 to it. In the end, start at 1 and go till 4 and add 1 to it.
For Input : 1 3*21#2*10#4*1
output will be :
22
23
24
11
12
2
3
4
5
I solved using below code
function solution(inputData) {
var first = inputData.substring(0, 1);
if(first == 1)
{
//sequential
var strArr = inputData.split(" "); //3*21#2*10#4*1
var strHashSplitArr = strArr[1].split("#"); //3*21 #2*10# 4*1
for(var i=0;i<strHashSplitArr.length;i++)
{
var loopInp = strHashSplitArr[i].split("*");
var maxVal = parseInt(loopInp[0]);
var addVal = parseInt(loopInp[1]);
for(var k=1;k<=maxVal;k++)
{
console.log(k+addVal);
}
}
}
}
But now the problem is with parallel programming
Problem:
For example 2, there are 3 processes to start in parallel and numbers are 1, 2 and 3 with delays 100, 20 and 50 consecutively. Here all the processes will start together but a number with less delay will be printed first. Here the number with less delay is 2.So it will print 21,22 in the meantime 50 ms will be achieved and it will print 51 from 3rd number. Now it is mixed with number 1 and prints 101 and so on.
Input : 2 1*100#2*20#3*50
Output should be :
21
22
51
101
52
53
I didn't try using parallels but sorted with milliseconds but couldn't get the expected output.
Here is JSfiddle code for 2nd .. which is giving wrong output (I am not using parallel approach) : https://jsfiddle.net/mahajan344/0u2ka981/
How can I achieve the same output using parallel JavaScript programming?
I think a solution for the problem using setTimeout may be:
function printParallel(val, delay)
{
setTimeout(function()
{
console.log(val);
}, delay);
}
function solution(inputData) {
var first = inputData.substring(0, 1);
var strArr = inputData.split(" ");
var strHashSplitArr = strArr[1].split("#");
for (var i = 0; i < strHashSplitArr.length; i++)
{
var loopInp = strHashSplitArr[i].split("*");
var maxVal = parseInt(loopInp[0]);
var modifier = parseInt(loopInp[1]);
if (first == 1)
{
for (var j = 1; j <= maxVal; j++)
{
console.log(j+modifier);
}
}
else if (first == 2)
{
for (var j = 1; j <= maxVal; j++)
{
printParallel(j+modifier, modifier);
}
}
}
}
So you will call solution("1 3*21#2*10#4*1"); and solution("2 1*100#2*20#3*50"); to execute the examples but this won't output as expected because the delay of 100 of number 1 is too big to mix with the printing of number 3.
EDIT:
I think now I understand the goal: yo need to set a timeout between every console.log. This will work as expected:
function printParallel(value, maxVal, modifier)
{
setTimeout(function()
{
console.log(value+modifier);
if (value < maxVal)
{
printParallel(++value, maxVal, modifier)
}
}, modifier);
}
function solution(inputData) {
var first = inputData.substring(0, 1);
var strArr = inputData.split(" ");
var strHashSplitArr = strArr[1].split("#");
for (var i = 0; i < strHashSplitArr.length; i++)
{
var loopInp = strHashSplitArr[i].split("*");
var maxVal = parseInt(loopInp[0]);
var modifier = parseInt(loopInp[1]);
if (first == 1)
{
for (var j = 1; j <= maxVal; j++)
{
console.log(j+modifier);
}
}
else if (first == 2)
{
printParallel(1, maxVal, modifier);
}
}
}
Consider:
async function delay(n) {
return new Promise(r => setTimeout(r, n));
}
async function* asyncRange(a, b, d) {
while (a < b) {
await delay(d);
yield a++;
}
}
async function parallel(...ranges_and_delays) {
let iters = ranges_and_delays.map(t => asyncRange(...t));
while (iters.length) {
await Promise.race(iters.map(async it => {
let v = await it.next();
if (!v.done) {
console.log(v.value)
} else {
iters = iters.filter(k => k !== it)
}
}));
}
}
parallel([1, 5, 700], [10, 13, 500], [200, 205, 600])
The idea is to put range generators in an array, start a race between them and print whatever comes first. Once a generator is exhausted, remove it from the list.
Note that this isn't real parallel computing (which is not possible in Javascript), just an imitation.
You cannot run your code in parallel in Javascript. It is single threaded language. However, you can use browser's web APIs to do work in parallel. For example, making xhr call.
Note: You cannot even run your code in parallel with SetTimeout() as it will only run the code when the call stack is empty. It does not actually run the code in parallel.
To develop an understanding of this, you must understand event loop.
https://www.educative.io/edpresso/what-is-an-event-loop-in-javascript
I'm having some trouble with the test cases for Project Euler #1 on HackerRank and was hoping someone with some JS experience on HackerRank could help out.
Below is my code. As far as I can tell, I can't spot any obvious logic errors so I would appreciate if someone could shed some light on why I'm not passing all the test cases and why the status is "abort called". All the code above "ignore above this line" is provided by HackerRank and is not part of the solution.
process.stdin.resume();
process.stdin.setEncoding('ascii');
var input_stdin = "";
var input_stdin_array = "";
var input_currentline = 0;
process.stdin.on('data', function (data) {
input_stdin += data;
});
process.stdin.on('end', function () {
input_stdin_array = input_stdin.split("\n");
main();
});
function readLine() {
return input_stdin_array[input_currentline++];
}
/////////////// ignore above this line ////////////////////
function threeFiveMultiples(num) {
let array = [];
for (let i = 0; i < num; i++) {
if (i % 3 === 0 ||
i % 5 === 0) {
array.push(i);
}
}
return array.reduce(function(accum, currVal) {
return accum + currVal;
});
}
function main() {
var t = parseInt(readLine());
for(var a0 = 0; a0 < t; a0++){
var n = parseInt(readLine());
let res = threeFiveMultiples(n);
console.log(res);
}
}
I've also tried using a BigNumbers library (see below).
process.stdin.resume();
process.stdin.setEncoding('ascii');
var BigNumber = require('bignumber.js');
var input_stdin = "";
var input_stdin_array = "";
var input_currentline = 0;
process.stdin.on('data', function (data) {
input_stdin += data;
});
process.stdin.on('end', function () {
input_stdin_array = input_stdin.split("\n");
main();
});
function readLine() {
return input_stdin_array[input_currentline++];
}
/////////////// ignore above this line ////////////////////
function threeFiveMultiples(num) {
let array = [];
for (let i = 0; i < num; i++) {
if (i % 3 === 0 ||
i % 5 === 0) {
array.push(i);
}
}
return parseInt(array.reduce(function(accum, currVal) {
accum = new BigNumber(accum);
currVal = new BigNumber (currVal);
return accum.plus(currVal);
}));
}
function main() {
var t = parseInt(readLine());
for(var a0 = 0; a0 < t; a0++){
var n = parseInt(readLine());
let res = threeFiveMultiples(n);
console.log(res);
}
}
UPDATE:
Per the suggestion of #5ar, I replaced my reduce function with the following; however, test cases #2 and #3 are still failing:
return array.reduce(function(accum, currVal) {
return accum.plus(currVal);
}, new BigNumber(0)).toString();
Your code is fine. If you simply call console.log(threeFiveMultiples(1000));, it will give you the solution. Not sure what all the other code is about, but that will work.
Try to use Math.round() on your values (after summing them), JavaScript treats all numbers as doubles so some may not be showing correctly.
If big numbers are the problem, try to find a library that you can use that can handle big numbers. If you can't, you can implement them yourself via strings, considering that you only need summing it shouldn't be that difficult.
UPDATE:
I think the return might be the problem (you're using parseInt which probably converts the BigNumber to a String and then tries to parse it as a Number), try to do this:
return array.reduce(function(accum, currVal) {
return accum.plus(currVal);
}, new BigNumber(0)).toString();
The problem is that for really large numbers the calculation takes up a quite significant amount of time and hackerrank has a timeout of 10s for the calculation. You have to find a faster way of calculation the correct output.
A small hint: Arithmetic progression (its possible in O(1))
There are two possible reasons why your code is failing
1) Timeout error
The code logic you have written iterates each number and checks if it is divisible by 3 or 5. This logic causes the time out error when the number in the testcase is huge number.
2) Number Cannot be represented in JS
The number used in Test Case 3 & Test Case 2 is a big number. So using a library like 'bignumber.js' is necessary, since JS does not support long integers.
Below is the code snippet which will help pass all the Test cases:
process.stdin.resume();
process.stdin.setEncoding('ascii');
var input_stdin = "";
var input_stdin_array = "";
var input_currentline = 0;
process.stdin.on('data', function (data) {
input_stdin += data;
});
process.stdin.on('end', function () {
input_stdin_array = input_stdin.split("\n");
main();
});
function readLine() {
return input_stdin_array[input_currentline++];
}
/////////////// ignore above this line ////////////////////
function main() {
var BigNumber = require('bignumber.js');
var t = new BigNumber(readLine()).toNumber();
var n;
for (var a0 = 0; a0 < t; a0++) {
n = new BigNumber(readLine());
sumOfNumberDivisibleBy3and5(n);
}
}
function sumOfNumberDivisibleBy3and5(n) {
const a = n.minus(1).dividedBy(3).floor();
const b = n.minus(1).dividedBy(5).floor();
const c = n.minus(1).dividedBy(15).floor();
const sumThree = a.times(3).times(a.plus(1)).dividedBy(2);
const sumFive = b.times(5).times(b.plus(1)).dividedBy(2);
const sumFifteen = c.times(15).times(c.plus(1)).dividedBy(2);
const sumOfAll = sumThree.plus(sumFive).minus(sumFifteen);
console.log(sumOfAll.toString());
}
This worked for me
function main() {
var t = parseInt(readLine());
for(var a0 = 0; a0 < t; a0++){
var n = parseInt(readLine());
/////////////////they forgot to tell us to put code below here
let N=BigInt(n)-BigInt(1)
let i3=BigInt(N)/BigInt(3)
let i5=BigInt(N)/BigInt(5)
let i15=BigInt(N)/BigInt(15)
let m3=BigInt(3)*BigInt(i3)*(BigInt(i3)+BigInt(1))
let m5=BigInt(5)*BigInt(i5)*(BigInt(i5)+BigInt(1))
let m15=BigInt(15)*BigInt(i15)*(BigInt(i15)+BigInt(1))
let sum=(BigInt(m3)+BigInt(m5)-BigInt(m15))/BigInt(2)
console.log(sum.toString())
/////////////////they forgot to tell us to put code above here
}
}
My task is to write a test-function. So that the runtime of two different function-implementation (doing the same task) can be compared. Task is to change a dash-separated string to camel case notation. But that's secondary here.
I guess I should show the whole test-setup first:
// The array with the test-data. I have shorten it a lot.
// The original-array, used for the test, is much larger.
var test = ["Alpha-North-blue-teal-West-pink-crimson-Delta",
"crimson-Gamma-blue-Delta",
"white-cyan-South-blue-East-East-South-blue",
"teal-black-East-East",
"South-black",
"black-cyan",
"West-white-Beta-Gamma-red-North-Alpha-Beta",
"Gamma-North-West-lime-North-crimson-North",
"blue-red-orange",
"red-West-South"];
// -- Implementation 1 ----------
function dashedToCamelCase( dashed ) {
var ret;
var parts;
if (typeof dashed !== 'string' || !dashed) {
return '';
}
parts = dashed.split('-');
ret = parts[0].toLowerCase();
parts = parts.slice(1);
ret = parts.reduce(function(previous, current) {
return previous +
current.slice(0, 1).toUpperCase() +
current.slice(1).toLowerCase();
}, ret);
return ret;
}
// -- Implementation 2 ----------
function dashedToCamelCase2( dashed ) {
if( typeof dashed != "string" || dashed.length==0 )
return "";
return dashed.toLowerCase().replace(/\-([a-z]?)/g, function(match, letter) {
return letter.toUpperCase();
});
}
function getRuntime(testData, func, countRunningTests) {
var i;
var tmp = 0;
var sum = 0;
var min = 0;
var max = 0;
var ret = {};
var getRuntimeSingleTest = function() {
var start = Date.now();
testData.forEach( function( item ) {
func(item);
});
return (Date.now() - start);
}
for (i = 1; i <= countRunningTests; i++) {
tmp = getRuntimeSingleTest( testData, func );
sum += tmp;
if (min === 0 || tmp < min) {
min = tmp;
} else if (tmp > max) {
max = tmp;
}
}
ret.averageRuntime = sum / countRunningTests;
ret.minimalRuntime = min;
ret.maximalRuntime = max;
return ret;
}
function displayResults( results, funcName ) {
funcName = funcName || '';
console.log('\n%s', funcName);
for ( var i in results ) {
console.log('%s : %s ms', i, results[i]);
}
}
displayResults(getRuntime(test, dashedToCamelCase, 100), ' - Implementation using reduce() - ');
displayResults(getRuntime(test, dashedToCamelCase2, 100), ' - Implementation using replace() - ');
What I don't understand:
I let the functions process the whole string-array many times. The results for the minimum and the maximum runtime differ a lot. With a lot I mean the maximal-runtime is six or seven times higher then the minimal-runtime.
The average-runtime also differs a lot. But not multiple times.
How is that possible?
It's always the same data which are used. The results should be at least similar.
Test have been runned on a computer with Windows 7 and Internet Explorer 11.
CPU: Intel i5-3230M 2.60 GHz
RAM: 8 GB
UPDATE
Like in the accepted answer suggested I increased in count of test-runs.
What I can say now is that the more test-runs used the more stable becomes the average-runtime.
So it's likely as supposed: The variations in the minimum- and maximum-results are an result of other processes which demand CPU-time.
Run time depends on running processes on your computer. So if your antivirus starts to do some stuff, than your browser process must wait.
Better run these tests like 100000 times same function to calculate average.
I am trying to call a function in jQuery and the variable is coming back as undefined in the console
var divide = function(entry) {
var entry = number
for (var i = 1; i <= entry; i++) {
if (i % 5 === 0 && i % 3 === 0) {
return "pingpong";
} else if ( i % 3 === 0) {
return "ping";
} else if (i % 5 === 0 ) {
return "pong";
} else {
return i;
}
}
}
$(document).ready(function(){
$("form#number").submit(function(event){
var number = parseInt($("#userNumber").val());
var pingpong = divide (number);
$("#result").text(pingpong);
event.preventDefault();
});
});
Why do you need a for-loop for this ? Assigning number to entry will not help as number is within the local scope of $(document).ready which will be undefined for divide. As you are passing entry as an argument, use that for conditions
Try this:
var divide = function(i) {
if (i % 5 === 0 && i % 3 === 0) {
return "pingpong";
} else if (i % 3 === 0) {
return "ping";
} else if (i % 5 === 0) {
return "pong";
} else {
return i;
}
}
$(document).ready(function() {
$("form#number").submit(function(event) {
var number = parseInt($("#userNumber").val());
var pingpong = divide(number);
$("#result").text(pingpong);
event.preventDefault();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<form id='number'>
<input type="number" id='userNumber'>
<input type="submit">
<div id="result"></div>
</form>
Fiddle here
I think you may be confused about how arguments are passed into functions.
You have:
function divide ( entry ) { // defining divide
var entry = number; // this line is counter-productive
...
}
....
var number;
... divide(number); // calling divide
When you call the divide() function, the value of the variable number is automatically copied into the variable entry in divide(). Then you attempt to do the same thing with var entry = number; but number is not available in divide() so this fails. Lets suppose that number was globally available do this line did not cause an error. It might do what you want in this case, but a function whose argument is immediately ignored and overwritten is not very useful. Imagine you wanted to call it with two different values:
divide(number);
...
divide(someothernumber);
that wouldn't work because of the var entry = number; line -- you could never successfully pass someothernumber into divide(). Delete the line:
var entry = number;
from divide() and you will be much happier.
you try to delete "var entry = number"
Really sorry if you've gone over this already with me. The good news: I've made progress. The bad news: it's broken progress.
I have a function that counts up from a certain number. It's a big number, and I need to insert commas in the correct places. Here's the code I've put together. It works at first, but then displays NaN...
http://jsfiddle.net/blackessej/TT8BH/7/
function createCounter(elementId,start,end,totalTime,callback)
{
var jTarget=jQuery("#"+elementId);
var interval=totalTime/(end-start);
var intervalId;
var current=addCommas(start)+'';
var f=function(){
jTarget.text(current);
if(current==end)
{
clearInterval(intervalId);
if(callback)
{
callback();
}
}
++current;
}
intervalId=setInterval(f,interval);
f();
}
jQuery(document).ready(function(){
createCounter("counter",12714086,9999999999,10000000000000,function(){
alert("finished")
})
})
function addCommas(str) {
var amount = new String(str);
amount = amount.split("").reverse();
var output = "";
for ( var i = 0; i <= amount.length-1; i++ ){
output = amount[i] + output;
if ((i+1) % 3 == 0 && (amount.length-1) !== i)output = ',' + output;
}
return output;
}
The problem comes from adding the commas to the number. Just convert the number to the comma string before putting it in the .text() function:
http://jsfiddle.net/TT8BH/11/
When you call addCommas, you are returning a String, nicely formatted for humans, but terrible for things like ++. You need to track and modify the start variable, and only convert to string when necessary:
var f=function(){
jTarget.text(addCommas(start));
if(start==end)
{
clearInterval(intervalId);
if(callback)
{
callback();
}
}
++start;
}