Arrays - Find missing numbers in a Sequence - javascript

I'm trying to find an easy way to loop (iterate) over an array to find all the missing numbers in a sequence, the array will look a bit like the one below.
var numArray = [0189459, 0189460, 0189461, 0189463, 0189465];
For the array above I would need 0189462 and 0189464 logged out.
UPDATE : this is the exact solution I used from Soufiane's answer.
var numArray = [0189459, 0189460, 0189461, 0189463, 0189465];
var mia= [];
for(var i = 1; i < numArray.length; i++)
{
if(numArray[i] - numArray[i-1] != 1)
{
var x = numArray[i] - numArray[i-1];
var j = 1;
while (j<x)
{
mia.push(numArray[i-1]+j);
j++;
}
}
}
alert(mia) // returns [0189462, 0189464]
UPDATE
Here's a neater version using .reduce
var numArray = [0189459, 0189460, 0189461, 0189463, 0189466];
var mia = numArray.reduce(function(acc, cur, ind, arr) {
var diff = cur - arr[ind-1];
if (diff > 1) {
var i = 1;
while (i < diff) {
acc.push(arr[ind-1]+i);
i++;
}
}
return acc;
}, []);
console.log(mia);

If you know that the numbers are sorted and increasing:
for(var i = 1; i < numArray.length; i++) {
if(numArray[i] - numArray[i-1] != 1) {
//Not consecutive sequence, here you can break or do whatever you want
}
}

ES6-Style
var arr = [0189459, 0189460, 0189461, 0189463, 0189465];
var [min,max] = [Math.min(...arr), Math.max(...arr)];
var out = Array.from(Array(max-min),(v,i)=>i+min).filter(i=>!arr.includes(i));
Result: [189462, 189464]

Watch your leading zeroes, they will be dropped when the array is interpreted-
var A= [0189459, 0189460, 0189461, 0189463, 0189465]
(A returns [189459,189460,189461,189463,189465])
function absent(arr){
var mia= [], min= Math.min.apply('',arr), max= Math.max.apply('',arr);
while(min<max){
if(arr.indexOf(++min)== -1) mia.push(min);
}
return mia;
}
var A= [0189459, 0189460, 0189461, 0189463, 0189465];
alert(absent(A))
/* returned value: (Array)
189462,189464
*/

To find a missing number in a sequence, First of all, We need to sort an array. Then we can identify what number is missing. I am providing here full code with some test scenarios. this code will identify only missing positive number, if you pass negative values even then it gives positive number.
function findMissingNumber(inputAr) {
// Sort array
sortArray(inputAr);
// finding missing number here
var result = 0;
if (inputAr[0] > 1 || inputAr[inputAr.length - 1] < 1) {
result = 1;
} else {
for (var i = 0; i < inputAr.length; i++) {
if ((inputAr[i + 1] - inputAr[i]) > 1) {
result = inputAr[i] + 1;
}
}
}
if (!result) {
result = inputAr[inputAr.length - 1] + 1;
}
return result;
}
function sortArray(inputAr) {
var temp;
for (var i = 0; i < inputAr.length; i++) {
for (var j = i + 1; j < inputAr.length; j++) {
if (inputAr[j] < inputAr[i]) {
temp = inputAr[j];
inputAr[j] = inputAr[i];
inputAr[i] = temp;
}
}
}
}
console.log(findMissingNumber([1, 3, 6, 4, 1, 2]));
console.log(findMissingNumber([1, 2, 3]));
console.log(findMissingNumber([85]));
console.log(findMissingNumber([86, 85]));
console.log(findMissingNumber([0, 1000]));

This can now be done easily as a one-liner with the find method:
const arr = [1,2,3,5,6,7,8,9];
return arr.find((x,i) => arr[i+1]-x > 1) + 1
//4

const findMissing = (arr) => {
const min = Math.min(...arr);
const max = Math.max(...arr);
// add missing numbers in the array
let newArr = Array.from(Array(max-min), (v, i) => {
return i + min
});
// compare the full array with the old missing array
let filter = newArr.filter(i => {
return !arr.includes(i)
})
return filter;
};

const findMissing = (numarr) => {
for(let i = 1; i <= numarr.length; i++) {
if(i - numarr[i-1] !== 0) {
console.log('found it', i)
break;
} else if(i === numarr.length) console.log('found it', numarr.length + 1)
}
};
console.log(findMissing([1,2,3,4,5,6,7,8,9,10,11,12,13,14]))

It would be fairly straightforward to sort the array:
numArray.sort();
Then, depending upon what was easiest for you:
You could just traverse the array, catching sequential patterns and checking them as you go.
You could split the array into multiple arrays of sequential numbers and then check each of those separate arrays.
You could reduce the sorted array to an array of pairs where each pair is a start and end sequence and then compare those sequence start/ends to your other data.

function missingNum(nums){
const numberArray = nums.sort((num1, num2)=>{
return num1 - num2;
});
for (let i=0; i < numberArray.length; i++){
if(i !== numberArray[i]){
return i;
}
}
}
console.log(missingNum([0,3,5,8,4,6,1,9,7]))

Please check below code.....
function solution(A) {
var max = Math.max.apply(Math, A);
if(A.indexOf(1)<0) return 1;
var t = (max*(max+1)/2) - A.reduce(function(a,b){return a+b});
return t>0?t:max+1;
}

Try as shown below
// Find the missing number
let numArray = [0189459, 0189460, 0189461, 0189463, 0189468];
let numLen = numArray.length;
let actLen = Number(numArray[numLen-1])-Number(numArray[0]);
let allNumber = [];
for(let i=0; i<=actLen; i++){
allNumber.push(Number(numArray[0])+i);
}
[...allNumber].forEach(ele=>{
if(!numArray.includes(ele)){
console.log('Missing Number -> '+ele);
}
})

I use a recursive function for this.
function findMissing(arr, start, stop) {
var current = start,
next = stop,
collector = new Array();
function parseMissing(a, key) {
if(key+1 == a.length) return;
current = a[key];
next = a[key + 1];
if(next - current !== 1) {
collector.push(current + 1);
// insert current+1 at key+1
a = a.slice( 0, key+1 ).concat( current+1 ).concat( a.slice( key +1 ) );
return parseMissing(a, key+1);
}
return parseMissing(a, key+1);
}
parseMissing(arr, 0);
return collector;
}
Not the best idea if you are looking through a huge set of numbers. FAIR WARNING: recursive functions are resource intensive (pointers and stuff) and this might give you unexpected results if you are working with huge numbers. You can see the jsfiddle. This also assumes you have the array sorted.
Basically, you pass the "findMissing()" function the array you want to use, the starting number and stopping number and let it go from there.
So:
var missingArr = findMissing(sequenceArr, 1, 10);

let missing = [];
let numArray = [3,5,1,8,9,36];
const sortedNumArray = numArray.sort((a, b) => a - b);
sortedNumArray.reduce((acc, current) => {
let next = acc + 1;
if (next !== current) {
for(next; next < current; next++) {
missing.push(next);
}
}
return current;
});

Assuming that there are no duplicates
let numberArray = [];
for (let i = 1; i <= 100; i++) {
numberArray.push(i);
}
let deletedArray = numberArray.splice(30, 1);
let sortedArray = numberArray.sort((a, b) => a - b);
let array = sortedArray;
function findMissingNumber(arr, sizeOfArray) {
total = (sizeOfArray * (sizeOfArray + 1)) / 2;
console.log(total);
for (i = 0; i < arr.length; i++) {
total -= arr[i];
}
return total;
}
console.log(findMissingNumber(array, 100));

Here is the most efficient and simple way to find the missing numbers in the array. There is only one loop and complexity is O(n).
/**
*
* #param {*} item Takes only the sorted array
*/
function getAllMissingNumbers(item) {
let first = 0;
let second = 1;
let currentValue = item[0];
const container = [];
while (first < second && item[second]) {
if ((item[first] + 1) !== item[second]) { // Not in sequence so adds the missing numbers in an array
if ((currentValue + 1) === item[second]) { // Moves the first & second pointer
first = second;
second++;
currentValue = item[first];
} else { // Adds the missing number between two number
container.push(++currentValue);
}
} else { // Numbers are in sequence so just moves the first & second pointer
first = second;
second++;
currentValue = item[first];
}
}
return container;
}
console.log(getAllMissingNumbers([0189459, 0189460, 0189461, 0189463, 0189465].sort( (a, b) => a - b )));
console.log(getAllMissingNumbers([-5,2,3,9]));

Adding one more similar method
Find the min and max of the numbers in the array
Loop with the max and min numbers to get the full list
compare the full list of numbers with the input array to get the difference
const array = [0189459, 0189460, 0189461, 0189463, 0189465]
const max = Math.max(...array)
const min = Math.min(...array)
let wholeNumber = []
for(var i = min ;i<=max ;i++ ){
wholeNumber.push(i)
}
const missing = wholeNumber.filter((v)=>!array.includes(v))
console.log('wholeNumber',wholeNumber)
console.log('missingNumber',missing)

Here's a variant of #Mark Walters's function which adds the ability to specify a lower boundary for your sequence, for example if you know that your sequence should always begin at 0189455, or some other number like 1.
It should also be possible to adjust this code to check for an upper boundary, but at the moment it can only look for lower boundaries.
//Our first example array.
var numArray = [0189459, 0189460, 0189461, 0189463, 0189465];
//For this array the lowerBoundary will be 0189455
var numArrayLowerBoundary = 0189455;
//Our second example array.
var simpleArray = [3, 5, 6, 7, 8, 10, 11, 13];
//For this Array the lower boundary will be 1
var simpleArrayLowerBoundary = 1;
//Build a html string so we can show our results nicely in a div
var html = "numArray = [0189459, 0189460, 0189461, 0189463, 0189465]<br>"
html += "Its lowerBoundary is \"0189455\"<br>"
html += "The following numbers are missing from the numArray:<br>"
html += findMissingNumbers(numArray, numArrayLowerBoundary);
html += "<br><br>"
html += "simpleArray = [3, 5, 6, 7, 8, 10, 11, 13]<br>"
html += "Its lowerBoundary is \"1\".<br>"
html += "The following numbers are missing from the simpleArray:<br>"
html += findMissingNumbers(simpleArray, simpleArrayLowerBoundary);
//Display the results in a div
document.getElementById("log").innerHTML=html;
//This is the function used to find missing numbers!
//Copy/paste this if you just want the function and don't need the demo code.
function findMissingNumbers(arrSequence, lowerBoundary) {
var mia = [];
for (var i = 0; i < arrSequence.length; i++) {
if (i === 0) {
//If the first thing in the array isn't exactly
//equal to the lowerBoundary...
if (arrSequence[i] !== lowerBoundary) {
//Count up from lowerBoundary, incrementing 1
//each time, until we reach the
//value one less than the first thing in the array.
var x = arrSequence[i];
var j = lowerBoundary;
while (j < x) {
mia.push(j); //Add each "missing" number to the array
j++;
}
} //end if
} else {
//If the difference between two array indexes is not
//exactly 1 there are one or more numbers missing from this sequence.
if (arrSequence[i] - arrSequence[i - 1] !== 1) {
//List the missing numbers by adding 1 to the value
//of the previous array index x times.
//x is the size of the "gap" i.e. the number of missing numbers
//in this sequence.
var x = arrSequence[i] - arrSequence[i - 1];
var j = 1;
while (j < x) {
mia.push(arrSequence[i - 1] + j); //Add each "missing" num to the array
j++;
}
} //end if
} //end else
} //end for
//Returns any missing numbers, assuming that lowerBoundary is the
//intended first number in the sequence.
return mia;
}
<div id="log"></div> <!-- Just used to display the demo code -->

Related

find max Consecutive Ones in array using javascript

I have an array of numbers. I need to find the maximum number of consecutive 1s in the array.
var arr = [1, 1, 3, 2, 3, 1, 1, 1];
const maxOne = (arr) => {
for (var i = 0; i < arr.length; i++) {
let count = 0;
let result = 0;
if (arr[i] ==1) {
count += 1;
result = Math.max(result, count);
} else {
count = 0
}
return result
}
}
console.log(maxOne(arr));
desired output: 3
my output : 1
I am not sure where I am going wrong
You algorithm works, you just did few misstakes:
create variables outside of loop
return after loop, not in it(it will break loop at first iteration)
const maxOne = (arr) => {
let count = 0;
let result = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] === 1) {
count += 1;
result = Math.max(result, count);
} else {
count = 0
}
}
return result
}
You can do like this.
let arr=[1,2,3,1,1,2,1,1,12,1,1,1,1];
let count=0;
for(let i=0;i<arr.length;i++){
arr[i]==1 ? count+=1 :count=0;
}
console.log(count).
const numbers = [1,1,0,0,1,1,1,0,1];
const maxString = Math.max(...numbers.join('').split('0')); // remove zero items and convert
// the sequential Ones to a string. After that Find the string with the largest number of characters.
console.log('max:', maxString.toString().length) // Take the string length
//3
you can use *Math.max.apply(Math, numbers.join('').split('0'))* instead of second line.

Not able to get value after Do...While loop

Question: Create a function that takes a positive integer and returns the next bigger number that can be formed by rearranging its digits. For example:
12 ==> 21
513 ==> 531
2017 ==> 2071
//nextBigger(num: 12) // returns 21
//nextBigger(num: 513) // returns 531
//nextBigger(num: 2017) // returns 2071
I am trying to compare two Array and get correct array as answer. In do...while loop I am comparing the two array by increment second array by one.
function nextBigger(n){
let nStrg = n.toString();
let nArr = nStrg.split('');
function compareArr(Ar1,Ar2){
if(Ar2.length>Ar1.length){
return false;
}
for(let i=0; i<Ar1.length; i++){
let num = Ar1[i];
for(let j=0; j<Ar2.length; j++){
if(Ar2.lastIndexOf(num) !== -1){
Ar2.splice(Ar2.lastIndexOf(num), 1);
break;
}
else{
return false;
break;
}
}
}
return true;
}
let nextNumArr;
let m = n;
do{
let nextNum = m+1
m=nextNum
let nextNumStrg = nextNum.toString();
nextNumArr = nextNumStrg.split('')
console.log(compareArr(nArr, nextNumArr))
}
while(compareArr(nArr, nextNumArr) == false)
console.log(nextNumArr)
return parseInt(nextNumArr.join())
}
nextBigger(12);
This gives me empty array at the end;
[2,0,1,7].join() will give you '2,0,1,7', can use [2,0,1,7].join('') and get '2017'
All looks a bit complicated. How about:
const nextLarger = num => {
const numX = `${num}`.split(``).map(Number).reverse();
for (let i = 0; i < numX.length; i += 1) {
if ( numX[i] > numX[i + 1] ) {
numX.splice(i, 2, ...[numX[i+1], numX[i]]);
return +(numX.reverse().join(``));
}
}
return num;
};
const test = [...Array(100)].map(v => {
const someNr = Math.floor(10 + Math.random() * 100000);
const next = nextLarger(someNr);
return `${someNr} => ${
next === someNr ? `not possible` : next}`;
}).join('\n');
document.querySelector(`pre`).textContent = test;
<pre></pre>
See also
function nextbig(number) {
let nums = []
number.toString().split('').forEach((num) => {
nums.push(parseInt(num))
})
number = nums
n = number.length
for (var i = n - 1; i >= 0; i--) {
if (number[i] > number[i - 1])
break;
}
if (i == 1 && number[i] <= number[i - 1]) {
return 'No greater possible'
}
let x = number[i - 1];
let smallest = i;
for (let j = i + 1; j < n; j++) {
if (number[j] > x &&
number[j] < number[smallest])
smallest = j;
}
let temp = number[smallest];
number[smallest] = number[i - 1];
number[i - 1] = temp;
x = 0
for (let j = 0; j < i; j++)
x = x * 10 + number[j];
number = number.slice(i, number.length + 1);
number.sort()
for (let j = 0; j < n - i; j++)
x = x * 10 + number[j];
return x
}
console.log(nextbig(12))
console.log(nextbig(513))
console.log(nextbig(2017))
In compareArr you are deleting elements as you find them, which is correct to do, to make sure duplicates actually occur twice etc. However, that also deletes the elements from nextNumArr in the calling context, because the array is passed by reference and not by value. You need to do a manual copy of it, for example like this: compareArr(nArr, [...nextNumArr]).
I have used a different approach, first I search for all possible combinations of the given numbers with the permutator function. This function returns an array of possible numbers.
Then I sort this array of combinations and look for the index of the given number in the main function.
Once I have this index I return the position before the given number.
function nextbig(num){
function permutator(inputArr){
let result = [];
const permute = (arr, m = []) => {
if (arr.length === 0) {
result.push(m)
} else {
for (let i = 0; i < arr.length; i++) {
let curr = arr.slice();
let next = curr.splice(i, 1);
permute(curr.slice(), m.concat(next))
}
}
}
permute(inputArr)
return result;
}
let arrNums = num.toString().split('')
let combinations = permutator(arrNums).map(elem => parseInt(elem.join("")))
combinations.sort((a, b) => {
return b - a
})
let indexOfNum = combinations.findIndex(elem => elem === num)
let nextBigIndex = indexOfNum <= 0 ? 0 : indexOfNum - 1
return (combinations[nextBigIndex])
}
console.log(nextbig(12))
console.log(nextbig(517))
console.log(nextbig(2017))

Algorithm for reversing certain characters in long strings

I'm currently working on a programming question:
Given a string s and an integer k, reverse the first k characters for every 2k characters counting from the start of the string.
If there are fewer than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and leave the other as original.
I created a program that solves the first 45 of the 60 test cases, but apparently falls apart on really long strings. When fed strings of 999 characters, the last few came out as nonsense.
I cannot see any fault in my code that may have caused that. Any feedback? Simple solutions or just better ways of constructing my code?
function reverseArrayOfChars(sArray) {
const length = sArray.length;
let temp;
for (let s = 0; s < length / 2; s++) {
temp = sArray[s];
sArray[s] = sArray[length - 1 - s];
sArray[length - 1 - s] = temp;
}
return sArray;
}
function reverseStr(s, k) {
let sArray = s.split("");
let newArray = []; //Final array to be returned
let tempArray = []; //tempArray is used to store returns from reverseArrayOfChars function. These returns are then concatenated onto newArray.
let switchBoard = 1; //Used to 'switch' between two conditions. Changes automatically every iteration of the loop.
for (let counter = 0; counter < sArray.length; counter += k) {
switchBoard = switchBoard === 0 ? 1 : 0;
if (sArray.length - counter < k) {
tempArray = reverseArrayOfChars(sArray.slice(counter));
newArray = newArray.concat(tempArray);
break;
} else if (sArray.length - counter > k && sArray.length < k * 2) {
tempArray = reverseArrayOfChars(sArray.slice(counter, counter + k));
newArray = newArray.concat(tempArray);
tempArray = sArray.slice(counter + k);
newArray = newArray.concat(tempArray);
break;
} else if (switchBoard === 0) {
tempArray = reverseArrayOfChars(sArray.slice(counter, counter + k));
newArray = newArray.concat(tempArray);
} else if (switchBoard === 1) {
tempArray = sArray.slice(counter, counter + k);
newArray = newArray.concat(tempArray);
}
}
return newArray.join("");
Alternatively, you could try this sample code:
var reverseStr = function(s, k) {
if (k > s.length)
return s.split('').reverse().join('');
const split = s.split('');
// reverse the seg. then join it back
for (let i = 0; i < s.length; i += 2*k) {
const reverse = split.splice(i, k).reverse();
split.splice(i, 0, ...reverse);
}
return split.join('');
};

Functions that takes array as argument and generate random numbers

First of all, any of built-in methods cannot be used. ex. pop(), shift(). What I can use is merely loops, array and so on.
I would like to make a function which takes an array as an argument and generate random strings of numbers, which does not contain these numbers given in the array.
For instance, func([6, 2]) //=> "20353" (2 and 6 would not be there).
The array length could change ([6, 2, 9], [7, 2, 1, 9]). So the function has to have an ability to accommodate any length of an array.
In order to tackle this practice question, I have used for and while loops. However, I ran into a problem that, when the second index is checked (whether numbers randomly generated contain 2 or not, in the example), if it contains, I regenerate the random number and it could produce the first index number (in this case, 6) which I do not want.
Please see the code I posted below and help me solve this. On top of that, if there is another way to get the same result which is a better way, please let me know too.
let str = "";
let arr = [];
let tem
const func = arg2 => {
for (let i = 0; i < 5; i++) {
arr[i] = Math.floor(Math.random() * 10);
}
for (let i = 0; i < arr.length; i++) {
for (let v = 0; v < arg2.length; v++) {
if (arg2[v] == arr[i]) {
do {
tem = Math.floor(Math.random() * 10);
} while (tem == arr[i])
arr[i] = tem;
}
}
}
for (let i = 0; i < arr.length; i++) str += arr[i]
return str
}
console.log(func([6, 2]))
// the output will not contain 2, which is the last index element
// however, when the second index number is removed, the output might replace it with 6, which is the first index element
Expected output:
func([6, 3, 8]) //=> "45102"
func([4, 9]) //=> "55108"
First, you already use two native methods (floor and random), but I'll assume you're OK with that.
Secondly, in your question the term digit would have been more appropriate in some instances than number. There is a difference...
To avoid that you still select a digit that is not allowed, you could first build an array with digits that are still allowed, and then randomly pick values from that array. That way you will not ever pick a wrong one.
Here is how that would look:
const func = arg2 => {
const digits = [0,1,2,3,4,5,6,7,8,9];
// Mark digits that are not allowed with -1
for (let i=0; i<arg2.length; i++) {
digits[arg2[i]] = -1;
}
// Collect digits that are still allowed
const allowed = [];
for (let i=0; i<digits.length; i++) {
if (digits[i] > -1) allowed[allowed.length] = digits[i];
}
// Pick random digits from the allowed digits
let str = "";
for(let i=0; i<5; i++) {
str += allowed[Math.floor(Math.random() * allowed.length)];
}
return str;
}
console.log(func([6, 2]));
Just for fun, if you lift the restrictions on what language aspects cannot be used, you can do this as follows:
const func = arg2 => {
const digits = new Set(Array(10).keys());
for (let digit of arg2) digits.delete(digit);
const allowed = [...digits];
return Array.from({length:5}, () =>
allowed[Math.floor(Math.random() * allowed.length)]
).join``;
}
console.log(func([6, 2]));
I suspect you're overthinking this. The basic algorithm is:
In a loop:
If output has 5 digits, return it.
Otherwise
Pick a random digit n from 0 to 9.
If n is not in the list of excluded numbers, it to output.
This maps pretty directly to the following function:
function fn(exclude, length = 5) {
let output = '';
while (output.length < length) {
const n = Math.floor(Math.random() * 10)
if (!exclude.includes(n)) {
output += n;
}
}
return output;
}
console.log(fn([6,3,8]));
There are, of course, other ways to achieve this, such as initializing an array with five elements and then joining the elements:
function fn(exclude, length = 5) {
return Array.from({ length }, () => {
let n;
while (n = Math.floor(Math.random() * 10), exclude.includes(n)) {}
return n;
}).join('');
}
console.log(fn([6,3,8]));
You need to loop through the entire arg2 array each time you pick a random digit. You can't replace the value in the arg2 loop, because then you won't check against earlier elements.
You don't need the arr array, you can append to str in the loop.
const func = arg2 => {
let str = "";
let arr = [];
for (let i = 0; i < 5; i++) {
let random;
while (true) {
let ok = true;
random = Math.floor(Math.random() * 10);
for (let j = 0; j < arg2.length; j++) {
if (random == arg2[j]) {
ok = false;
break;
}
}
if (ok) {
break;
}
}
str += random
}
return str
}
console.log(func([6, 2]))
Besides the fact (what others stated as well) that you use native array-methods yourself, I would probably go for it with something like this (using only what you used so far):
const func = without => {
let result = '';
while (result.length < 5) {
let rand = Math.floor(Math.random() * 10);
let add = true;
for (i=0; i<without.length; i++) {
if (rand === without[i]) {
add = false;
}
}
if (add) {
result += rand;
}
}
return result;
}
console.log(func([6, 2]))
a more concise version using native array methods could look like this:
const func = without => {
let result = '';
while (result.length < 5) {
let rand = Math.floor(Math.random() * 10);
if (!without.includes(rand)) {
result += rand;
}
}
return result;
}
console.log(func([6, 2]))

Javascript reduce not working after function?

Not too sure where I've gone wrong here, expecting to factorialize 5 (1*2*3*4*5 = 120) by turning 5 into a string of [1,2,3,4,5] and then using reduce to multiply the string all together. When I run the code, it just gives me [1,2,3,4,5]...
var arr = [];
function factorialize(num) {
for (var i = 1; i <= num; i++) {
arr.push(i);
}
return arr;
}
var factors = 0;
factors = arr.reduce(function(previousVal, currentVal) {
return previousVal * currentVal;
}, 0); // Expecting 120, instead result = [1,2,3,4,5]
factorialize(5);
Forgive the long route - my first week of Javascript!
arr is empty, you should give it the resulting array of the factorisation first, and you should multiply, not add, and when multiplying, the starting value is 1 not 0:
var arr = [];
function factorialize(num) {
for (var i = 1; i <= num; i++) {
arr.push(i);
}
return arr;
}
arr = factorialize(5); // give it the value
var factors = arr.reduce(function(previousVal, currentVal) {
return previousVal * currentVal; // multiply, don't add
}, 1); // start with 1 when multiplying
console.log(arr);
console.log(factors);
If you just want to calculate the factorial:
function factorial(num) {
var res = 1;
for (var i = 2; i <= num; i++) {
res *= i;
}
return res;
}
console.log('factorial(5) = ' + factorial(5));
console.log('factorial(10) = ' + factorial(10));
You are not calling factors. factorialize(5); by doing this you are just calling function factorialize(num) which will give you array(of 1...num).
(Additional info)And also in reduce you are adding + instard of multiplying * so change that too and
factors = arr.reduce(function(previousVal, currentVal) {
return previousVal + currentVal;
}, 0);
^
|_ either initialize it to 1 or remove this.
See below code. I just create array and then apply reduce on that array.
function factorialize(num) {
var arr = [];
for (var i = 1; i <= num; i++) {
arr.push(i);
}
return arr.reduce(function(previousVal, currentVal) {
return previousVal * currentVal;
});
}
console.log(factorialize(5));
var arr = [];
function factorialize(num) {
for (var i = 1; i <= num; i++) {
arr.push(i);
}
var factors = 0;
factors = arr.reduce(function (previousVal, currentVal) {
return previousVal * currentVal;
});
return factors
}
factorialize(5); // 120
You could get first the factors and then multiply in Array#reduce the factors.
I suggest to name the function what it does and move the array declaration inside of the function, because the function returns this array.
For getting the product, you need to multiply the values and use 1 as neutral start value for getting a product out of the numbers.
function getFactors(num) {
var i, arr = [];
for (i = 1; i <= num; i++) {
arr.push(i);
}
return arr;
}
var factors = getFactors(5),
product = factors.reduce(function(previousVal, currentVal) {
return previousVal * currentVal;
}, 1);
console.log(factors);
console.log(product);
Put the global variable arr inside of the function factorialize.
Get the returned array and then execute the function reduce.
You need to multiply rather than to add the numbers.
Start the reduce with initialValue = 1, this is to avoid 0 * n.
function factorialize(num) {
var arr = [];
for (var i = 1; i <= num; i++) {
arr.push(i);
}
return arr;
}
var arr = factorialize(5);
var factors = arr.reduce(function(previousVal, currentVal) {
return previousVal * currentVal;
}, 1);
console.log(factors)
Issue is with the initial value set to 0 and instead of multiplying numbers, it is being added
arr.reduce(callback, initValue)
arr = [1,2,3,4,5]
In the code provided, it accumulates in below format
arr.reduce(function(previousVal, currentVal) {
return previousVal + currentVal;
}, 0);
First call -> 0 + 1 = 1 (factors = 1)
Second call -> 0 + 2 = 2 (factors = 2)
First call -> 0 + 3 = 3 (factors = 3)
First call -> 0 + 4 = 4 (factors = 10)
First call -> 0 + 5 = 5 (factors = 15)
To achieve expected result, use below option
var arr = []; // initialize array arr
function factorialize(num) {
//for loop to push 1,2 ,3, 4, 5 to arr array
for (var i = 1; i <= num; i++) {
arr.push(i);
}
// return arr.reduce value by multiplying all values in array, default initial value is first element
return arr.reduce(function(previousVal, currentVal) {
//console log to debug and display loop values
console.log(previousVal, currentVal);
return previousVal * currentVal;
});
}
console.log("output", factorialize(5));
code sample - https://codepen.io/nagasai/pen/YaQKZw?editors=1010

Categories

Resources