Sum of Factorial numbers in javascript - javascript

I would like to sum the given factorials numbers in javascript
'1! + 2! + 3! + ... + n!'

You may use factorial function :
Iterative function:
function sFact(num)
{
var rval=1;
for (var i = 2; i <= num; i++)
rval = rval * i;
return rval;
}
Recursive
function rFact(num)
{
if (num === 0)
{ return 1; }
else
{ return num * rFact( num - 1 ); }
}
I copied these function from this link.
Now what can you do is.
Suppose n value is 6.
var n = 6;
var sum = 0;
for(var i=1;i<=n;i++)
{
sum = sum + rFact(i);//Here you can use one of factorial funciton. I am using recursive function
}
document.print("The answer is "+ sum );

The naïve solution would be to actually calculate every factorial and add them together, which has a complexity of O(n²). However, if you're clever, you can design an algorithm that solves the same problem with a complexity of O(n). Take a look at the pattern of the following example that calculates the sum of the factorials of 1 through 4.
1!+2!+3!+4! =
1+1*2+1*2*3+1*2*3*4
Notice how you're reusing results from previous calculations multiple times? This can be taken advantage of. You can calculate the sum of all the factorials up to n with a program something like this.
function sumFactorials(n) {
var sum = 0;
var prod = 1;
for(var i=1; i<=n; i++) {
prod *= i;
sum += prod;
}
return sum;
}

Related

Factorializing a number by creating an array and multiplying it

I am going through one of the FreeCodeCamp challenges.
" Return the factorial of the provided integer.
If the integer is represented with the letter n, a factorial is the
product of all positive integers less than or equal to n.
Factorials are often represented with the shorthand notation n!
For example: 5! = 1 * 2 * 3 * 4 * 5 = 120 "
I already know that the easiest way is to use recursion but by the moment I've discovered this fact I was already trying to solve the problem by creating an array, pushing numbers in it and multiplying them. However I got stuck on this step. I have created an array with the number of digits depending on the function factorialize argument, but I can't get the product of those digits. What did I do wrong:
function factorialize(num) {
var array = [];
var product;
for(i = 0; i<=num;i++) {
array.push(i);
for (j=0; j < array.length; j++) {
product *= array[j];
}
return product;
}
}
factorialize(5);
I think the easiest way would be to create a range and reduce that:
var n = 5;
function factorize(max) {
return [...Array(max).keys()].reduce((a,b) => a * (b + 1), 1);
}
console.log(factorize(n));
It looks like you missed a close parenthesis
function factorialize(num) {
var array = [];
var product = 1;
for(i = 0; i<=num;i++) {
array.push(i);
} //right here!!! <----
for (j=0; j < array.length; j++) {
product *= array[j];
}
return product;
}
factorialize(5);
but as stated in the comments, you should change i = 0 to i = 1 not just because it would change the final result(which it does for all num ) but because it also doesn't follow the factorial algorithm.
1) You need initial value 'product' variable
2) You should change i = 0 to 1. You multiply by 0 in the loop
3) You don't need nested loop
function factorialize(num) {
var array = [];
var product = 1;
for(var i = 1; i <= num; i++) {
array.push(i);
}
for (j=0; j < array.length; j++) {
product *= array[j];
}
return product;
}
You only need one loop for that,
from 1 to the maximum number, then you multiply them up,
just a little clean up from your code
fact variable will contain the string version of the individual numbers making up the sum
if m is 5 you'll fact will be 1*2*3*4*5
function factorialize(num) {
var product = 1;
var fact = ""
for (i = 1; i <= num; i++) {
product *= i;
fact += i + "*"
}
fact = fact.substring(0, fact.length - 1)
console.log(fact)
return product;
}
console.log(factorialize(5));

Algorithm to get all possible permutations of n numbers in a range that have specific sum

What I'm trying to do can be easily illustrated with an example. Assume the following:
var minNum = 1;
var maxNum = 30;
var sum = 75;
var amount = 6;
I want to get all the permutations of amount numbers that add up to sum and are >= minNum && <= maxNum.
For example, if I was to create these permutations by hand, I would start like this:
30,30,12,1,1,1
30,30,11,2,1,1
30,30,11,1,2,1
30,30,11,1,1,2
30,30,10,3,1,1
30,30,10,2,2,1
etc
Is this a known problem in mathematics/programming and are there any algorithms that solve it?
Thanks in advance.
Here's a JavaScript solution (if your environment recursion depth limits the number of results you would like, you can convert the recursion to an explicit array-stack, push the arguments as would a function call and pop to process them):
function partition(n, min, max, parts) {
if (n < 0){
return;
} else if (n == 0) {
document.getElementById('output').innerHTML += (JSON.stringify(parts)) + '<br>';
} else {
for (var i=max; i>=min; i--){
var _parts = parts.slice();
_parts.push(i);
partition(n-i,min,max,_parts)
}
}
}
partition(6,2,4,[])
<pre id="output"></pre>

Javascript Loop Performance: Counting occurrences of a number in a finite series

What is the most efficient way to write a javascript loop to calculate the number of occurrences of 7's (as an example number) that will be encountered in counting from 1 to 100?
Example:
function numberOccurences(targetNumber, minNumber, maxNumber) {
var count = 0;
for (i = minNumber; i < maxNumber; i++) {
count = count + (i.toString().split(targetNumber).length - 1);
}
return count;
}
var result = numberOccurences(7,1,100);
This will do it without looking at the actual numbers. Sorry, no loop, but you did ask for effeciency. If you really want to use a loop, make the recursion an iteration.
function digitOccurences(digit, min, max, base) {
if (typeof base != "number") base = 10;
return digitOccurencesPlus(digit, max, base, 1, 0) - digitOccurencesPlus(digit, min, base, 1, 0);
function digitOccurencesPlus(digit, N, base, pow, rest) {
if (N == 0) return 0;
var lastDigit = N%base,
prevDigits = (N-lastDigit)/base;
var occsInLastDigit = pow*(prevDigits+(lastDigit>digit));
var occsOfLastInRest = rest * (lastDigit==digit);
// console.log(prevDigits+" "+lastDigit, rest, occsInLastDigit, occsOfLastInRest);
return occsInLastDigit + occsOfLastInRest + digitOccurencesPlus(digit, prevDigits, base, pow*base, pow*lastDigit+rest);
}
}
This is an interesting problem, and already has similar answers for other languages. Maybe you could try to make this one in javascript: Count the number of Ks between 0 and N
That solution is for occurences from 0 to n, but you could easily use it to calculate from a to b this way:
occurences(a,b)= occurences(0,b)-occurences(0,a)
This is much faster (x6) than my original function...JSPERF
function numberOccurences2(targetNumber, minNumber, maxNumber) {
var strMe = "";
for (i = minNumber; i < maxNumber; i++) {
strMe = strMe.concat(i);
}
var re = new RegExp(targetNumber,"g");
var num1 = strMe.length;
var num2 = strMe.replace(re, "").length;
num2 = num1- num2;
return (num2);
}
There has to be a faster way still...

Javascript Binary to Decimal Calculator

I have no idea why this code doesn't work, could anyone help:
toDecimal: function () {
var counter = 0;
var decimalValue = 0;
for (var i = 7; i > 0; i--){
var binaryValue = self.binaryArray[i];
decimalValue += binaryValue * Math.pow(2, counter);
counter++;
}
return decimalValue;
}
the code self.binaryArray is just an array of numbers (contains only 8, a byte, that's all i need to work with) something like this [0,0,0,0,1,1,1,1]
2nd'ly
Can you provide a slicker way of doing the counter, for the life of me I can't figure out how to calculate the counter from the i value, which shouldn't be too difficult, simple maths really.
Thanks
Your original loop never processes binaryArray[0]. As to a "slicker" way of doing things, assuming that binaryArray[0] is the most significant bit, I'd write your loop like this:
toDecimal: function () {
var decimalValue = 0;
for (var i = 0; i < 8; i++){
decimalValue = (decimalValue << 1) + self.binaryArray[i];
}
return decimalValue;
}
(The left shift is just a quick way of multiplying by 2.)
However, I like StephenH's suggestion:
toDecimal: function () {
return parseInt(self.binaryArray.join(''), 2);
}
Why not just use JavaScript's built in parseInt function?
Syntax: parseInt(string, radix);
var n = parseInt("10001",2);
n = 17

Javascript generate random unique number every time

Ok so i need to create four randomly generated numbers between 1-10 and they cannot be the same. so my thought is to add each number to an array but how can I check to see if the number is in the array, and if it is, re-generate the number and if it isnt add the new number to the array?
so basically it will go,
1.create new number and add to array
2.create second new number, check to see if it exist already, if it doesn't exist, add to array. If it does exist, re-create new number, check again etc...
3.same as above and so on.
You want what is called a 'random grab bag'. Consider you have a 'bag' of numbers, each number is only represented once in this bag. You take the numbers out, at random, for as many as you need.
The problem with some of the other solutions presented here is that they randomly generate the number, and check to see if it was already used. This will take longer and longer to complete (theoretically up to an infinite amount of time) because you are waiting for the random() function to return a value you don't already have (and it doesn't have to do that, it could give you 1-9 forever, but never return 10).
There are a lot of ways to implement a grab-bag type solution, each with varying degrees of cost (though, if done correctly, won't ever be infinite).
The most basic solution to your problem would be the following:
var grabBag = [1,2,3,4,5,6,7,8,9,10];
// randomize order of elements with a sort function that randomly returns -1/0/1
grabBag.sort(function(xx,yy){ return Math.floor(Math.random() * 3) - 1; })
function getNextRandom(){
return grabBag.shift();
};
var originalLength = grabBag.length;
for(var i = 0; i < originalLength; i++){
console.log(getNextRandom());
}
This is of course destructive to the original grabBag array. And I'm not sure how 'truly random' that sort is, but for many applications it could be 'good enough'.
An slightly different approach would be to store all the unused elements in an array, randomly select an index, and then remove the element at that index. The cost here is how frequently you are creating/destroying arrays each time you remove an element.
Here are a couple versions using Matt's grabBag technique:
function getRandoms(numPicks) {
var nums = [1,2,3,4,5,6,7,8,9,10];
var selections = [];
// randomly pick one from the array
for (var i = 0; i < numPicks; i++) {
var index = Math.floor(Math.random() * nums.length);
selections.push(nums[index]);
nums.splice(index, 1);
}
return(selections);
}
You can see it work here: http://jsfiddle.net/jfriend00/b3MF3/.
And, here's a version that lets you pass in the range you want to cover:
function getRandoms(numPicks, low, high) {
var len = high - low + 1;
var nums = new Array(len);
var selections = [], i;
// initialize the array
for (i = 0; i < len; i++) {
nums[i] = i + low;
}
// randomly pick one from the array
for (var i = 0; i < numPicks; i++) {
var index = Math.floor(Math.random() * nums.length);
selections.push(nums[index]);
nums.splice(index, 1);
}
return(selections);
}
And a fiddle for that one: http://jsfiddle.net/jfriend00/UXnGB/
Use an array to see if the number has already been generated.
var randomArr = [], trackingArr = [],
targetCount = 4, currentCount = 0,
min = 1, max = 10,
rnd;
while (currentCount < targetCount) {
rnd = Math.floor(Math.random() * (max - min + 1)) + min;
if (!trackingArr[rnd]) {
trackingArr[rnd] = rnd;
randomArr[currentCount] = rnd;
currentCount += 1;
}
}
alert(randomArr); // Will contain four unique, random numbers between 1 and 10.
Working example: http://jsfiddle.net/FishBasketGordo/J4Ly7/
var a = [];
for (var i = 0; i < 5; i++) {
var r = Math.floor(Math.random()*10) + 1;
if(!(r in a))
a.push(r);
else
i--;
}
That'll do it for you. But be careful. If you make the number of random numbers generated greater than the may number (10) you'll hit an infinite loop.
I'm using a recursive function. The test function pick 6 unique value between 1 and 9.
//test(1, 9, 6);
function test(min, max, nbValue){
var result = recursValue(min, max, nbValue, []);
alert(result);
}
function recursValue(min, max, nbValue, result){
var randomNum = Math.random() * (max-min);
randomNum = Math.round(randomNum) + min;
if(!in_array(randomNum, result)){
result.push(randomNum);
nbValue--;
}
if(nbValue>0){
recursValue(min, max, nbValue, result);
}
return result;
}
function in_array(value, my_array){
for(var i=0;i< my_array.length; i++){
if(my_array[i] == value){
console.log(my_array+" val "+value);
return true;
}
}
return false;
}
Here is a recursive function what are you looking for.
"howMany" parameter is count of how many unique numbers you want to generate.
"randomize" parameter is biggest number that function can generate.
for example : rand(4,8) function returns an array that has 4 number in it, and the numbers are between 0 and 7 ( because as you know, Math.random() function generates numbers starting from zero to [given number - 1])
var array = [];
var isMatch= false;
function rand(howMany, randomize){
if( array.length < howMany){
var r = Math.floor( Math.random() * randomize );
for( var i = 0; i < howMany; i++ ){
if( array[i] !== r ){
isMatch= false;
continue;
} else {
isMatch= true;
break;
}
}
if( isMatch == false ){
array.push(r);
ran(howMany, randomize);
}
ran(howMany, randomize);
return array;
}
}
In your answer earlier, you do have a small bug. Instead of
var originalLength = grabBag.length;
for(var i = 0; i < originalLength .length; i++){
console.log(getNextRandom());
}
I believe you meant:
var originalLength = grabBag.length;
for(var i = 0; i < originalLength; i++){
console.log(getNextRandom());
}
Thanks.

Categories

Resources