Counting zeros in a recursive manner - javascript

I am trying to count TRAILING zeros from a recursive manner. Basically I split the final recursive result and then created a var counter that will count all the zeros.
function countingZeros(n) {
if (n < 0) {
// Termination condition to prevent infinite recursion
return;
}
// Base case
if (n === 0) {
return 1;
}
// Recursive case
let final = n * countingZeros(n -1);
let counter = 0;
String(final).split('').forEach(function(item){
item === 0 ? counter++ : counter;
});
return counter;
}
countingZeros(12) // => suppose to output 2 since there are 2 trailing zeros from 479001600 but got 0
countingZeros(6) // => suppose to get 1 since 720 is the final result.
I am expecting to get 2 in return as the counter must return but instead I got 0. Any idea what am I missing on my function? How should I fix it?

I think you're working too hard. First of all, in response to a comment, you don't actually need to calculate the factorial, since all you really need is to count factors of 5 and of 2. And since there are many more factors of 2, your real answer is just counting factors of 5. But each factor of 5 must be a factor of one of {1, 2, 3, ... n}, so we just have to add up the highest powers of five that evenly divide into each of {1, 2, 3, ... n}.
We can do that with some simple recursion:
const fiveFactors = (n, acc = 0) => (n % 5 == 0)
? fiveFactors(n / 5, acc + 1)
: acc
const factZeros = (n, acc = 0) => (n > 0)
? factZeros(n - 1, acc + fiveFactors(n))
: acc
factZeros(1000) //=> 249
Note that both functions are eligible for tail-call optimization.
Also, although this does involve a double recursion, it's not really ill-performant. Four out of five times, the internal recursion stops on the first call, and of the remainder, four out of five stop on the second call, and so on.

You are trying to count the number of zeroes using string functions(i will assume, you forgot to include the factorial method. Correct flow could have been- you first pass the input to a factorial method and pass output from factorial method to countingZeros method). Anyways as stated already in other answer, you don't really need to calculate the factorial product to count the trailing zeroes.
Here a sample to count the number of trailing zeroes in n!
temp = 5;
zeroes = 0;
//counting the sum of multiples of 5,5^2,5^3....present in n!
while(n>=temp){
fives = n/temp;
zeroes = zeroes + fives;
temp = temp*5;
}
printf("%d",zeroes);
Note that each multiple of 5 in the factorial product will contribute 1 to the number of trailing zeros. On top of this, each multiple of 25 will contribute an additional 1 to the number of trailing zeros. Then, each multiple of 125 will contribute another 1 to the number of trailing zeros, and so on.
Here's a great link to understand the concept behind this:
https://brilliant.org/wiki/trailing-number-of-zeros/

Related

Javascript: How to recursively return a counter?

In the example below, I don't want to make a counter as a param. Rather, I just want to return '+ 1' each time so that what gets returned is the number of steps it takes. My issue lies with the base case. If I do return + 1, I get the correct number of steps plus one additional step so I tried just return but that delivers NaN. Is it even possible?
var numberOfSteps = function(num) {
if (num == 0) {
return;
} else {
if (num % 2 == 0) {
return 1 + numberOfSteps(num/2);
} else {
return 1 + numberOfSteps(num - 1);
}
}
};
edit : The goal is to track how many steps it takes to reduce a number to 0. If it's even, divide by 2 or else subtract by 1. Ultimately, I want to return the number of steps it takes for any given number to get reduced to 0 following those rules
I hope the point has gotten through in the long comment thread and other answers that return + 1 is equivalent to return (+1), that is, return the integer positive one. And since there are no steps to take once you've reached zero, +1 is the wrong answer. Similarly, a plain return is functionally equivalent to return undefined. But undefined is not a number, and you're going to run into problems if you later try to add 1 to it. So the solution from the comments or other answers to return the correct number of steps, which in this case 0, will fix your code.
I would like to point out another way to solve this, though:
const numberOfSteps = (n) =>
n <= 0
? 0
: 1 + numberOfSteps (n % 2 == 0 ? n / 2 : n - 1)
console .log (numberOfSteps (12))
There are superficial differences here from the other solutions, such as using an arrow function, using a conditional statement (ternary) rather than if-statements, and using <= 0 instead of < 0 to avoid possible infinite loops on negative numbers.
But the fundamental difference is that this code only has one recursive branch. I think this is a better match to the problem.
We can think of this as a function which answers "How many steps does it take to reach 0 from our input number if each step cuts even numbers in half and subtracts one from odd ones?" Well that logically leads to a base case (we're already at 0) so have to return 0, and a recursive one (we're at some positive integer) so have to add 1 to the total steps required from our next entry.
By doing this single recursive call and adding one to the result, we make it clearer what the recursion is doing.
If this is unclear, then this alternative might show what I mean:
const takeStep = (n) =>
n % 2 == 0 ? n / 2 : n - 1
const numberOfSteps = (n) =>
n <= 0
? 0
: 1 + numberOfSteps (takeStep (n))
Think you just need to return 0 when it's...zero.
var numberOfSteps = function(num) {
if (num == 0) {
return 0;
} else {
if (num % 2 == 0) {
return 1 + numberOfSteps(num/2);
} else {
return 1 + numberOfSteps(num - 1);
}
}
}
return + 1 maybe doesn't do what you think it does: it returns the number 1. + here means positive not negative, there is no addition or subtraction going on. It will also give you one too many steps.
return; by itself returns undefined, which when converted to a Number, translates to NaN, because, well, it's not a number.

Round number down to nearest power of ten

I have a number and I need to round it down to the nearest power of ten. It seems like this should be possible without a whole bunch of if statements or using recursion or looping, but I don't know the most elegant way to do it. In case it's unclear what I mean, here are some examples:
f(1) === 1
f(5) === 1
f(15) === 10
f(43) === 10
f(456) === 100
f(999) === 100
To clarify: I do not need nearest multiple of 10 (not: 10, 20, 30...), but nearest power of ten (10, 100, 1000...).
Edit: To my knowledge this is not a duplicate question. Please stop closing as a duplicate of a question asking about rounding to the nearest multiple of ten. This question is unrelated to the linked question, because it asks about rounding to the nearest power of ten. If you would like to close this question as a duplicate, please find and link a duplicate question. The question which is currently linked was commented about 30 seconds after I posted the question, by someone who did not read the entire question and merely commented complaining about it being a duplicate. That person has since deleted his comments (after realizing he was wrong), although you can see comments by myself and someone else both pointing out that this is not a duplicate.
You could take the logarithm of 10 and take the integer value for the power of 10.
function f(v) {
return Math.pow(10, Math.floor(Math.log10(v)));
}
console.log(f(1)); // 1
console.log(f(5)); // 1
console.log(f(15)); // 10
console.log(f(43)); // 10
console.log(f(456)); // 100
console.log(f(999)); // 100
Simply get the length of the number(by converting Number into a string) and then generate the result by taking the power of 10(where the exponent is length - 1).
function generateNum(v) {
return Math.pow(10, v.toString().length - 1);
}
var data = [1, 5, 15, 43, 456, 456, 999];
data.forEach(function(v) {
console.log(generateNum(v));
})
function generateNum(v) {
return Math.pow(10, v.toString().length - 1);
}
FYI : In case number includes decimal part then you need to avoid decimal part by taking the floor value.
function generateNum(v) {
return Math.pow(10, Math.floor(v).toString().length - 1);
}
Here's a variant that works for negative numbers:
let round10 = v => Math.pow(10, Math.floor(Math.log10(Math.abs(v)))) * Math.pow(-1, v < 0);
You can do it in the following way
function f(num){
let count = 0;
while(num > 1){
count ++;
num/= 10;
}
return Math.pow(10, count-1) * (Math.round(num) ? 10: 1);
}
console.log(f(453));
f = n => +("1"+"0".repeat((""+n).length-1));
or:
f = n => +(""+n).split("").map((_,i)=>i?"0": "1").join("");

Find number of pairs with difference larger than or equal to given number

I have a array/dict(HashMap) of positive integers.
I need to find the number of pairs that have a absolute difference greater or equal to a given number, K.
import random
import time
#given number
k = 4
# List of 2,00,000 random numbers in range 0-1000
strength = [random.randrange(0,1000) for x in range(200000)]
strength.sort()
# start clock
start1 = time.clock()
n = len(strength)
# count keeps track of number of pairs found
count = 0
for x in range(n):
for y in range(x,n):
if abs(strength[x] - strength[y]) >= k:
# if found, all number from this point to the end will satisfy
count += n-y
# So no need to go to the end
break
end1 = time.clock()
print(count)
print(end1-start1)
All the answers I find are for pairs less than or equal to a given number.
I need to find the number of pairs that have a absolute difference greater or equal to a given number, K.
Note that the total number of pairs is n * (n - 1) / 2, so if you can find the number of pairs with difference less than K, the number of pairs with difference greater than K is just n * (n - 1) / 2 - num_pairs_with_diff_less_than_K
The solution you provide is also correct (and well documented). If your question is how to adapt it to your case, then all you need to do is to use values of your HashMap (sorted) instead of the strength array.
You can get the 2 item combinations of the array and then filter / reduce them according to the difference.
One might do the job in JavaScript as follows;
Array.prototype.combinations = function(n){
return this.reduce((p,c,i,a) => p.concat(n > 1 ? a.slice(i+1).combinations(n-1).map(e => (e.push(c),e))
: [[c]]),[]);
};
function getAcordingToDiff(a,d){
return a.combinations(2)
.reduce((p,c) => Math.abs(c[0]-c[1]) >= d ? (p.push(c),p) : p ,[]);
}
var arr = Array(30).fill().map((_,i) => i+1); // array from [1,...,30]
console.log(JSON.stringify(arr))
console.log(JSON.stringify(getAcordingToDiff(arr,25))); // diff >= 25
Explanation:
So in the heart of the above code obviously lies the Array.prototype.combinations function. For those who are not familiar with JS, this is just an ordinary function that we define under the Array object's prototype (so that now every array has access to this function like arr.combinations(n)) But let's use a more expressive language and refactor the above combinations array method into a generic function.
function combinations(a,n){
var sa;
return a.reduce(function(p,c,i,a){
if (n > 1) sa = combinations(a.slice(i+1), n-1).map(e => (e.push(c),e));
else sa = [[c]];
return p.concat(sa);
},[]);
}
So as you will notice combinations(a,n) is a recursive function which takes an array a and items count n. It works on the basis of keeping the first item of the input array and recursively invoking itself with one item shorter array, combinations(a.slice(i+1), n-1), and with one less items count up until n decrements to 1 in which case it starts it's return cycle with whatever remains from the input array and each item is wrapped in an array, sa = [[c]].
So on the return cycle of the recursive calls we take the resulting array and push the kept first element (remember -> It works on the basis of keeping the first item of the input array) into each item of the returned array (remember -> ...and each item is wrapped in an array, sa = [[c]]).
So that's it... You should be able to figure out yourself the details.
However in our application we are given an array of numbers and requested to obtain only the 2 item combinations with a certain difference. In this particular case we don't need to calculate all combinations and then filter them. We can do this on the way constructing our combinations. As the required difference value d gets bigger this will bring in a huge gain over filtering afterwards method, since now as d gets bigger we are eliminating more and more of the two item combinations, even before we generate them. And... let's hard-wire our code to work with 2 items only and merge everything in a single function. The performance results are below;
function getCombosWithDiff(a, d, n = 2){
var sa;
return a.reduce(function(p,c,i,a){
if (n > 1) sa = getCombosWithDiff(a.slice(i+1), d, n-1).reduce((r,e) => Math.abs(e[0]-c) > d ? (e.push(c),r.push(e),r)
: r, []);
else sa = [[c]];
return p.concat(sa);
},[]);
}
var arr = Array(100).fill().map((_,i) => i+1);
result = getCombosWithDiff(arr,89);
console.log(JSON.stringify(arr));
console.log(JSON.stringify(result));
So that's it. I have tried the above code to list the 2 items combinations each with diff greater than 10 from an array of 1000 items. It takes like 5000 msecs in Chrome and 14000 msecs in FF. However as mentioned above, the more the diff value d gets bigger, the shorter it takes. e.g same array with diff 900 would resolve in just 1100msecs with Chrome and in 4000msecs with FF.
You can test and play here
Create a 1001-element array A of integers initialized to zeroes. Generate your random integers, and increment the appropriate index by 1 for each such integer. With some math, you could do this without generating 2,000,000 random integers, but it's not worth the complexity.
Create a second 1001-element integer B s.t. B[i] = A[0] + ... + A[i]
Answer is sum from i=0 to 1000-k of B[i] * (2,000,000 - B[i+k-1])

Decomposing a value into results of powers of two

Is it possible to get the integers that, being results of powers of two, forms a value?
Example:
129 resolves [1, 128]
77 resolves [1, 4, 8, 64]
I already thought about using Math.log and doing also a foreach with a bitwise comparator. Is any other more beautiful solution?
The easiest way is to use a single bit value, starting with 1 and shift that bit 'left' until its value is greater than the value to check, comparing each bit step bitwise with the value. The bits that are set can be stored in an array.
function GetBits(value) {
var b = 1;
var res = [];
while (b <= value) {
if (b & value) res.push(b);
b <<= 1;
}
return res;
}
console.log(GetBits(129));
console.log(GetBits(77));
console.log(GetBits(255));
Since shifting the bit can be seen as a power of 2, you can push the current bit value directly into the result array.
Example
You can adapt solutions from other languages to javascript. In this SO question you'll find some ways of solving the problem using Java (you can choose the one you find more elegant).
decomposing a value into powers of two
I adapted one of those answers to javascript and come up with this code:
var powers = [], power = 0, n = 129;// Gives [1,128] as output.
while (n != 0) {
if ((n & 1) != 0) {
powers.push(1 << power);
}
++power;
n >>>= 1;
}
console.log(powers);
Fiddle
Find the largest power of two contained in the number.
Subtract from the original number and Add it to list.
Decrement the exponent and check if new 2's power is less than the number.
If less then subtract it from the original number and add it to list.
Otherwise go to step 3.
Exit when your number comes to 0.
I am thinking of creating a list of all power of 2 numbers <= your number, then use an addition- subtraction algorithm to find out the group of correct numbers.
For example number 77:
the group of factors is { 1,2,4,8,16,32,64} [ 64 is the greatest power of 2 less than or equal 77]
An algorithm that continuously subtract the greatest number less than or equal to your number from the group you just created, until you get zero.
77-64 = 13 ==> [64]
13-8 = 7 ==> [8]
7-4 = 3 ==> [4]
3-2 = 1 ==> [2]
1-1 = 0 ==> [1]
Hope you understand my algorithm, pardo my bad english.
function getBits(val, factor) {
factor = factor || 1;
if(val) {
return (val % 2 ? [factor] : []).concat(getBits(val>>1, factor*2))
}
return [];
}
alert(getBits(77));

Find the sum of consecutive whole numbers w/o using loop in JavaScript

I'm looking for a method to do calculations like:
function sumIntegerUpTo(number) {
return 1+2+3+...+number;
}
If you pass number as 5 function should return the sum of 1+2+3+4+5. I'm wondering if it's possible to do without loops.
Of course it is!
1+2+3+...+n = n * (n+1) / 2
function sumIntegerUpTo(number) {
return (1 + number) * number / 2;
}
I can think of two easy ways for me to remember this formula:
Think about adding numbers from both ends of the sequence: 1 and n, 2 and n-1, 3 and n-2, etc. Each of these little sums ends up being equal to n+1. Both ends will end at the middle (average) of the sequence, so there should be n/2 of them in total. So sum = (n+1) * (n/2).
There are as many number before the average (which is (1+n)/2) as there are after, and adding a pair of numbers that are equidistant to this average always results in twice the average, and there are n/2 pairs, so sum = (n+1)/2 * 2 * n/2 = (n+1)/2*n.
You can fairly easily extend the above reasoning to a different starting number, giving you: sum(numbers from a to b, inclusive) = (a+b)/2*(b-a+1).
Or you can use a recursive approach - which here is redundant given there is a simple formula! But there is always something cool and magical about recursion!
function addToN(n)
{
if(n==0) return 0;
else return n + addToN(n-1);
}
Edited to deal with 0!

Categories