Sum of Digits works in console but not when returned - javascript

So I'm doing a codewars challenge and I have no clue why my code isn't working. I'm a beginner so please don't hate on me.
This is my code:
function digital_root(n) {
let str = n.toString()
let arr = []
let sum = 0
for (let i = 0; i < str.length; i++) {
arr.push(str.charAt(i))
}
for (let i = 0; i < str.length; i++) {
sum += Number(arr[i])
}
let sumStr = sum.toString()
if (sumStr.length > 1) {
digital_root(sum)
} else if (sumStr.length == 1) {
return sum
}
}
It works when I console.log it but not when I return the value. I'm trying to learn recursion. Thanks for the help!

You need to return digital_root(sum) too, if sumStr.length > 1 in order to access recursive returned value.
you have to write return digital_root(sum) instead of just digital_root(sum).
check below:
function digital_root(n) {
let str = n.toString()
let arr = []
let sum = 0
for (let i = 0; i < str.length; i++) {
arr.push(str.charAt(i))
}
for (let i = 0; i < str.length; i++) {
sum += Number(arr[i])
}
let sumStr = sum.toString()
if (sumStr.length > 1) {
return digital_root(sum)
} else if (sumStr.length == 1) {
return sum
}
}
console.log("Digital Root :", digital_root('123456789'));

Ok, it seems you are missing dealing with the return value of digital_root when you call it recursively. See added "return" statement below.
function digital_root(n) {
let str = n.toString()
let arr = []
let sum = 0
for (let i = 0; i < str.length; i++) {
arr.push(str.charAt(i))
}
for (let i = 0; i < str.length; i++) {
sum += Number(arr[i])
}
let sumStr = sum.toString()
if (sumStr.length > 1) {
// ***** You need to deal with the return value of digital_root when you call it.
return digital_root(sum)
} else if (sumStr.length == 1) {
return sum
}
}

However, while JavaScript's functional coding style does support recursive functions, we need to be aware that most JavaScript compilers are not currently optimized to support them safely. Recursion is best applied when you need to call the same function repeatedly with different parameters from within a loop.
Please read this,
https://www.sitepoint.com/recursion-functional-javascript/#:~:text=However%2C%20while%20JavaScript's%20functional%20coding,parameters%20from%20within%20a%20loop.

Related

why my code doesn't work when I am trying to concatenate a function's return value with a string?

So, in this code I have a string of 0's and 1's and the length of the string is 32, which will be split in 6 equal parts but the last part will have the length of 2 so I will add (4) 0's after that which will make its length 6. So I wrote a function that will add the remaining 0's which is padding(num).
And that function will be invoked in side the slicing(str) function.
But the code breaks when I try to do execute.
Any help?
Thanks.
// This code works.
function padding0s(num) {
let s = "";
for (i = 0; i < 6 - num; i++) {
s += "0";
}
return s;
}
function slicing(str) {
let k = 6;
let res = [];
let temp1 = 0;
let f = padding0s(2);
for (i = 0; i < str.length; ) {
res.push(str.slice(i, k));
i += 6;
k += 6;
if (res[temp1].length !== 6) {
res[temp1] += f;
}
temp1++;
}
console.log(res);
}
slicing("01000011010011110100010001000101");
// But this does not..
function padding0s(num) {
let s = "";
for (i = 0; i < 6 - num; i++) {
s += "0";
}
return s;
}
function slicing(str) {
let k = 6;
let res = [];
let temp1 = 0;
for (i = 0; i < str.length; ) {
res.push(str.slice(i, k));
i += 6;
k += 6;
if (res[temp1].length !== 6) {
let f = padding0s(res[temp1].length);
res[temp1] += f;
}
temp1++;
}
console.log(res);
}
slicing("01000011010011110100010001000101");
Always define variables before using them
Not doing so can result in undefined behaviour, which is exactly what is happening in your second case. Here is how:
for (i = 0; i < str.length; ) {...}
// ^ Assignment to undefined variable i
In the above for-loop, by using i before you define it, you are declaring it as a global variable. But so far, so good, as it doesn't matter, if not for this second problem. The real problem is the call to padding0s() in your loop. Let's look at padding0s:
function padding0s(num) {
...
for (i = 0; i < 6 - num; i++) {
s += "0";
}
}
This is another loop using i without defining it. But since i was already defined as a global variable in the parent loop, this loop will be setting its value. So in short, the value of i is always equal to 6 - num in the parent loop. Since your exit condition is i < str.length, with a string of length 32 the loop will run forever.
You can get around this in many ways, one of which you've already posted. The other way would be to use let i or var i instead of i in the parent loop. Even better is to write something like this (but beware that padEnd may not work on old browsers):
function slicing(str) {
return str.match(/.{1,6}/g).map((item) => {
return item.padEnd(6, "0");
});
}
console.log(slicing("01000011010011110100010001000101"));

how to resolve sum of prime-indexed elements?

Good morning, am getting stuck with this kata, anyone can explain me ?
In this kata i have to return the sum of elements occupying prime-numbered indices.
I started my code like that, but didn't know what to do next. THANK YOU in advance.
function total(arr) {
for (let i = 2; i < arr.length; i++) {}
};
Please use ; after breaking condition which is i < arr.length here for (let i = 2; i < arr.length, i++) {}
You can loop over arr the way you are doing here and validate if index at which you are looping is prime itself.
If 2nd step is met you can add the value into summation var sum
return sum.
Please follow this thread to find know more about calculating if value is prime. Number prime test in JavaScript
function isPrime(num) {
for(var i = 2; i < num; i++)
if(num % i === 0) return false;
return num > 1;
}
function total(arr) {
var sum = 0;
for (let i = 2; i < arr.length; i++) {
if(isPrime(i)) {
sum = sum + arr[i]
}
}
return sum;
}

How to avoid my permutation algorithm of ERROR:heap out memory

Today I try to solve a problem on codewars,it requires me give the permutations of a given string.
Firstly,I try to use a recursion function looks like:
function permutate(str) {
var result = [];
if (str.length == 1) {
return [str]
} else {
var preResult = permutate(str.slice(1));
for (var j = 0; j < preResult.length; j++) {
for (var k = 0; k < preResult[j].length + 1; k++) {
var temp = preResult[j].slice(0, k) + str[0] + preResult[j].slice(k);
result.push(temp);
}
}
return result;
}
}
After I click the attemp button,the OJ tells me there is an error caused by heap out memory.Because my function called with a long string:"abcdefghijkl".
Secondly,I rewrite my function by using loop.just like:
function perm(str) {
let result = [],tempArr = [];
let subStr = str;
while (subStr.length !== 0) {
if (result.length === 0) {
result.push(str[0]);
} else {
for (let i = 0; i < result.length; i++) {
let item = result[i];
let itemLen = item.length;
for (let j = 0; j < itemLen+1; j++) {
let temp = item.slice(0, j) + subStr[0] + item.slice(j);
tempArr.push(temp);
}
}
result = tempArr;
tempArr = [];
}
subStr = subStr.slice(1);
}
return result;
}
It works when the given string is short.But still cause Error.
So,I want to know why cause this error and if there is a permutation algorithm can run in Node(v6.11.0) without memory error?
I searched a lot and tried many methods,but nothing works.So I ask my first question on stackoverflow,hoping you can give me some help.Thanks!
Try the module https://github.com/miguelmota/permutations, or even try to use the code from the module
In addition to previous answer as a possible try out, you can try to increase process max memory limit size, for example with node --max-old-space-size=8192 which is in bytes, the node process will run with extended 8GB memory limit.

How to add a counter to this loop?

I'm a javascript newbie working on a hangman game, I had everything working properly until I realized that my method for comparing my guess to the answer was unable to handle words with multiple letters. I've written a new loop that takes care of this, but that's led to a new problem: I don't know how to work in a counter to keep track of wrong guesses.
This is the loop that I have:
function checkGuess(guess, array) {
for (let i = 0; i < array.length; i++) {
let found = false;
for (let j = 0; j < array.length; j++) {
if (array[i] === guess) {
found = true;
}
}
if (found) {
results += answer[i];
}
}
}
The game will end when the number of wrong guesses reaches a certain count or when results.length = answer.length but I can't figure out how to handle wrong guesses. Any tips would be appreciated.
try this, create a function that return the number of places that the guess exists
function checkGuess(guess, array) {
let found = 0;
for (let i = 0; i < array.length; i++) {
if (array[i] === guess) {
found++;
}
}
return found;
}
then use 2 vars to hold the correct guess and the wrong guess
var correct = 0, wrong = 0
then every time the user is guessing, do the following:
var check = checkGuess(guess, question);
if (check > 0) {
correct += check;
} else {
wrong++;
}
to determine if win or lose
if (wrong >= 3) {
// set it to lose
}
if (correct == question.length) {
// set it to win
}
Is this maybe what you're looking for?
var wrongGuesses = 0;
function checkGuess(guess, array) {
for (let i = 0; i < array.length; i++) {
let found = false;
let go_time = false;
for (let j = 0; j < array.length; j++) {
if (array[i] === guess) {
found = true;
results += answer[i];
}
if(j===(array.length-1)){
go_time = true;
}
}
if (go_time===true&&found!==true) {
wrongGuesses++;
}
}
}

How to analyse complexity of an Algorithm that contains hidden loops made by external function or method?

First of all, I would like to apologize in case my title is not concise as it should be, but my point is, if you take a look at the following code which is selection sort algorithm, it's obvious for someone to analyze its complexity.
module.exports = function (arr) {
var temp;
for (var i = 0; i < arr.length; i++) {
var iTh = i;
for (var j = i+1; j < arr.length; j++) {
if (arr[j] < arr[iTh]) {
iTh = j;
}
}
temp = arr[i];
arr[i] = arr[iTh];
arr[iTh] = temp;
}
return arr;
}
But what if an algorithm contains hidden loops which are provided by particular language's functions or methods. For instance these two functions are both reversing a string, and they have JavaScript methods which have complexity behind them too.
So! How can someone analyze the complexity of these two and pick the optimal one? Or they don't qualify to be algorithms?
First Reverse
exports.reverse1 = function (str) {
if (str == undefined || str.length) {
return 0;
}
let collector = [];
for (var i = str.length; i >= 0; i--) {
collector.push(str.charAt(i));
}
return collector.join("");
}
Second Reverse
exports.reverse2 = function (str) {
if (str == undefined || str === "") {
return 0;
}
return str.split("").reverse().join("");
}

Categories