Reputation: 11
So I am currently in prep-course and a lot of the possible leetcode problems we are going to have during the exam are to do with things like factorials and numbers.
For instance this is one of the problems
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:
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
Now my question is I know that we can use something like this
var arr = num.toString().split('');
And this will give us the arr of strings, and we can simply call something like this in the loop
for (var i = 0; i < arr.length; i++) {
var currentNum = Number(arr[i]);
}
But I am struggling to figure out how I would implement maybe a while loop or some conditional to continue the loop through the problem.
For instance in this case 39 would become
39-> 3*9 | (27) 27-> 2*7 | (14) 14-> 1*4
However im struggling to work through how to actually do the continuous loop. Like if it where just to do one loop I can do that, but the recursion is where I am lost.
If anyone could walk me through this with some level of detail it would be really helpfull, thanks!
Upvotes: 1
Views: 92
Reputation: 1577
You seemed to be on the right track with the while loop so thats what I used. I'll add more comments to this code on "edits" after I post.
function p(n) {
// n = n.toString();
// v = n;
var cnt = 0;
var v = n.toString();
while (v.length > 1) {
var digits = v.split('');
var product = 1;
for (var i = 0; i < digits.length; i++) {
product *= parseInt( digits[i] );
}
v = product.toString();
cnt++;
}
// This line returns the final value, not the "count" or "persistence"
// return parseInt(v);
// This line (edit) returns the "persistence"
return cnt;
}
console.log( p(999) );
console.log( p(39) );
console.log( p(4) );
Basically what's at work here is n
is converted to a string in case it arrived as a number. Next the while
loop continues so long as v
length is more than one, so really you could just set v = n.toString()
there, same difference.
Now if v's length is more than 1 than likewise, v is not less than 10. So the loop continues until that happens with the rest of the logic inside the loop.
v
is a string so it's split into digits as you suggested in your question.
product
starts out as 1
as opposed to 0
because of obvious reasons. The digits are multiplied together via the for loop.
Then that product becomes the new v
so that the loop can either iterate again, or terminate based on the while
condition.
Upvotes: 1
Reputation: 4337
I'm betting some things might look fancy to you, but as a fellow javascript user, u gotta learn to do straightfoward solutions
function persistence(num){
var numArr = num.toString().split``; //only these quotes skip out the brackets for functions. eg: functionName('abc'+varName) is the same as functionName`abc${varName}`
var ans = 0;
while(numArr.length > 1){
var newNum = 1;
numArr.forEach((a,i)=>{newNum *= a}); //this is basically a for loop structure for arraays. a is the element, i is the index. "1" is the same as 1 when it comes to multiplication, division and subtraction (NOT ADDITION)
numArr = newNum.toString().split``;
ans++;
}
return(ans);
}
//solution examples
console.log(persistence(999));
console.log(persistence(81));
console.log(persistence(4));
console.log(persistence(39));
//yes, it looks simple and straightfoward... ur welcome
Upvotes: 0
Reputation: 1381
Here is a quick solution. Hope it helps!
function p(num){
var new_num = 1,
sNumber = num.toString(),
len = sNumber.length,
counter = 0;
while(len > 1) {
counter = counter + 1;
for (var i = 0; i < len; i += 1) {
new_num = new_num * parseInt(sNumber.charAt(i));
}
sNumber = new_num.toString();
len = sNumber.length;
new_num=1;
}
return counter;
}
console.log(p(39));
console.log(p(999));
console.log(p(4));
Upvotes: 1
Reputation: 2388
In case you're interested in a recursive version:
function p(input){
const v = input.toString();
if(v.length<=1){
return 0;
}
let product = 1;
for(var i=0;i< v.length;i++)
{
product *= parseInt(v[i]);
}
return p(product)+1;
}
console.log(p(999));
console.log(p(39));
console.log(p(4));
Upvotes: 1
Reputation: 4519
You could make a function that will perform multiplication and then call it each time the number is bigger than 10
function getper(n){
var arr = n.toString().split('');
i=1
res= multi(arr)
do{
if(res>10) {
na= res.toString().split('')
res=multi(na)
if(res<10){
i=-1
}
else i++
}
else i=-1
}while(i>0)
return res
}
console.log(getper(39))
console.log(getper(999));
console.log(getper(4));
function multi(arr){
return arr.reduce((acc,curr)=>{
return acc*curr
})
}
Upvotes: 0