Factorializing a number by creating an array and multiplying it - javascript

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));

Related

Implement a single iteration in Javascript

So I came into this online test question, something like this :
Write a function to check if the given value is a single digit. If it is not, add up all the numbers until it becomes a single digit. For example, the given value is 55555 resulting 25. When 2 and 5 added will get 7.
And here is my answer :
function createCheckDigit(membershipId) {
let sum = 0;
let array = membershipId.toString().split("")
if(array.length > 1){
for(let i = 0; i < array.length; i++){
sum = sum + parseInt(array[i]);
}
}
if(sum.toString().split("").length > 1){
return createCheckDigit(sum.toString())
} else {
return sum
}
}
console.log(createCheckDigit("55555"));
The goal for this question is:
test case answer = 7 (done)
single iteration required (required)
two iterations required (done)
multiple iterations required (done)
I managed to get 1, 3, 4 fulfilled but not 2. I don't understand which part should the single iteration takes place?
I think I have found a solution to the problem:
function checkDigit(v) {
let sum = 0;
const digits = v.toString().split("");
for (let i = 0; i < digits.length; ++i) {
sum += Number(digits[i]);
if (sum >= 10) {
sum -= 9; // same as (sum - 10) + 1; this works because we won't ever get a sum greater than 9+9=18 so the sum of those digits will be a single digit
}
}
return sum;
}
console.log(checkDigit('55555'));
console.log(checkDigit('2'));
console.log(checkDigit('12345'));
console.log(checkDigit('99999'));
console.log(checkDigit('775542'));

javascript for loop to achieve particular output?

How would I get a standard for loop to output in pairs or other groups (like three's of four's) with the output shifting up one after the last digit of the group?
for(var i = 0: i < 8; i++){
console.log(i)
}
so instead of the output being; 0,1,2,3,4,5,6,7
In pairs it would be; 0,1,1,2,2,3,3,4
or if it went up in groups of four; 0,1,2,3,1,2,3,4
I did try doing something like this, but instead of going up in two's every time I need the loop to output the first 2 digits move up one then output the next two ect...
for(var i = 0: i < 8; i+= 2){
console.log(i)
}
Hope that makes sense
For each case you would need to come up with the right formula based on i:
so instead of the output being; 0,1,2,3,4,5,6,7 In pairs it would be; 0,1,1,2,2,3,3,4
for (let i = 1; i < 9; i++) {
console.log(i >> 1); // this bit shift is integer division by 2
}
or if it went up in groups of four; 0,1,2,3,1,2,3,4
for (let i = 0; i < 8; i++) {
// Perform division by 4 and add remainder to that integer quotient
console.log((i >> 2) + (i % 4));
}
You could work with a variable inside the loop to determine the index. This way you can specify how many times you want the loop to run:
for(let index = 0; index < 8; index++) {
const currentIndex = index - (index >> 1);
console.log(currentIndex);
}
It also makes it easy to implement it as immutable:
const array = new Array(8).fill(0).map((entry, index) => index - (index >> 1));
console.log(array);
I think a function like below where we specify the total n and the chunksize after which you want to increase a single step might work for us :-
function getByChunkSteps(n,chunkSize){
let step = -1;
let output = [];
for(let index = 0;index < n;index++){
if(index%chunkSize===0){
step+=1;
}
output.push((index%chunkSize)+step);
}
return output;
}
console.log(getByChunkSteps(10,2));
console.log(getByChunkSteps(8,4));
console.log(getByChunkSteps(9,3));

Javascript How To Concatenate Separate Characters Into One String In Array?

I wrote a code for a "Heads or Tails" game below and:
var userInput = prompt("Enter maximum number output: ");
function coinFlip() {
return (Math.floor(Math.random() * 2) === 0) ? 'Heads' ; 'Tails';
}
for (var i = 0; i < 6; i++)
{
var result = [];
result["randomNum"] = (Math.floor(Math.random()*userInput);
result["coin"] = (coinFlip());
}
I'm trying to count the sum of total heads and sum of total tails each with the code:
var headsCount = 0;
var tailsCount = 0;
for (var j = 0; j < result["coin"].length; j++)
{
if (result["coin"] == 'Heads')
headsCount++;
else
tailsCount++;
}
The only problem is that it's counting each characters of 'Heads' and 'Tails' in the result["coin"] array as separate (such as 'H'-'e'-'a'-'d'-'s') and not into a full string (like "Heads"). Thus, instead of increment by 1 each time the loop above runs, it increments by +5.
I want it to increment by +1 only.
How do I make it so that the code reads the full string stored in result["coin"] and not character-by-character?
EDITED -- changed the <2 to *2
var result = []; is inside the for loop, so it is being overwritten with an empty array each time. So when you try to loop over the results, there's one one item in it; the last one. Pull the result array out of the loop so that you can add to it in each iteration.
It seems userInput should be the number of times to loop. Not sure why you're putting it in result["randomNum"]. result is an array, not an object, so it only has integer keys.
Instead of adding the result of the coin toss to result["coin"] I think you mean to add it to the array, so after tossing it six times it might look like this: ["Heads", "Heads", "Tails", "Heads", "Tails", "Tails"]. You can do this by calling result.push with the coin toss output.
To get one of two results randomly, compare the output of Math.random() against 0.5, which is half way between the limits. Numbers less than 0.5 can be considered heads, while numbers greater than or equal to 0.5 can be considered tails.
Putting it all together, this is what I think you were going for:
function coinFlip() {
return Math.random() < 0.5 ? 'Heads' : 'Tails';
}
var result = [];
var userInput = parseInt(prompt("Enter maximum number output: "), 10);
for (var i = 0; i < userInput; i++) {
result.push(coinFlip());
}
var headsCount = 0;
var tailsCount = 0;
for (var j = 0; j < result.length; j++) {
if (result[j] == 'Heads')
headsCount++;
else
tailsCount++;
}
console.log(headsCount, "heads and", tailsCount, "tails");
All that being said, there are definitely areas for improvement. You don't need to loop once to build the results, then loop a second time to read the results.
You can count the number of heads/tails as the coins are flipped. For example:
function isCoinFlipHeads() {
return Math.random() < 0.5;
}
var numFlips = parseInt(prompt("How many flips?"), 10);
var heads = 0;
var tails = 0;
for (var i = 0; i < numFlips; i++) {
isCoinFlipHeads() ? heads++ : tails++;
}
console.log(heads, "heads and", tails, "tails");

Sum of Factorial numbers in 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;
}

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