I have found this script on the Mozilla Development Network as an example.
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
Could you explain me what the double "+" means right after the "start"? Will it change the value of the start variable?
Thank you
This is the same as
var old_value = start;
start = start + 1;
if (element % old_value < 1) {
...
Read the value of the variable and then increase it by one.
The double "+" after a variable means that it will increase that variable by 1 after it has used it in the statement.
So in your case element % start++ < 1 is equivalent to element % start < 1; start = start+1;
On the other hand, having the "++" before the variable, means it will first increment the variable, and then execute the statement.
Here are some examples of this behaviour:
var a = 1;
var b = a++;
console.log(b); // 1
console.log(a); // 2
var c = 1;
var d = ++c;
console.log(d); //2
console.log(c); //2
var test = 2;
if (8 % test++ < 1) {
console.log("will log");
}
test = 2;
if (8 % ++test < 1) {
console.log("will NOT log");
}
Related
The challenge is to return an array that follows an arrow pattern when given a number. For example:
arrow(3) ➞ [">", ">>", ">>>", ">>", ">"]
I have almost completed it but it repeats the middle value in the array twice.
function arrow(n) {
var arr = [];
var num = 1;
while(num <= n) {
arr.push(">".repeat(num));
num++;
}
while(num > 0) {
arr.push(">".repeat(num - 1));
num--;
}
return arr;
}
console.log(arrow(3));
So then I changed it to this (for the second repeat I changed it to num - 2 but it says an error).
function arrow(n) {
var arr = [];
var num = 1;
while(num <= n) {
arr.push(">".repeat(num));
num++;
}
while(num > 0) {
arr.push(">".repeat(num - 2));
num--;
}
return arr;
}
console.log(arrow(3));
Can someone explain to me why this doesn't work?
Your function does not work because you start the second loop when num is equal to n + 1 (which causes the middle value to be added twice) and do not end the loop until num is 0 (which causes an empty string to be appended to the result). For a simpler solution, you can use Array.from with a bit of arithmetic.
function arrow(n) {
return Array.from({length: n * 2 - 1}, (_,i)=>">".repeat(i < n ? i + 1 : n * 2 - 1 - i));
}
console.log(arrow(3));
The first one does not work because "num" is incremented a last time and thus equals "n + 1" when the code goes out from the while loop.
So if "n" = 3, when the code executes the first "while(num > 0) {", num will equal 4. So 4 - 1 = 3 repetition of the arrow.
So, to fix it :
function arrow(n) {
var arr = [];
var num = 1;
while(num <= n) {
arr.push(">".repeat(num));
num++;
}
num--; // add this line
while(num > 0) {
arr.push(">".repeat(num - 1));
num--;
}
return arr;
}
console.log(arrow(3));
The error with the first solution is that when num equals 3, you increment it to 4 in the while loop. When the second while loop runs, num - 1then equals 3.
In the second solution, num - 2 will equal -1 during the fourth iteration, which throws an error.
A for-loop may be easier to control here:
function arrow(n) {
var arr = [];
var num = 1;
for (let i = 1; i <= n; i++) {
arr.push(">".repeat(i))
}
for (let i = n - 1; i > 0; i--) {
arr.push(">".repeat(i));
}
return arr;
}
The issue with your second function :
when you were using the second while loop, the value of num was decreasing by 1 in each loop.
when the loop value of num comes to 1 , and and you tried to use arr.push(">".repeat(num - 2)); , then n-2 = -1 , but repeat(-1) is invalid function.
Solution:
I think in between two while loop, use num--; to decrease the value of num by 1. it will solve your problem.
function arrow(n) {
var arr = [];
var num = 1;
while(num <= n) {
arr.push(">".repeat(num));
num++;
}
num --;
while(num > 1) {
arr.push(">".repeat(num - 1));
num--;
}
return arr;
}
console.log(arrow(3));
so when your loop get the last element number == 1
the repeat function (num-2) will not work
for this challenger i simply put a (number--;) in the middle of the While loops
i hope that work.
function arrow(n) {
var arr = [];
var num = 1;
while(num <= n) {
arr.push(">".repeat(num));
num++;
}
num--; // take 1 out
while(num > 1) {
arr.push(">".repeat(num -1));
num--;
}
return arr;
}
console.log(arrow(3));
I saw a question in leetcode.
Also,I found solution in it.
And one thing i don't understand is this line of code
while(n-- >1)
Could someone explain --> meaning?
Here is the JS:
var countAndSay = function(n) {
var result = "1";
var prev;
var count;
var tmp;
while (n-- > 1) {
prev = result[0];
count = 1;
tmp = [];
for (var i = 1; i < result.length; i++) {
if (prev === result[i]) {
count++;
} else {
tmp.push(count, prev);
prev = result[i];
count = 1;
}
}
tmp.push(count, prev);
result = tmp.join("");
}
return result;
};
console.log(countAndSay(4))
One last thing,Could someone explain what is this question's meaning.
I still don't understand why 2 is 11,3 is 21,4 is 1211 and 5 is 111221.
The expression
n-- > 1
means: subtract one from n, and check whether its value before the subtraction was greater than 1.
while (n-- > 1) {
// rest of the code
is equivalent to
while (true) {
if (n > 1) {
n--;
// rest of the code
} else {
// n is decremented regardless:
n--;
// initial condition was not fulfilled:
break;
}
Or, with the negation of the condition:
while (true) {
const origN = n;
n--;
if (!(origN > 1)) {
break;
}
// rest of the code
That means you check whether the n is greater than 1 and after that decrement n by 1.
That means, subtract 1 from n and check if the result is greater than 1.
n-- in any part of the code is equivalent to n = n - 1, or ``n -= 1`, in that loop is a consised way to subtract and evaluate.
The expression (n-- > 1) is similar to comparing the value of n greater than 1. But the thing which you must notice is the value of n will not be decremented(at the beginning) while comparing here. This is because the value of n is first compared with 1 after that only, the value of n is decremented. To understand this clearly, you can take a look over this.
function test(name) {
var n = 5;
while (n-- == 5) { //Here the decrement doesn't takes places so it gets inside the block
console.log(n); //This statement returns the value of n as 4.
}
}
const testing = new test();
My code is freezing Chrome (and Firefox), won't execute on Coderbyte console but when I submit the code as an answer to the exercise, it does take.
var numOrdered = 0;
var numReversed = 0;
var tries = 0;
function KaprekarsConstant(num) {
var arr = [];
while (num > 0) {
arr.unshift(num % 10);
num = num / 10 | 0;
}
arr.sort();
numOrdered = Number(arr.join(''));
numReversed = Number(arr.reverse().join(''));
while (num !== 6174) {
num = numReversed - numOrdered;
tries += 1;
}
return tries;
};
KaprekarsConstant(8593);
Why is it crashing? How can I prevent it?
Thank you guys!
the actual problem is the second while loop:
while (num !== 6174) {
num = numReversed - numOrdered;
tries += 1;
}
Removing it, your code doesn't hang the browser:
var numOrdered = 0;
var numReversed = 0;
var tries = 0;
function KaprekarsConstant(num) {
var arr = [];
while (num > 0) {
arr.unshift(num % 10);
num = num / 10 | 0;
}
arr.sort();
numOrdered = Number(arr.join(''));
numReversed = Number(arr.reverse().join(''));
return tries;
};
console.log(KaprekarsConstant(8593));
You need to revisit the logic in the second loop so that it doesn't become infinite.
The second loop makes your code to hang up.Try this. I have made some changes.
var numOrdered = 0;
var numReversed = 0;
var tries = 0;
function KaprekarsConstant(num) {
while (num !== 6174) {
var arr = [];
while(num >0){
arr.unshift(num % 10);
num = num / 10 | 0;
}
arr.sort();
numOrdered = Number(arr.join(''));
numReversed = Number(arr.reverse().join(''));
num = numReversed - numOrdered;
tries += 1;
}
return tries;
};
KaprekarsConstant(8593);
The while loop in the post keeps calculating the same value for num, so it it is not immediately 6174, the loop continues forever.
Basically the code is not following the algorithm for demonstrating Kaprekar's constant as shown on Wikipedia:
pad numbers of less than 4 digits with leading zeroes,
subtract the smaller number from the larger of { number, number with reversed digits), and
repeat from the step of extracting digits from the latest subtraction result.
Spoiler alert - here's a working example of a recursive function with the extra pieces of logic:
"use strict";
function KaprekarsConstant(num, tries=0) {
if( num == 6174) // Kaprekar's constant.
return tries;
if( num == 0) // degenerate case, digits are the same
return -tries;
var arr = [];
while (num > 0) {
arr.unshift(num % 10);
num = num / 10 | 0;
}
while( arr.length<4) { // leading zeroes as required
arr.unshift(0);
}
arr.sort();
var numOrdered = Number(arr.join(''));
var numReversed = Number(arr.reverse().join(''));
num = Math.abs( numOrdered - numReversed) // larger - smaller
return KaprekarsConstant( num, ++tries); // try again
};
// and test
function test() {
var num = Number(input.value);
if( Number.isNaN(num) || num < 1 || num > 9999) {
throw new Error("Enter number between 1 and 9999");
}
console.log("Tries = %s", KaprekarsConstant(num) );
}
<label> Enter 1 to 4 digit number: <input type="text" id="input"></label><br>
<button type="button" onclick="test()">Calculate tries</button>
While the answers do address your question, the solutions and the code are missing the part about leading zeros as in wiki Kaprekar's constant
and the whole solution is very simple
function KaprekarsConstant(num)
{
var tries=0;
var numOrdered =0;
var numRevesed=0;
while(num!=6174)
{
numOrdered=("0000" + num).substr(-4,4).split("").sort().join("");
numRevesed=numOrdered.split("").reverse().join("");
num = numRevesed-numOrdered;
tries+=1;
}
return tries;
}
KaprekarsConstant(8593);
To the reason for 'Why is it crashing?', its maybe due to Infinite Loop .
The response I got when I try to run your code
Possible infinite loop detected.
Error: Infinite loop
at KaprekarsConstant (script 19:68)
at script 27:1
Thank you everybody for the answers!!
Thanks to #Jaromanda X I realise the last while loop was infinite, since
num = numOrdered - numReversed;
will always be the same.
I realised I had to re-arrange the numbers every time so I create a function for that and incorporate it into the while loop.
I also added a bit of code from #traktor53 to add the leading zeros in case of a number with less than 4 digits.
And to finish I declare
var tries = 0;
inside the function so it will start from zero in each run.
.
.
Final result:
var numOrdered = 0;
var numReversed = 0;
function KaprekarsConstant(num) {
var tries = 0;
function order(num) { // function to order the numbers
var arr = [];
while (num > 0) {
arr.unshift(num % 10);
num = num / 10 | 0;
}
while(arr.length<4) { // leading zeroes as required
arr.unshift(0);
}
arr.sort();
numOrdered = Number(arr.join(''));
numReversed = Number(arr.reverse().join(''));
}
while (num !== 6174) {
order(num);
num = Math.abs(numOrdered - numReversed); // larger - smaller
tries += 1;
}
return tries;
};
KaprekarsConstant(8593);
I looked for a function to determine if a number is prime and found this
for (var i = 2; i <= Math.sqrt(num); i++)
if (num % i === 0) {
return false;
}
return true;
and I don't understand why that works, yet this doesn't
for (var i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) {
return false;
}
return true;
}
What is it about the (lack of the) block statement that is functioning differently
Your first code looks like this:
for (var i = 2; i <= Math.sqrt(num); i++){
if (num % i === 0) {
return false;
}
}
return true;
Notice how return true is on the outside. Your second code doesn't work because it prematurely returns true when there are more numbers to check. Your entire for loop is equivalent to
return num % 2 !== 0;
which is clearly incorrect.
Let me tell you something about blocks that you might not have known (It took me a while to discover this at least).
When you use a loop or if-else statement, you can ignore the using braces { and }.
Example 1
if (a === b){
c = 0;
}
is actually the same as
if (a === b)
c = 0;
Example 2
for (i = 0; i < 10; i++){
a += 1;
}
is actually the same as
for (i = 0; i < 10; i++)
a += 1;
However 1
if (a === b){
c = 0;
d = 1;
}
is not the same with
if (a === b)
c = 0;
d = 1;
However 2
for (i = 0; i < 10; i++){
a += 1;
b += 1;
}
is not the same with
for (i = 0; i < 10; i++)
a += 1;
b += 1;
Explanation
In loops and if-else statement, the block statement (codes surrounded by { and } groups the codes within it and execute it.
However, in the absence of { and }, the loops or if-else statement will only execute the single line of code after it.
Meaning,
var a = 0,
b = 0;
for (i = 0; i < 10; i++)
a += 1;
b += 1;
In this case, a === 10 but b === 1.
Also, in the following case,
var a = 0,
b = 0;
if (false)
a = 10;
b = 10;
a === 0 but b === 10.
I want to print the root of all numbers to 9999. How do I tell the program to skip the numbers that don't have a round root? Here's the code
let i=1;
for (i===1;i>=1 && i <10000;i++){
let b = Math.sqrt(i);
console.log(`${i} = ${b}`);
}
You can check if both the int value and the original value are same.
let i=1;
for (i=1;i>=1 && i <10000;i++){
let b = Math.sqrt(i);
if (Math.trunc(b) == b)
console.log(`${i} = ${b}`);
}
Instead of Math.trunc(b), you can use either of the following:
Math.round(b)
Math.floor(b)
Math.ceil(b)
parseInt(b, 10)
You don't need to iterate and test every number up to 10000. You can directly compute powers of two:
var count = 0, i = 0;
while (count < 10000) {
i++;
var b = i * i;
console.log(`${i} = ${b}`);
count = b;
}
Or as mentioned in comments you can do it elegantly with for-loop:
for (let i = 1; i*i < 10000; i++) {
console.log(`${i*i} = ${i}`);
}