I need to write a prime factorisation function that returns an object whose keys are a prime factor and values are the exponents of the corresponding prime factors. E.g.
console.log(primeFactorisation(4)) // { 2: 2 }
console.log(primeFactorisation(6)) // { 2: 1, 3: 1 }
My code so far is below but I'm stuck. Any help much appreciated.
const primeFactorisation = (num) => {
let result = {};
for (let i = 2; i < num; i++) {
if (num % i === 0) {
result[i] = i;
num /= i;
}
}
return result
}
When a number is found, increment it on the result object instead of assigning i to the result object.
You also need a nested loop to keep testing for the number until it no longer divides evenly, and you also need i <= num, not i < num, so that the last factor is caught:
const primeFactorisation = (num) => {
let result = {};
for (let i = 2; i <= num; i++) {
while (num % i === 0) {
result[i] = (result[i] || 0) + 1;
num /= i;
}
}
return result
}
console.log(
primeFactorisation(6),
primeFactorisation(4),
);
Related
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))
I am trying to solve a problem where I am required to loop through an array of arrays, each of which contains a list of numbers that together make up a credit card number. I've been asked to use the Luhn algorithm to validate these numbers, working from the rightmost number in each array to the leftmost. I came up with a function that successfully returns true or false for each array correctly (I know in advance that 5 are valid and 5 are false while a remaining 5 are not known). However, when I then try to loop through the array containing all these arrays, calling the function on them each in turn, the program hangs for ages and finally returns a long list of trues, far longer than the 15 results I expect. My code is below, validateCred seems to work for each card number individually, but findValidCards does not. I can't see why this is happening, can anyone enlighten me?
const validateCred = arr => {
const resultArray = [];
let index = (arr.length) - 1;
if ((index % 2) != 0) {
for (i = index; i >= 0; i--) {
if ((i % 2) == 0) {
let doubled = arr[i] * 2;
if (doubled > 9) {
let numToUnshift = doubled - 9;
resultArray.unshift(numToUnshift);
} else {
resultArray.unshift(doubled);
};
} else {
resultArray.unshift(arr[i]);
};
};
} else {
for (i = index; i >= 0; i--) {
if ((i % 2) != 0) {
let doubled = arr[i] * 2;
if (doubled > 9) {
let numToUnshift = doubled - 9;
resultArray.unshift(numToUnshift);
} else {
resultArray.unshift(doubled);
};
} else {
resultArray.unshift(arr[i]);
};
};
};
const reducer = (acc, curr) => acc + curr;
let sum = resultArray.reduce(reducer);
if ((sum % 10) == 0) {
return true;
} else {
return false;
};
}
const findInvalidCards = array => {
let resultArray = [];
for (i = 0; i < array.length; i++) {
let card = array[i];
let result = validateCred(card);
console.log(result);
};
};
So I am trying to "write a function Single() that takes a number and returns the number of times you must multiply the digits in num so as to reach a single digit. e.g. Single(456)//4*5*6=120, 1*2*0=0//it takes two loops to to reach the single digit so the return would be 2.
My problem is that now I have to put in an array of individual digits instead of a number. So I probably need to combine the two functions.
function numberToArray(num) {
var tmpString = num.toString();
var tempArray = [];
for (var i = 0; i < tmpString.length; i++) {
tempArray.push(tmpString[i]);
}
return tempArray;
}
function reachSingle(tempArray) {
var count = 0;
var k = 1;
for (var i = 0; i < tempArray.length; i++) {
k *= tempArray[i];
}
count++;
if (k <= 10) return count;
else {
var newArray = numberToArray(k);
return count + reachSingle(newArray);
}
}
document.write(reachSingle([2, 9, 3, 7, 6]));
You could take a recursive approach with an exit condition for numbers smaller than 10 and return in this case zero. Otherwise return one plus the result of the call of the product of the digits.
function reachSingle(n) {
if (n < 10) return 0;
return 1 + reachSingle(Array.from(n.toString()).reduce((a, b) => a * b));
}
console.log(reachSingle(29376)); // 4
I have an integer X and a list of all the factors of X. I want to output the ratio between X and a factor, and for each time set X to that ratio. I want this algorithm to continue till the ratio is bigger than or equal to 1.
For example: X = 36.
All factors (but 1 and 36): 2, 3, 4, 6, 9, 12, 18,
Algorithm: 36 / 2 = 18 --> 18 / 3 = 6 --> 6 / 4 = 1.5 --> 1.5 / 6 < 1 --> Stop
Output: [18, 6, 1.5]. Question:
How do I get this output?
What i have written:
var arr = [];
for (var i = 2; i < X; i++) {
if (X % i == 0) {
arr.push(i);
}
}
var temp = [];
var index = 0;
while (X / arr[index] >= 1) {
index += 1;
X = X / arr[index];
temp.push(X / arr[index]);
}
var arr = [];
var X = 36
for (var i = 2; i < X; i++) {
if (X % i == 0) {
arr.push(i);
}
}
var temp = arr.reduce((acc, item, index) => {
if(!(X/item < 1)){
acc.push(X/item)
X = X/item;
}
return acc;
}, [])
console.log(temp)
You could calculate the first value before you go into the while loop an check the asssigned x. If the value passes the condition, you could push that value to the result array and increment the index and calculate a new value.
function fn(x) {
var array = [], // declare all variable on top
i,
result = [];
for (var i = 2; i < x; i++) {
if (x % i == 0) {
array.push(i);
}
}
i = 0; // prepare index for looping
x /= array[i]; // take a first possible value
while (x >= 1) { // check value
result.push(x); // push value
i++; // increment index
x /= array[i]; // take the next value for checking
}
return result;
}
console.log(fn(36))
A bit shorter with Array#every
function fn(x) {
var array = [], // declare all variable on top
i,
result = [];
for (var i = 2; i < x; i++) {
if (x % i == 0) {
array.push(i);
}
}
array.every(v => (x /= v) >= 1 && result.push(x));
return result;
}
console.log(fn(36))
Your question is a little bit confuse. Is this what you want?
Basically, I update the factor after each iteration (if >= 1) and store into an array the output.
// Generate a range of integers (starting at 2, and we should not including the input)
// get only values divisible by the input (filter)
const generateRange = (input) => {
return Array.from({length: (input - 2)}, (v, k) => k + 2).filter(i => {
return input % i === 0;
})
}
const divideFactors = (input) => {
const list = generateRange(input) // filtered range
let output = []
let factor = input
for (const item of list) {
let ratio = factor / item
if (ratio < 1) { //if ratio < 1, break the loop
break;
}
output.push(ratio) // update output array with new ratio
factor = ratio; // update factor variable with current ratio
}
return output
}
console.log(divideFactors(36))
More info:
Array.from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
For of: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
I am working on an excercise to sum all prime numbers from 2 to the parameter. I have worked this far in the code, but am stuck. I believe by using the splice function, I am actually skipping an element because of a changed indices.
function sumPrimes(num) {
var primearray = [];
var sum = 0;
for(var i =2; i <= num; i++){
primearray.push(i);
}
for(var j = 0; j < primearray.length; j++) {
console.log(primearray[j]);
if ((primearray[j]%2===0) && (primearray[j] >2)) {
primearray.splice(j,1);
} else if ((primearray[j]%3===0) && (primearray[j] > 3)) {
primearray.splice(j,1);
console.log(primearray);
} else if ((primearray[j]%5===0) && (primearray[j] > 5)) {
primearray.splice(j,1);
} else if ((primearray[j]%7===0) && (primearray[j] > 7)) {
primearray.splice(j,1);
}
}
sum = primearray.reduce();
return sum;
}
sumPrimes(30);
I haven't utilized the reduce function yet because I am still working on the if else statements.
I found a pretty good solution to the same problem. afmeva was spot on. This is how it works.
function isPrime(val){
//test if number is prime
for(var i=2; i < val; i++){
if(val % i === 0){
return false;
}
}
return true;
}
In the above code we accept a number to determine whether or not it is prime. We then loop from two all the way up until our number minus one because we know that our number will be divisible by itself and one. If the remainder of our value with the current loop value is zero then we know it is not prime so break out and say so.
This article explains very well
function sumPrimes(num) {
var answer = 0;
//loop through all numbers from 2 to input value
for(var i=2; i <= num; i++){
//sum only prime numbers, skip all others
if(isPrime(i)){
answer += i;
}
}
return answer;
}
sumPrimes(977); // 73156
Here's another good resource
function sumPrimes(num) {
let arr = Array.from({length: num+1}, (v, k) => k).slice(2);
let onlyPrimes = arr.filter( (n) => {
let m = n-1;
while (m > 1 && m >= Math.sqrt(n)) {
if ((n % m) === 0)
return false;
m--;
}
return true;
});
return onlyPrimes.reduce((a,b) => a+b);
}
sumPrimes(977);
I have seen lots of people putting all prime numbers into arrays and in order to check if a number is prime, they check from 2 to the number to see if there's a remainder.
You only need to check odd numbers, and only need to count to half the number because a number can't be divisible by any number greater than it has.
Here's my solution:
function sumPrimes(num){
var sum = num>=2?2:0;
for(var i=3;i<=num;i+=2){
var isPrime=true;
for(var j=3;j<(i/2);j++){
if (i%j==0)
{
isPrime=false;
break;
}
}
sum+=isPrime?i:0;
}
return sum;
}
Note: I started from j=2 because we are only checking odd numbers, so they'd never be divisible by 2.
function sumPrimes(num) {
var sumArr= [];
for(var i=0;i<=num;i++){
if(isPrime(i))
sumArr.push(i);
}
sumArr = sumArr.reduce(function(a,b){
return a+b;
})
return sumArr;
}
function isPrime(num) {
if(num < 2) return false;
for (var i = 2; i < num; i++) {
if(num%i === 0)
return false;
}
return true;
}
sumPrimes(10);
something like this?
function isPrime(_num) {
for(var i = 2; i < _num; i++) {
if(!(_num % i)) {
return false
}
}
return true;
}
function sumPrimes(_num) {
var sum = 0;
for(var i = 2; i <= _num; i++) {
if(isPrime(i)) {
sum += i;
}
}
return sum;
}
sumPrimes(20) // 77
sumPrimes(5) // 10
You could do this as well.
function sumPrimes(num) {
var sum = 0;
for (var i = 0; i <= num; i++) {
if (isPrime(i)) {
sum += i;
}
}
return sum;
}
function isPrime(n) {
if (n < 2) { return false; }
if (n !== Math.round(n)) { return false; }
var result = true;
for (var i = 2; i <= Math.sqrt(n); i++) {
if (n % i === 0) {
result = false;
}
}
return result;
}
Here's my solution. I hope you find it easy to interpret:
function sumPrimes(num) {
// determine if a number is prime
function isPrime(n) {
if (n === 2) return true;
if (n === 3) return true;
if (n % 2 === 0) return false;
if (n % 3 === 0) return false;
var i = 5;
var w = 2;
while (i * i <= n) {
if (n % i === 0) {
return false;
}
i += w;
w = 6 - w;
}
return true;
}
// subtract 1 for 'not being prime' in my context
var sum = isPrime(num) ? num - 1 : -1;
for (var x = 0; x < num; x++) {
if (isPrime(x) === true) {
sum += x;
}
}
return sum;
}
here is my solution to sum of n prime number
function sumOfNPrimeNumber(num){
var sum = 0;
const isPrime = function(n){
if (isNaN(n) || !isFinite(n) || n%1 || n<2) {
return false;
}
if (n%2==0){
return (n==2);
}
var sqrt = Math.sqrt(n);
for (var i = 3; i < sqrt; i+=2) {
if(n%i == 0){
return false;
}
}
return true;
}
const getNextPrime = function* (){
let nextNumber = 2;
while(true){
if(isPrime(nextNumber)){
yield nextNumber;
}
++nextNumber;
}
}
const nextPrime = getNextPrime();
for (var i = 0; i < num; i++) {
sum = sum + nextPrime.next().value;
}
return sum;
}
console.log(sumOfNPrimeNumber(3));
All the above answers make use of helper functions or aren't time efficients.
This is a quick, recursive solution in O(n) time:
// # signature int -> int
// # interpr: returns sum of all prime integers <= num
// assume: num is positive integer
function sumPrimes(num) {
if (num <= 2) {
return 2;
}
let i = 2;
while (i < num) {
if (num % i === 0) {
return sumPrimes(num - 1)
}
i++;
}
return num + sumPrimes(num - 1)
}
// test
sumPrimes(10); // -> 17
function prime_sum(num){
let count=0; *//tracks the no of times number is divided perfectly*
for(let i=1;i<=num;i++){ *//from 1 upto the number*
if(num%i==0){count++};
}
if(count===2){return "Prime"};
return{"Not prime"};
}
console.log(prime_sum(10));//expected output is 17**
//the code receives a number,checks through the range and returns prime if it meets the condition
The following solution uses the Eratosthenes Sieve to sum all prime numbers lower than or equal to num. The first for loop fills an array with size equal to num with true. The second for loop sets to false all non-prime numbers in the array. Then, the last for loop simply iterates through the array to sum all the array indexes i for which the value in the array, i.e., array[i], is equal to true.
/**
* Sum all primes lower or equal than n.
* Uses the Eratosthenes Sieve to find all primes under n.
*/
function sumPrimes(num) {
let array = [];
let output = 0;
// Fill an array of boolean with 'true' from 2 to n.
for (let i = 0; i <= num; i++) {
array.push(true);
}
// Set all multiples of primes to 'false' in the array.
for (let i = 2; i <= Math.sqrt(num); i++) {
if (array[i]) {
for (let j = i * i; j <= num; j += i) {
array[j] = false;
}
}
}
// All array[i] set to 'true' are primes, so we just need to add them all.
for (var i = 2; i <= num; i++) {
if (array[i]) {
output += i;
}
}
return output;
}
console.log(sumPrimes(10)); // 17
console.log(sumPrimes(977)); // 73156
console.log(sumPrimes(250_000_000)); // 197558914577
function sumPrimes(num) {
let output = 0;
// check if num is a prime number
function isPrime(num) {
for(let i = 2; i < num; i++) {
if(num % i === 0) {
return false;
}
}
return true;
}
for (let i = 2; i <= num; i++) {
if (isPrime(i)) {
output += i;
}
}
return output;
}
console.log(sumPrimes(10)); // 17
This is what I've done to get primes. I don't know if it's the most efficient, but it works. This is in Java, but can be easily converted to JavaScript. Hopefully this will help point you in the right direction.
final int TOTAL = 10;
int primes[] = new int[TOTAL];
int arrPos = 2;
boolean prime = false;
primes[0] = 2;
for (int i = 2; i < TOTAL; i++) {
prime = false;
int sqrt = (int) Math.sqrt(i);
for (int j = 1; j < arrPos && primes[j] < sqrt; j++) {
if (i % primes[j] != 0) {
prime = true;
} else {
prime = false;
break;
}
}
if (prime == true) {
primes[arrPos] = i;
arrPos++;
}
}