Why does my code work with underscore.js but not when I use Ramda.js? - javascript

I am new to Javascript, I am doing a coding challenge to learn more about the language. This is not school related or anything like that, totally for my own personal growth. Here is the challenge:
Return the sum of all odd Fibonacci numbers up to and including the
passed number if it is a Fibonacci number.
I have spent the past 2 evenings working on solving this challenge. When I run my code using underscore.js it works. When I use Ramda.js it says NaN. I would think both would return NaN. I'm very surprised that I can get the correct answer from one and not the other. Any insights would be greatly appreciated!
var R = require('ramda');
function sumFibs(num) {
var fib_Arr = [];
var new_Arr = [];
var total = 0;
// I use this to tell if the fib num is greater than 2
var the_Bit = "false";
// This is used to keep track of when to stop the loop
var fib_Num = 0;
// THIS WORKS FROM HERE
// This loop generates a list of fibonacci numbers then pushes them to the fib_Arr
for(var i = 0; total < num; i++){
if (i < 1){
fib_Arr.push(0);
}
else if (i === 1){
fib_Arr.push(i);
fib_Arr.push(1);
}
else if (i === 2){
fib_Arr.push(2);
the_Bit = "true";
}
else if (the_Bit === "true"){
temp_Arr = R.last(fib_Arr,2);
temp_Arr = temp_Arr[0] + temp_Arr[1];
fib_Arr.push(temp_Arr);
total = R.last(fib_Arr);
}
// Generating the fib Array works TO HERE!!!!
}
// console.log(fib_Arr); // Print out the generated fibonacci array
// if last Array element is greater than the original in
var last_Element = R.last(fib_Arr);
if (last_Element > num){
console.log("The last element of the array is bigger!");
fib_Arr.splice(-1,1); // This removes the last item from the array if it is larger than the original num input
}
// This loop removes all of the EVEN fibonacci numbers and leaves all of the ODD numbers
for (var j = 0; j < fib_Arr.length; j++){
if (fib_Arr[j] % 2 !== 0){
new_Arr.push((fib_Arr[j]));
}
}
// This checks if the original input num was a
if (num % 2 !== 0){
new_Arr.push(num);
}
else{
console.log("The original num was not a Fibonacci number!");
}
// if last Array element is the same as the original input num
var last = R.last(fib_Arr);
if (last === num){
console.log("Removing the last element of the array!");
new_Arr.splice(-1,1); // This removes the last item from the array if it is the same as the original num input
}
// Now to add all of the numbers up :-)
for (var k = 0; k < new_Arr.length; k++){
console.log("This is fib_Num: " + fib_Num);
// console.log(fib_N`);
fib_Num = fib_Num += new_Arr[k];
}
return fib_Num;
}
// TEST CASES:
// console.log(sumFibs(75025)); //.to.equal(135721);
console.log(sumFibs(75024)); //.to.equal(60696);

You have a problem on these lines :
temp_Arr = R.last(fib_Arr,2);
temp_Arr = temp_Arr[0] + temp_Arr[1];
Besides the fact that R.last does not take a second argument (that will not fail though), you are using temp_arr as an array, when it is a number. Therefore, temp_arr gets a NaN value.
You are probably looking for R.take (combined with R.reverse) or R.slice.
By changing :
temp_Arr = R.last(fib_Arr,2);
with :
temp_Arr = R.take(2, R.reverse(fib_Arr));
or with :
temp_Arr = R.slice(fib_Arr.length - 2, fib_Arr.length)(fib_Arr);
or with (bonus play with a reduce from the right) :
temp_Arr = R.reduceRight(function(arr, elem) {
return arr.length < 2 ? [elem].concat(arr) : arr;
}, [])(fib_Arr);
We get :
sumFibs(75024) === 60696

For the record, here's how you do this problem:
function fibSumTo(n) {
var f1 = 1, f2 = 1, sum = 1, t;
while (f2 <= n) {
if (f2 & 1) sum += f2;
t = f1 + f2;
f1 = f2;
f2 = t;
}
return sum;
}
There's really no need for any sort of library because there's really no need for any sort of data structure.

var _ = require('underscore');function sumUpFibs (number){
arr_of_fibs = [1,1];
current = 1; //cursor for previous location
while (true){
var num = arr_of_fibs[current] + arr_of_fibs[current - 1];
if (num <= number) {
arr_of_fibs.push(num);
current++;
} else {
break;
}
}
console.log(arr_of_fibs);
var total = 0;
_.each(arr_of_fibs, function(fib){
total += fib;
})
return total;}console.log(sumUpFibs(75025));
This may be a better implementation... Though I know you're just starting so I don't want to come off as mean : D.... Also, maybe check your test cases too.

Related

Least Common Multiple - for loop breaks down - javascript

I'm taking a course on FreeCodeCamp.org and the assignment is to find "Smallest Common Multiple". So I came up with a solution I think works and I does up to a certain point. Then the code just seems like it's breaking down. Here is my code:
function smallestCommons(arr) {
arr = arr.sort((a,b) => {return a - b;});
console.log(arr);
var truesec = false;
for(var a = arr[1]; truesec != true; a++){
for(var e = 1; e <= arr[1]; e++){
//console.log(a % e + " " + e);
if(a % e != 0){
truesec = false;
break;
}else{
truesec = true;
}
}
//console.log(truesec + " " + a);
if(truesec == true){
return a;
}
}
return a;
}
console.log(smallestCommons([23,18]));
This should return 6056820 according to their checklist but every time I check I get a different result I've gotten both 114461 & 122841 from the same code. Can somebody please tell me what is wrong with this?
Here is the assignment if it helps:
Intermediate Algorithm Scripting: Smallest Common Multiple
What your algorithm trying to do is find the common multiple between 1 and the greater number in the array, which might take a very long time. However, the question from the FreeCodeCamp asks you to find the common multiple between the two numbers in the array, so the result calculated from your algorithm does not match the tests.
To make your solution works, you can change
from for (var e = 1; e <= arr[1]; e++)
to for (var e = arr[0]; e <= arr[1]; e++)
in order to loop between two numbers in the array.
I would take a different approach to this problem:
create function to get all prime factors
create array of prime factor of all number between a[0] and a[1]
reduce the array as the biggest power for each prime factor.
multiple all the prime factor left in the array
Your approach will take O(k*a[1]) when k is the answer - and k can be very high... This approach will take O((a[1])^2)
Consider the following code:
function smallestCommons2(arr) {
arr.sort((a,b) => {return a - b;});
let factors = [];
for(let i = arr[0]; i <= arr[1]; i++)
factors.push(findPrimeFactors(i));
let reduced = reduceFactors(factors);
let ans = 1;
for (let i in reduced)
ans *= Math.pow(i, reduced[i]);
return ans;
}
function reduceFactors(factorsArr) {
let factorObject = {};
for (let i in factorsArr) {
for(let key in factorsArr[i]) {
if (!(key in factorObject) || factorObject[key] < factorsArr[i][key])
factorObject[key] = factorsArr[i][key];
}
}
return factorObject;
}
function findPrimeFactors (num) {
var primeFactors = [];
while (num % 2 === 0) {
primeFactors.push(2);
num = num / 2;
}
var sqrtNum = Math.sqrt(num);
for (var i = 3; i <= sqrtNum; i++) {
while (num % i === 0) {
primeFactors.push(i);
num = num / i;
}
}
if (num > 2)
primeFactors.push(num);
let factorObject = {};
for (let item of primeFactors) {
if (item in factorObject)
factorObject[item] += 1;
else factorObject[item] = 1;
}
return factorObject;
}
console.log(smallestCommons2([23,18]));
This code will output 6056820 in sec
Edited - found a post that do the same thing in a better way

JavaScript neglecting the else statement

I created a function which takes in two values..
Both are numbers represented by n & p. What the function does is that it gets the number n and splits it up then squares it to the value of p and sums them in an increasing order like this: n^p + n^(p+1) + n^(p+2) + ...
Here is the function
function digPow(n, p) {
// ...
let num = n.toString();
let pow = p;
let arrn = [];
let arrp = [];
for (let i = 0; i < num.length; i++) {
arrn.push(JSON.parse(num[i]));
}
let index = arrn.join('');
let sindex = index.split('');
for (let j = 0; j < sindex.length; j++) {
let power = p + j;
let indexs = sindex[j];
let Mathpow = Math.pow(indexs, power);
arrp.push(Mathpow);
}
let total = 0;
for (let m in arrp) {
total += arrp[m]
}
let secondVal = total / n;
let totals = total / secondVal;
let mx = [-1]
if (totals.length == n.length) {
return secondVal
} else {
return -1
}
}
Now i created variables and arrays to store up the values and then the if part is my problem.. The if/else statement is meant to let the program check if a particular variable totals is equal to n which is the input.. if true it should return a variable secondVal and if not it should return -1..
So far its only returning secondVal and i'snt returning -1 in cases where it should like:
digPow(92, 1) instead it returns 0.14130434782608695
What do i do?
totals and n are both numbers. They don't have a .length property, so both totals.length and n.length evaluate to undefined. Thus, they are equal to each other.
There are plenty of other weird things going on in your code, too. I'd recommend finding a good JavaScript tutorial and working through it to get a better feel for how the language (and programming in general) works.
Let's start by stripping out the redundant variables and circular-logic code from your function:
function digPow(n, p) {
let num = n.toString();
// let pow = p; // this is never used again
// let arrn = []; // not needed, see below
// let arrp = []; // was only used to contain values that are later summed; can instead just sum them in the first place
// this does the same thing as num.split(''), and isn't needed anyway:
//for (let i = 0; i < num.length; i++) {
// arrn.push(JSON.parse(num[i]));
//}
// this is the same as the original 'num' variable
// let index = arrn.join('');
// This could have been num.split(), but isn't needed anyway
// let sindex = index.split('');
let total = 0; // moved this line here from after the loop below:
for (let j = 0; j < num.length; j++) { // use num.length instead of the redundant sindex
let power = p + j;
// The only reason for the sindex array was to get individual characters from the string, which we can do with .charAt().
//let indexs = sindex[j];
let indexs = num.charAt(j);
let Mathpow = Math.pow(indexs, power);
//arrp.push(Mathpow); // No need to collect these in an array
total += Mathpow; // do this instead
}
// No need for this loop, since we can sum the total during the previous loop
// let total = 0;
//for (let m in arrp) {
// total += arrp[m]
//}
let secondVal = total / n;
// let totals = total / secondVal;
// The above is the same thing as total / total / n, which is:
let totals = 1/n;
// This is never used
//let mx = [-1]
// This was totals.length and n.length, which for numbers would always be undefined, so would always return true
if (totals == n) {
return secondVal
} else {
return -1
}
}
So the above reduces to this functionally identical code:
function digPow(n, p) {
let num = n.toString();
let total = 0;
for (let j = 0; j < num.length; j++) {
let power = p + j;
let indexs = num.charAt(j);
let Mathpow = Math.pow(indexs, power);
total += Mathpow;
}
let secondVal = total / n;
let totals = 1 / n;
if (totals == n) {
return secondVal
} else {
return -1
}
}
Now let's talk about the logic. The actual output will always be -1, unless the input is 1, due to what's clearly a logic error in the totals variable: the only case where 1/n == n is true is when n==1.
Setting that aside, and looking only at the secondVal variable, some examples of what it's calculating for a given input would be
digPow(123,1) --> (1^1 + 2^2 + 3^3) / 123 --> 14/123
digPow(321,2) --> (3^2 + 2^3 + 1^4) / 321 --> 21/321
digPow(92, 1) --> (9^1 + 2^2) / 92 --> 13/92
I'm pretty sure from your description that that's not what you intended. I'm not at all sure from your description what you did intend, so can't be much help in correcting the function beyond what I've done here.
What I'd suggest is to sit down and think through your algorithm first; make sure you know what you're trying to build before you start building it. There were some syntax problems with your code, but the real issues are with the logic itself. Your original function shows clear signs of "just keep throwing more lines of code at it until something happens" rather than any planned thinking -- that's how you wind up with stuff like "split a string into an array, then join it back into a string, then split that string into another array". Write pseudocode first: break the problem down into steps, think through those steps for some example inputs and make sure it'll produce the output you're looking for. Only then should you bust out the IDE and start writing javascript.

Find out which one of the given numbers differs from the others for Javascript

I'm trying to solve this exercise. There is a string of numbers and among the given numbers the program finds one that is different in evenness, and returns a position of this number. The element has to be returned by its index (with the number being the actual position the number is in). If its index 0, it has to be returned as 1. I have this so far but it's not passing one test. I'm not too sure why because it feels like it should. Is anyone able to see what the error is? Any help is appreciated!
function iqTest(numbers) {
var num = numbers.split(" ");
var odd = 0;
var even = 0;
var position = 0;
for(var i = 0; i < num.length; i++) {
if(num[i]%2!==0) {
odd++;
if(odd===1) {
position = num.indexOf(num[i]) + 1;
}
}
else if(num[i]%2===0) {
even++;
if(even===1) {
position = num.indexOf(num[i]) + 1;
}
}
}
return position;
}
iqTest("2 4 7 8 10") output 3
iqTest("2 1 2 2") output 2
iqTest("1 2 2") outputs 2 when it should be 1
The simplest way is to collect all even/odd positions in subarrays and check what array has the length 1 at the end:
function iqTest(numbers) {
numbers = numbers.split(' ');
var positions = [[], []];
for (var i = 0; i < numbers.length; i++) {
positions[numbers[i] % 2].push(i + 1);
}
if(positions[0].length === 1) return positions[0][0];
if(positions[1].length === 1) return positions[1][0];
return 0;
}
console.log(iqTest("2 4 7 8 10"))
console.log(iqTest("2 1 2 2"))
console.log(iqTest("1 2 2"))
console.log(iqTest("1 3 2 2"))
Your code is overly complex.
Since the first number determines whether you're looking for an even number or an odd one, calculate it separately. Then, find the first number that doesn't match it.
function iqTest(numbers) {
numbers = numbers.split(" ");
var parity = numbers.shift() % 2;
for( var i=0; i<numbers.length; i++) {
if( numbers[i] % 2 != parity) {
return i+2; // 1-based, but we've also skipped the first
}
}
return 0; // no number broke the pattern
}
That being said, iqTest("1 2 2") should return 2 because the number in position 2 (the first 2 in the string) is indeed the first number that breaks the parity pattern (which 1 has established to be odd)
You have to define which "evenness" is the different one. Use different counters for the two cases, and return -1 if you don't have a single different one. Something like this:
function iqTest(numbers) {
var num = numbers.split(" ");
var odd = 0;
var even = 0;
var positionOdd = 0;
var positionEven = 0;
for(var i = 0; i < num.length; i++) {
if(num[i]%2!==0) {
odd++;
if(odd===1) {
positionOdd = i + 1;
}
}
else if(num[i]%2===0) {
even++;
if(even===1) {
positionEven = i + 1;
}
}
}
if (odd == 1)
return positionOdd;
else if (even == 1)
return positionEven;
else
return -1;
}
Note that, if you have exactly a single even number and a single odd one, the latter will be returned with the method of mine. Adjust the logic as your will starting from my solution.
Since the first number determines whether you're looking for an even number or an odd one, calculate it separately.
Then, find the first number that doesn't match it.
function iqTest(numbers){
// ...
const numArr = numbers.split(' ');
const checkStatus = num => (parseInt(num) % 2) ? 'odd' : 'even';
const findUniqueStatus = array => {
let numEvens = 0;
array.forEach(function(value){
if (checkStatus(value) == 'even') { numEvens++; }
});
return (numEvens === 1) ? 'even' : 'odd'
}
let statuses = numArr.map(checkStatus),
uniqueStatus = findUniqueStatus(numArr);
return statuses.indexOf(uniqueStatus) + 1;
}
}
public static int Test(string numbers)
{
var ints = numbers.Split(' ');
var data = ints.Select(int.Parse).ToList();
var unique = data.GroupBy(n => n % 2).OrderBy(c =>
c.Count()).First().First();
return data.FindIndex(c => c == unique) + 1;
}

How can I get the sum of all odd fibonacci vales in javaScript?

I am working through this Free Code Camp exercise.
Return the sum of all odd Fibonacci numbers up to and including the
passed number if it is a Fibonacci number. The first few numbers of the Fibonacci sequence are 1, 1, 2, 3, 5 and
8, and each subsequent number is the sum of the previous two numbers.
And here is what I have so far...
Any suggestions?
function sumFibs(num) {
var arr, isFibVal, isEvenVal, sum, i = 0, fibonacci = function (num){
var a, b, result, fibArr = [1];
a=0;
b=1;
result=b;
for(var j = 0; j < num; j++){
result = a + b;
a = b;
b = result;
fibArr.push(result);
}
return fibArr;
},
isFib = function (val){
var prev = 0;
var curr = 1;
while(prev<=val){
if(prev == val){
return true;
} else {
return false;
}
curr = prev + curr;
prev = curr - prev;
}
},
isEven = function(someNumber){
return (someNumber % 2 === 0) ? true : false;
};
function sumArray(array) {
for (
var
index = 0, // The iterator
length = array.length, // Cache the array length
sum = 0; // The total amount
index < length; // The "for"-loop condition
sum += array[index++] // Add number on each iteration
);
return sum;
}
arr = fibonacci(num);
isFibVal = isFib(num);
isEvenVal = isEven(num);
if (isFibVal && !isEvenVal){
sum += sumArray(arr);
}
return sum;
}
All I get back is undefined which seems to be weird because i thought this part of my code was pretty cool—using the function values to check vs. in the if statement.
arr = fibonacci(num);
isFibVal = isFib(num);
isEvenVal = isEven(num);
if (isFibVal && !isEvenVal){
sum += sumArray(arr);
}
I won't give you the answer outright since you're going through FCC, but I'll provide you with some hints as to where to look:
See this segment:
for(var j = 0; j < num; j++){
result = a + b;
a = b;
b = result;
fibArr.push(result);
}
And this one:
function sumArray(array) {
for (
var
index = 0, // The iterator
length = array.length, // Cache the array length
sum = 0; // The total amount
index < length; // The "for"-loop condition
sum += array[index++] // Add number on each iteration
);
return sum;
}
Also, you probably don't need this segment at all:
isFibVal = isFib(num);
isEvenVal = isEven(num);
if (isFibVal && !isEvenVal){
sum += sumArray(arr);
Good luck. As someone who has finished a good chunk of the curriculum, I can say that Free Code Camp is the real deal.
You're pretty close and the other answer is good for pushing you in the right direction, I'll post a different way that does this using native JS functions:
Example of the code below in JSBin
function fibs(n) {
var f = [0, 1];
var extraNumber = 0;
for (var i = 0; i < n; i++) {
f.push(f[f.length - 1] + f[f.length - 2]);
}
// lets check if the passed in number is a fib:
if (f.indexOf(n) > -1) {
extraNumber = n;
}
console.log(f); // just to check we can cut all the logs later...
var filtered = f.filter(function(num) {
// filter out the even numbers
return num % 2 === 1;
});
console.log(filtered);
var sum = filtered.reduce(function(a, b) {
// add up whats left
return a + b;
});
console.log(sum);
return sum + extraNumber;
}
heres my solution, and i find it to be pretty readable:
function sumOddFibs(num) {
// initialize with 2 because
// fib sequence starts with 1 and 1
var sum = 2;
var prev = 1;
var curr = 1;
var next = 2;
while (next <= num) {
prev = curr;
curr = next;
next = prev + curr;
if (curr % 2 !== 0) {
sum += curr;
}
}
return sum;
}
You could start by defining variables for the previous number, current number, and total Fibonacci
To check for odd numbers, you could use an if statement and use %:
if (currNum % 2 !== 0){ }
If current number is odd, then you add it to the total
fibTotal += currNumber;
To determine the next Fibonacci number you, you will need to add the previous and current number:
var nextNumber = prevNumber + currNumber;
You will need to update the previous number to the current one
prevNumber = currNumber;
Set the current number to the next Fibonacci number in the sequence
currNumber = nextNumber;
Hope this helps.

Trying to find factors of a number in JS

I am just starting JS, and understand the concept of finding a factor. However, this snippet of code is what I have so far. I have the str variable that outputs nothing but the first factor which is 2. I am trying to add each (int) to the str as a list of factors. What's the wrong in below code snippet?
function calculate(num) {
var str = "";
var int = 2;
if (num % int == 0) {
str = str + int;
int++;
} else {
int++;
}
alert(str);
}
calculate(232);
UPDATED ES6 version:
As #gengns suggested in the comments a simpler way to generate the array would be to use the spread operator and the keys method:
const factors = number => [...Array(number + 1).keys()].filter(i=>number % i === 0);
console.log(factors(36)); // [1, 2, 3, 4, 6, 9, 12, 18, 36]
ES6 version:
const factors = number => Array
.from(Array(number + 1), (_, i) => i)
.filter(i => number % i === 0)
console.log(factors(36)); // [1, 2, 3, 4, 6, 9, 12, 18, 36]
https://jsfiddle.net/1bkpq17b/
Array(number) creates an empty array of [number] places
Array.from(arr, (_, i) => i) populates the empty array with values according to position [0,1,2,3,4,5,6,7,8,9]
.filter(i => ...) filters the populated [0,1,2,3,4,5] array to the elements which satisfy the condition of number % i === 0 which leaves only the numbers that are the factors of the original number.
Note that you can go just until Math.floor(number/2) for efficiency purposes if you deal with big numbers (or small).
As an even more performant complement to #the-quodesmith's answer, once you have a factor, you know immediately what its pairing product is:
function getFactors(num) {
const isEven = num % 2 === 0;
const max = Math.sqrt(num);
const inc = isEven ? 1 : 2;
let factors = [1, num];
for (let curFactor = isEven ? 2 : 3; curFactor <= max; curFactor += inc) {
if (num % curFactor !== 0) continue;
factors.push(curFactor);
let compliment = num / curFactor;
if (compliment !== curFactor) factors.push(compliment);
}
return factors;
}
for getFactors(300) this will run the loop only 15 times, as opposed to +-150 for the original.
#Moob's answer is correct. You must use a loop. However, you can speed up the process by determining if each number is even or odd. Odd numbers don't need to be checked against every number like evens do. Odd numbers can be checked against every-other number. Also, we don't need to check past half the given number as nothing above half will work. Excluding 0 and starting with 1:
function calculate(num) {
var half = Math.floor(num / 2), // Ensures a whole number <= num.
str = '1', // 1 will be a part of every solution.
i, j;
// Determine our increment value for the loop and starting point.
num % 2 === 0 ? (i = 2, j = 1) : (i = 3, j = 2);
for (i; i <= half; i += j) {
num % i === 0 ? str += ',' + i : false;
}
str += ',' + num; // Always include the original number.
console.log(str);
}
calculate(232);
http://jsfiddle.net/r8wh715t/
While I understand in your particular case (calculating 232) computation speed isn't a factor (<-- no pun intended), it could be an issue for larger numbers or multiple calculations. I was working on Project Euler problem #12 where I needed this type of function and computation speed was crucial.
function calculate(num) {
var str = "0";
for (var i = 1; i <= num; i++) {
if (num % i == 0) {
str += ',' + i;
}
}
alert(str);
}
calculate(232);
http://jsfiddle.net/67qmt/
Below is an implementation with the time complexity O(sqrt(N)):
function(A) {
var output = [];
for (var i=1; i <= Math.sqrt(A); i++) {
if (A % i === 0) {
output.push(i);
if (i !== Math.sqrt(A)) output.push(A/i);
}
}
if (output.indexOf(A) === -1) output.push(A);
return output;
}
here is a performance friendly version with complexity O(sqrt(N)).
Output is a sorted array without using sort.
var factors = (num) => {
let fac = [], i = 1, ind = 0;
while (i <= Math.floor(Math.sqrt(num))) {
//inserting new elements in the middle using splice
if (num%i === 0) {
fac.splice(ind,0,i);
if (i != num/i) {
fac.splice(-ind,0,num/i);
}
ind++;
}
i++;
}
//swapping first and last elements
let temp = fac[fac.length - 1];
fac[fac.length - 1] = fac[0];
fac[0] = temp;
// nice sorted array of factors
return fac;
};
console.log(factors(100));
Output:
[ 1, 2, 4, 5, 10, 20, 25, 50, 100 ]
This got me an 85% on Codility (Fails on the upperlimit, over a billion).
Reducing the input by half doesn't work well on large numbers as half is still a very large loop. So I used an object to keep track of the number and it's half value, meaning that we can reduce the loop to one quarter as we work from both ends simultaneously.
N=24 becomes: (1&24),(2&12),(3&8),(4&6)
function solution(N) {
const factors = {};
let num = 1;
let finished = false;
while(!finished)
{
if(factors[num] !== undefined)
{
finished = true;
}
else if(Number.isInteger(N/num))
{
factors[num] = 0;
factors[N/num]= 0;
}
num++
}
return Object.keys(factors).length;
}
Using generators in typescript in 2021
function* numberFactorGenerator(number: number): Generator<number> {
let i: number = 0;
while (i <= number) {
if (number % i === 0) {
yield i;
}
i++;
}
}
console.log([...numberFactorGenerator(12)]); // [ 1, 2, 3, 4, 6, 12 ]
function factorialize(num) {
var result = '';
if( num === 0){
return 1;
}else{
var myNum = [];
for(i = 1; i <= num; i++){
myNum.push(i);
result = myNum.reduce(function(pre,cur){
return pre * cur;
});
}
return result;
}
}
factorialize(9);
I came looking for an algorithm for this for use in factoring quadratic equations, meaning I need to consider both positive and negative numbers and factors. The below function does that and returns a list of factor pairs. Fiddle.
function getFactors(n) {
if (n === 0) {return "∞";} // Deal with 0
if (n % 1 !== 0) {return "The input must be an integer.";} // Deal with non-integers
// Check only up to the square root of the absolute value of n
// All factors above that will pair with factors below that
var absval_of_n = Math.abs(n),
sqrt_of_n = Math.sqrt(absval_of_n),
numbers_to_check = [];
for (var i=1; i <= sqrt_of_n; i++) {
numbers_to_check.push(i);
}
// Create an array of factor pairs
var factors = [];
for (var i=0; i <= numbers_to_check.length; i++) {
if (absval_of_n % i === 0) {
// Include both positive and negative factors
if (n>0) {
factors.push([i, absval_of_n/i]);
factors.push([-i, -absval_of_n/i]);
} else {
factors.push([-i, absval_of_n/i]);
factors.push([i, -absval_of_n/i]);
}
}
}
// Test for the console
console.log("FACTORS OF "+n+":\n"+
"There are "+factors.length+" factor pairs.");
for (var i=0; i<factors.length; i++) {
console.log(factors[i]);
}
return factors;
}
getFactors(-26);
function calculate(num){
var str = "0" // initializes a place holder for var str
for(i=2;i<num;i++){
var num2 = num%i;
if(num2 ==0){
str = str +i; // this line joins the factors to the var str
}
}
str1 = str.substr(1) //This removes the initial --var str = "0" at line 2
console.log(str1)
}
calculate(232);
//Output 2482958116
Here's an optimized solution using best practices, proper code style/readability, and returns the results in an ordered array.
function getFactors(num) {
const maxFactorNum = Math.floor(Math.sqrt(num));
const factorArr = [];
let count = 0; //count of factors found < maxFactorNum.
for (let i = 1; i <= maxFactorNum; i++) {
//inserting new elements in the middle using splice
if (num % i === 0) {
factorArr.splice(count, 0, i);
let otherFactor = num / i; //the other factor
if (i != otherFactor) {
//insert these factors in the front of the array
factorArr.splice(-count, 0, otherFactor);
}
count++;
}
}
//swapping first and last elements
let lastIndex = factorArr.length - 1;
let temp = factorArr[lastIndex];
factorArr[lastIndex] = factorArr[0];
factorArr[0] = temp;
return factorArr;
}
console.log(getFactors(100));
console.log(getFactors(240));
console.log(getFactors(600851475143)); //large number used in Project Euler.
I based my answer on the answer written by #Harman
We don't have to loop till end of the given number to find out all the factors. We just have to loop till reaching the given number's squareroot. After that point we, can figure out the rest of the factors by dividing the given number with the already found factors.
There is one special case with this logic. When the given number has a perfect square, then the middle factor is duplicated. The special case is also handled properly in the below code.
const findFactors = function (num) {
const startingFactors = []
const latterFactors = []
const sqrt = Math.sqrt(num)
for (let i = 1; i <= sqrt; i++) {
if (num % i == 0) {
startingFactors.push(i)
latterFactors.push(num / i)
}
}
// edge case (if number has perfect square, then the middle factor is replicated, so remove it)
if (sqrt % 1 == 0) startingFactors.pop()
return startingFactors.concat(latterFactors.reverse())
}
function factorialize(num) {
if(num === 0)
return 1;
var arr = [];
for(var i=1; i<= num; i++){
arr.push(i);
}
num = arr.reduce(function(preVal, curVal){
return preVal * curVal;
});
return num;
}
factorialize(5);

Categories