Double countdown using recursion function? - javascript

I'm trying to write a recursion using JavaScript, without using global variables but i am not sure that the program can be possible like desire output.
Question is "Given a non-negative integer n, create a double countdown-pattern in the output."
Example:
If you ran doubleCountdown(5) you would also get the following output:
5
4
3
2
1
4
3
2
1
0
I have tried following ways:
In this way getting down to up output but not exact output:
double_countdown(5);
function double_countdown(n){
if(n == 0){
console.log(n);
return
}
console.log(n);
double_countdown(n-1);
console.log(n);
}
In this ways, i have used global for desired output but not standard way.
let second_n = 0;
let double_count =0;
double_countdown(5);
function double_countdown(n){
if(n == 0 && double_count == 0){
double_count = 1;
double_countdown(second_n-1);
console.log(n);
}
if(n == 0){
return
}else{
second_n +=1;
}
console.log(n);
double_countdown(n-1);
}

I would write the single countdown as a recursive function and have a double countdown function simply call it twice. This keeps all the parts simple.
const countdown = (s, e = 0) =>
s < e ? [] : [s, ...countdown (s -1, e)]
const doubleCountdown = (n) =>
[...countdown (n, 1), ...countdown (n - 1, 0)]
console .log (doubleCountdown (5))
You can then log the answer however you want for your homework. Perhaps something like for (let n of doubleCountdown (5)) {console .log (n)}

Implement the recursive function in a way that it keeps track of its recursion state by providing and working with more parameters than just the required first parameter (which is the current count down value).
Thus one would implement e.g. a function which is capable of running the count down cycle N times. And a double_countdown respectively countDownTwice function could be derived from such a generic implementation.
function countDownNTimes(value = 0, times = 1, initialValue) {
// initially invoked with an `undefined` value for `initialValue`.
initialValue ??= value;
console.log(value);
if (times >= 2) {
if (value <= 1) {
// does trigger a new recursion cycle with minimized boundaries.
countDownNTimes(initialValue - 1, --times, initialValue);
} else {
// stays within the current recursion of minimized boundaries.
countDownNTimes(--value, times, initialValue);
}
} else if ((times >= 1) && (value >= 1)) {
// stays within the current, final recursion of reastablished boundaries.
countDownNTimes(--value, times, initialValue);
}
}
const countDownTwice = value => countDownNTimes(value, 2);
console.log('... countDownTwice(5) ...');
countDownTwice(5);
console.log('... countDownNTimes(3, 3) ...');
countDownNTimes(3, 3);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Finally, after trying many times. I got the answer. If anything wrong then please help for more improve.
double_countdown(5);
function double_countdown(n,sc=0){
if(sc == 0) sc = n;
if(n == 0 ) return ;
console.log(n);
double_countdown(n-1,sc);
console.log(sc-n);
}

Related

How can I make this for loop iteration available inside the function for the if( condition ) with out repeating the function outcome n times as i?

I have a function which requires an Array iteration in order to set proper conditionals in the if statement, here's the code:
const code = reactive([] as string[])
for (let field = 0; field < props.length; field++) code.push('')
const inputs = reactive([] as HTMLInputElement[])
const focusOn = ref(0 as number | null)
onMounted(() => {
inputs[0].focus()
})
const nextInput = (): void => {
for (let i = 0; i < code.length; i++) {
console.log(code[i])
console.log(code)
if (
focusOn.value !== null &&
focusOn.value < props.length - 1 &&
code[i] !== ' ' &&
code[i] !== undefined
) {
inputs[focusOn.value + 1].focus()
}
}
}
You can ignore the console.log.
the problem I'm having is that the outcome ⇒ inputs[i + 1] is not
working as expected ⇒ stepping to the next input by 1, instead is
doing something like inputs[i +1] * 4 in every click ⇒ I assume it's
the number of iterations which by the way is 4, that's the
code.length.
focusOn.value ⇒ index number
What I'm trying to achieve is to iterate the code object[] in order to use its outcome as conditionals, but not to have it in the same scope as the return, so I can avoid returning the result x times as iterations.
I already tried numerous things, but I'm having an understanding level problem here. How can I solve this? Any help/suggestion is greatly appreciated!
btw, I just added more code to give you context that was clearly missing, my bad.

Recursive approach to Persistent bugger problem returns undefined

I've been trying to solve the following problem in codewars using recursion:
Write a function, persistence, that takes in a positive parameter num and returns its multiplicative persistence, which is the number of times you must multiply the digits in num until you reach a single digit.
For example (Input --> Output):
39 --> 3 (because 3*9 = 27, 2*7 = 14, 1*4 = 4 and 4 has only one digit)
999 --> 4 (because 9*9*9 = 729, 7*2*9 = 126, 1*2*6 = 12, and finally 1*2 = 2)
4 --> 0 (because 4 is already a one-digit number)
Here's what I've tried:
var numOfIterations = 0;
function persistence(num) {
//code me
var i;
var digits=[];
var result = 1;
if (num.toString().length==1) {
return numOfIterations;
} else {
numOfIterations++;
digits = Array.from(String(num), Number);
for (i=0;i<digits.size;i++) {
result=result*digits[i];
}
persistence(result);
}
}
But for some reason, instead of returning the number of iterations, it returns undefined. I've been told that I'm not using recursion correctly, but I just can't find the problem.
Other answers have explained what's wrong with your code. I just want to point out a simpler implementation:
const multiplyDigits = (n) =>
n < 10 ? n : (n % 10) * multiplyDigits (n / 10 | 0);
const persistence = (n) =>
n < 10 ? 0 : 1 + persistence (multiplyDigits (n));
[39, 999, 4] .forEach (t => console .log (`${t}:\t${persistence (t)}`));
multiplyDigits does just what it says, recursively multiplying the final digit by the number left when you remove that last digit (Think of | 0 as like Math .floor), and stopping when n is a single digit.
persistence checks to see if we're already a single digit, and if so, returns zero. If not, we add one to the value we get when we recur on the multiple of the digits.
I've been told that I'm not using recursion correctly
You're recursing, but you're not returning the result of that recursion. Imagine for a moment just this structure:
function someFunc() {
if (someCondition) {
return 1;
} else {
anotherFunc();
}
}
If someCondition is false, what does someFunc() return? Nothing. So it's result is undefined.
Regardless of any recursion, at its simplest if you want to return a result from a function then you need to return it:
function persistence(num) {
//...
if (num.toString().length==1) {
//...
} else {
//...
return persistence(result); // <--- here
}
}
As #David wrote in his answer, you were missing the return of the recursive call to itself.
Plus you were using digits.size instead of digits.length.
Anyway consider that one single digit being zero will collpse the game because that's enough to set the result to zero despite how many digits the number is made of.
To deal with the reset of numOfIterations, at first I tried using function.caller to discriminate between recursive call and direct call and set the variable accordingly. Since that method is deprecated as shown here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller
I opted for the optional argument iteration that gets set to zero as default, to keep track of that value while it goes down the call stack. This solution still fulfills the fact that the caller doesn't need to know a new interface for the function to work.
//var numOfIterations = 0;
function persistence(num, iteration=0) {
/*
Commented strategy using the function.caller
working but deprecated so I can't recommend anymore
used optional argument iteration instead
//gets the name of the caller scope
let callerName = persistence.caller?.name;
//if it's different from the name of this function
if (callerName !== 'persistence')
//reset the numOfIterations
numOfIterations = 0;
*/
var digits=[];
if (num.toString().length==1){
return iteration;
} else {
var result = 1;
digits = Array.from(String(num), Number);
for (let i=0;i<digits.length;i++) {
result = result * digits[i];
}
return persistence(result, iteration+1);
}
}
console.log( persistence(39) ); //-> 3
console.log( persistence(999 ) ); //-> 4
console.log( persistence(4) ); //-> 0
You can do something like this
const persistenceTailRecursive = (num, iterations = 0) => {
const str = '' + num;
if(str.length === 1){
return iterations;
}
return persistenceTailRecursive(str.split('').reduce((res, a) => res * parseInt(a), 1), iterations + 1)
}
const persistence = (num) => {
const str = '' + num;
if(str.length === 1){
return 0;
}
return 1 + persistence(str.split('').reduce((res, a) => res * parseInt(a), 1))
}
console.log(persistenceTailRecursive(93))
console.log(persistenceTailRecursive(999))
console.log(persistence(93))
console.log(persistence(999))
There are 2 versions
1 tailRecursive call the same method with the exact signature (preventing stackoverflow in some languages like scala)
2 basic the result is calculated at the end

javascript external called function does not return value [duplicate]

Im solving a codewars problem and im pretty sure i've got it working:
function digital_root(n) {
// ...
n = n.toString();
if (n.length === 1) {
return parseInt(n);
} else {
let count = 0;
for (let i = 0; i < n.length; i++) {
//console.log(parseInt(n[i]))
count += parseInt(n[i]);
}
//console.log(count);
digital_root(count);
}
}
console.log(digital_root(942));
Essentially it's supposed to find a "digital root":
A digital root is the recursive sum of all the digits in a number.
Given n, take the sum of the digits of n. If that value has two
digits, continue reducing in this way until a single-digit number is
produced. This is only applicable to the natural numbers.
So im actually getting the correct answer at the end but for whatever reason on the if statement (which im watching the debugger run and it does enter that statement it will say the return value is the correct value.
But then it jumps out of the if statement and tries to return from the main digital_root function?
Why is this? shouldn't it break out of this when it hits the if statement? Im confused why it attempt to jump out of the if statement and then try to return nothing from digital_root so the return value ends up being undefined?
You're not returning anything inside else. It should be:
return digital_root(count);
^^^^^^^
Why?
digital_root is supposed to return something. If we call it with a one digit number, then the if section is executed, and since we return from that if, everything works fine. But if we provide a number composed of more than one digit then the else section get executed. Now, in the else section we calculate the digital_root of the count but we don't use that value (the value that should be returned). The line above could be split into two lines of code that makes it easy to understand:
var result = digital_root(count); // get the digital root of count (may or may not call digital_root while calculating it, it's not owr concern)
return result; // return the result of that so it can be used from the caller of digital_root
Code review
My remarks is code comments below
// javascript generally uses camelCase for function names
// so this should be digitalRoot, not digital_root
function digital_root(n) {
// variable reassignment is generally frowned upon
// it's somewhat silly to convert a number to a string if you're just going to parse it again
n = n.toString();
if (n.length === 1) {
// you should always specify a radix when using parseInt
return parseInt(n);
} else {
let count = 0;
for (let i = 0; i < n.length; i++) {
//console.log(parseInt(n[i]))
count += parseInt(n[i]);
}
// why are you looping above but then using recursion here?
// missing return keyword below
digital_root(count);
}
}
console.log(digital_root(942));
Simple recursive solution
With some of those things in mind, let's simplify our approach to digitalRoot...
const digitalRoot = n =>
n < 10 ? n : digitalRoot(n % 10 + digitalRoot((n - n % 10) / 10))
console.log(digitalRoot(123)) // => 6
console.log(digitalRoot(1234)) // 10 => 1
console.log(digitalRoot(12345)) // 15 => 6
console.log(digitalRoot(123456)) // 21 => 3
console.log(digitalRoot(99999999999)) // 99 => 18 => 9
Using reduce
A digital root is the recursive sum of all the digits in a number. Given n, take the sum of the digits of n. If that value has two digits, continue reducing in this way until a single-digit number is produced. This is only applicable to the natural numbers.
If you are meant to use an actual reducing function, I'll show you how to do that here. First, we'll make a toDigits function which takes an integer, and returns an Array of its digits. Then, we'll implement digitalRoot by reducing those those digits using an add reducer initialized with the empty sum, 0
// toDigits :: Int -> [Int]
const toDigits = n =>
n === 0 ? [] : [...toDigits((n - n % 10) / 10), n % 10]
// add :: (Number, Number) -> Number
const add = (x,y) => x + y
// digitalRoot :: Int -> Int
const digitalRoot = n =>
n < 10 ? n : digitalRoot(toDigits(n).reduce(add, 0))
console.log(digitalRoot(123)) // => 6
console.log(digitalRoot(1234)) // 10 => 1
console.log(digitalRoot(12345)) // 15 => 6
console.log(digitalRoot(123456)) // 21 => 3
console.log(digitalRoot(99999999999)) // 99 => 18 => 9
its a recursive function the code should be somewhat like this
function digital_root(n) {
// ...
n=n.toString();
if(n.length === 1){
return parseInt(n);
}
else
{
let count = 0;
for(let i = 0; i<n.length;i++)
{
//console.log(parseInt(n[i]))
count+=parseInt(n[i]);
}
//console.log(count);
return digital_root(count);
}
}
you should return the same function instead of just calling it to get the correct call stack

Multiplicative Persistence program in Javascript not working

I can't get my program to work. The problem is a kata from Codewars:
Write a function, persistence, that takes in a positive parameter num and returns its multiplicative persistence, which is the number of times you must multiply the digits in num until you reach a single digit.
Example:
persistence(39) === 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit
persistence(999) === 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2
persistence(4) === 0 // because 4 is already a one-digit number
I've gone through answers to similar problems here already. This is my code:
var count = 0;
var product = 1;
function persistence(num) {
if (num.toString().length == 1) {
count+=0;
return count;
}
for (i of num.toString()) {
product *= Number(i);
}
count++;
var newProduct = product;
// reset product to 1 so that line ten does not
// start with the product from the last loop
product = 1;
persistence(newProduct);
}
I can't tell what the problem is. Initially I was getting a maximum call stack exceeded error. I researched that and realized I did this for my base case:
if (num.length == 1) {
count+=0;
return count;
}
instead of
if (num.toString().length == 1) {
count+=0;
return count;
}
My logic seems sound. What could the problem be?
Here's a much better way of solving your problem, complete with comments that I think gives a pretty clear explanation of what's going on.
function persistence(num) {
// Create a new function that you'll use inside your main function
function multiply(n) {
// Multiply the first number by next number in the array
// until the entire array has been iterated over
return n.reduce(function(a,b){return a*b;});
}
// Set the count to 0
var count =0;
// Use a while loop to iterate the same number of times
// as there are digits in num
while (num.toString().length > 1) {
// Splits the num into an array
num= num.toString().split("");
// Runs multiply on our num array and sets num to the returned
// value in preparation of the next loop.
// The multiply function will for 39 run 3 * 9 = 27,
// next iteration we've set num to 27 so multiply will be
// 2 * 7 = 14, then 1 * 4 = 4, and since num 4 now
// has a length <= 1 the loop stops.
num = multiply(num);
// Increase count by 1 each iteration, then run the next
// iteration in the loop with the new value for num being
// set to the result of the first multiplication.
count++;
}
return count; // return the value of count
}
console.log(persistence(39));// === 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit
console.log(persistence(999));// === 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2
console.log(persistence(4));// === 0 // because 4 is already a one-digit number
https://jsfiddle.net/8xmpnzng/
Use "of" instead of "in". "in" looks for properties. "of" increments an array.
var count = 0;
var product = 1;
function persistence(num) {
if (num.toString().length == 1) {
count+=0;
return count;
}
for (i of num.toString()) {
product *= Number(i);
}
count++;
var newProduct = product;
// reset product to 1 so that line ten does not
// start with the product from the last loop
product = 1;
persistence(newProduct);
}
I'm pretty sure it's this block:
for (i in num.toString()) {
product *= Number(i);
}
That's a for...in loop, which is used to iterate over keys in an object. If you want to multiply each digit of the num string together, you could split the string into an array, and use the reduce method (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce):
//this coerces the number into a string
const numString = num + ''
//this is the function to pass as the first argument into the reduce method
const multiplyAll = (accumulator, currentVal) => accumulator * Number(currentVal)
let product = numString.split('').reduce(multiplyAll, 1)
It's generally best practice to avoid declaring global variables outside of a function's scope, but you can do a cool trick with your recursion where you declare your count as a parameter in your function like so:
function persistence(num, count = 0) {
And then when you call it again with recursion, you simply add 1 like so:
function persistence(product, count + 1) {
Simpler way of Persistence:
let countIteration = 1;
function persistence(num) {
let numStr = num.toString();
if(numStr.toString().length === 1) {
return 0;
}
let numArr = numStr.split("");
let persistRes = numArr.reduce((acc, curr) => acc = curr * acc);
if (persistRes.toString().length !== 1) {
countIteration += 1;
return persistence(persistRes);
}
else {
return countIteration;
}
}
console.log(persistence(39)); // === 3
console.log(persistence(15)); // === 1
console.log(persistence(999));// === 4

Javascript recursive function not returning value?

Im solving a codewars problem and im pretty sure i've got it working:
function digital_root(n) {
// ...
n = n.toString();
if (n.length === 1) {
return parseInt(n);
} else {
let count = 0;
for (let i = 0; i < n.length; i++) {
//console.log(parseInt(n[i]))
count += parseInt(n[i]);
}
//console.log(count);
digital_root(count);
}
}
console.log(digital_root(942));
Essentially it's supposed to find a "digital root":
A digital root is the recursive sum of all the digits in a number.
Given n, take the sum of the digits of n. If that value has two
digits, continue reducing in this way until a single-digit number is
produced. This is only applicable to the natural numbers.
So im actually getting the correct answer at the end but for whatever reason on the if statement (which im watching the debugger run and it does enter that statement it will say the return value is the correct value.
But then it jumps out of the if statement and tries to return from the main digital_root function?
Why is this? shouldn't it break out of this when it hits the if statement? Im confused why it attempt to jump out of the if statement and then try to return nothing from digital_root so the return value ends up being undefined?
You're not returning anything inside else. It should be:
return digital_root(count);
^^^^^^^
Why?
digital_root is supposed to return something. If we call it with a one digit number, then the if section is executed, and since we return from that if, everything works fine. But if we provide a number composed of more than one digit then the else section get executed. Now, in the else section we calculate the digital_root of the count but we don't use that value (the value that should be returned). The line above could be split into two lines of code that makes it easy to understand:
var result = digital_root(count); // get the digital root of count (may or may not call digital_root while calculating it, it's not owr concern)
return result; // return the result of that so it can be used from the caller of digital_root
Code review
My remarks is code comments below
// javascript generally uses camelCase for function names
// so this should be digitalRoot, not digital_root
function digital_root(n) {
// variable reassignment is generally frowned upon
// it's somewhat silly to convert a number to a string if you're just going to parse it again
n = n.toString();
if (n.length === 1) {
// you should always specify a radix when using parseInt
return parseInt(n);
} else {
let count = 0;
for (let i = 0; i < n.length; i++) {
//console.log(parseInt(n[i]))
count += parseInt(n[i]);
}
// why are you looping above but then using recursion here?
// missing return keyword below
digital_root(count);
}
}
console.log(digital_root(942));
Simple recursive solution
With some of those things in mind, let's simplify our approach to digitalRoot...
const digitalRoot = n =>
n < 10 ? n : digitalRoot(n % 10 + digitalRoot((n - n % 10) / 10))
console.log(digitalRoot(123)) // => 6
console.log(digitalRoot(1234)) // 10 => 1
console.log(digitalRoot(12345)) // 15 => 6
console.log(digitalRoot(123456)) // 21 => 3
console.log(digitalRoot(99999999999)) // 99 => 18 => 9
Using reduce
A digital root is the recursive sum of all the digits in a number. Given n, take the sum of the digits of n. If that value has two digits, continue reducing in this way until a single-digit number is produced. This is only applicable to the natural numbers.
If you are meant to use an actual reducing function, I'll show you how to do that here. First, we'll make a toDigits function which takes an integer, and returns an Array of its digits. Then, we'll implement digitalRoot by reducing those those digits using an add reducer initialized with the empty sum, 0
// toDigits :: Int -> [Int]
const toDigits = n =>
n === 0 ? [] : [...toDigits((n - n % 10) / 10), n % 10]
// add :: (Number, Number) -> Number
const add = (x,y) => x + y
// digitalRoot :: Int -> Int
const digitalRoot = n =>
n < 10 ? n : digitalRoot(toDigits(n).reduce(add, 0))
console.log(digitalRoot(123)) // => 6
console.log(digitalRoot(1234)) // 10 => 1
console.log(digitalRoot(12345)) // 15 => 6
console.log(digitalRoot(123456)) // 21 => 3
console.log(digitalRoot(99999999999)) // 99 => 18 => 9
its a recursive function the code should be somewhat like this
function digital_root(n) {
// ...
n=n.toString();
if(n.length === 1){
return parseInt(n);
}
else
{
let count = 0;
for(let i = 0; i<n.length;i++)
{
//console.log(parseInt(n[i]))
count+=parseInt(n[i]);
}
//console.log(count);
return digital_root(count);
}
}
you should return the same function instead of just calling it to get the correct call stack

Categories

Resources