Trying to find factors of a number in JS - javascript

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

Related

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.

Finding Least Common Multiple using Table Method

Find the least common multiple of the provided parameters using Table Method that can be evenly divided by both, as well as by all sequential numbers in the range between these parameters. There will only be two parameters. For ex [1,3], find the lcm of 1,2,3.
Note - It might create an infinite loop
function smallestCommons(arr) {
var nums = [];
var multiples = [];
if(arr[0]>arr[1]) {
var bigger = arr[0];
} else {
var bigger = arr[1];
}
for(var i=bigger;i>0;i--) {
nums.push(i);
console.log(i);
}console.log(nums + " nums");
var sums = 0;
while(sums != nums.length) {
for(var k=0;k<nums.length;k++) {
if(nums[k] % 2 === 0) {
nums[k] = nums[k]/2;
multiples.push(2);
} else if(nums[k] % 3 === 0) {
nums[k] = nums[k]/3;
multiples.push(3);
}else if(nums[k] % 5 === 0) {
nums[k] = nums[k]/5;
multiples.push(5);
}else if(nums[k] % 7 === 0) {
nums[k] = nums[k]/7;
multiples.push(7);
}else if(nums[k] === 1) {
break;
}else {
nums[k] = nums[k]/nums[k];
multiples.push(nums[k]);
}
}
for(var j = bigger; j>0;j--) {
sums = sums + nums[j];
}
}
var scm = [multiples].reduce(function(a,b){console.log(a*b)}); return scm
}
smallestCommons([1,5]);
I found this to be a simple solution, It works wonders;
Loop through all possible numbers, beginning with lower bound input (var i)
for every number, test divisibility by each number between and including input bounds (var j)
if i meets all criteria return it as answer, otherwise increment i by 1 and try again
click here for explanation of ? operator in variable initialization
function smallestCommons(arr) {
//set variables for upper and lower bounds
//incase they aren't entered in ascending order
var big = arr[0] < arr[1] ? arr[1]:arr[0],
small = arr[0] < arr[1] ? arr[0]:arr[1],
i = small;
//loop through all numbers, note the possibility of an infinite loop
while(true){
//test each number for divisibility by by both upper and lower
//bounds, as well as by all sequential numbers inbetween
for(var j = small; j <= big; j++){
if(i % j === 0){
if(j===big){
return i;
}
}else {
break;
}
}
i++;
}
}
smallestCommons([1,5]); //60
What you need is find the LCM in range (n, m) ?
Finding least common multiples by prime factorization seems better.
You can use Legendre's formula to find all prime factors of n! and m! , then just do a simple subtraction.

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

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.

Find first missing number in a sequence of numbers

I am trying to figure out how to find the first missing number of a sequence of numbers like this (1,2,3,5,6,9,10,15)
I want to put the first missing number, #4, into an variable for later use but don't know how to do so?
I have tried this but this only gives me the last number:
var mynumbers=new Array(1,2,3,6,9,10);
for(var i = 1; i < 32; i++) {
if(mynumbers[i] - mynumbers[i-1] != 1) {
alert("First missing number id: "+mynumbers[i]);
break;
}
}
First of all it gives me the first number after an "hole" in the numbersequence, secondly it continues to alert all numbers comming after an "hole" if I don't insert an break. I only want the first missing number of an numbersequence from 1 - 32. How do i do so?
Hoping for help and thanks in advance ;-)
How about this
var mynumbers = new Array(1,2,3,6,9,10);
var missing;
for(var i=1;i<=32;i++)
{
if(mynumbers[i-1] != i){
missing = i;
alert(missing);
break;
}
}
The O(n) solutions are easy , but this is a common interview question and often we look for O(log n) time solution. Here is the javascript code. It's basically a modified binary search.
function misingNumInSeq(source, min = 0, max = source.length - 1){
if(min >= max){
return min + 1;
}
let pivot = Math.floor((min + max)/2);
// problem is in right side. Only look at right sub array
if(source[pivot] === pivot + 1){
return misingNumInSeq(source, pivot + 1, max);
} else {
return misingNumInSeq(source, min , pivot);
}
}
Output
misingNumInSeq([1,2,3,5,6,9,10,15])
4
By if(mynumbers[i] - mynumbers[i-1] != 1), you mean to say the series will always be incrementing by 1?
var missing = (function (arr) {
var i;
for (i = 0; i < arr.length; ++i) {
if (i + arr[0] !== arr[i]) return i + arr[0];
}
if (i < 32) // if none missing inside array and not yet 32nd
return i + arr[0]; // return next
}([1,2,3,6,9,10])); // 4
alert(missing);
You're going to need the break no matter what. That's what it's there for; to stop the loop from continuing on to the end. And you should use the length of the array instead of hardcoding 32 as the end condition, because your numbers only go up to 32, but there are possibly holes in the list so there will not be 32 elements in the array.
Since you know that each element should be 1 more than the previous element, then the number in the hole is clearly mynumbers[i - 1] + 1.
var mynumbers = new Array(1,2,3,6,9,10);
for(var i = 1; i < mynumbers.length; i++) {
if(mynumbers[i] - mynumbers[i-1] != 1) {
alert("First missing number id: " + (mynumbers[i - 1] + 1));
break;
}
}
EDIT: This only holds true for the missing number not being 1. To catch that, you will need to check if (mynumbers[0] != 1)
Edit:
function findFirstMissing(array) {
for (var i = 0; i < array.length; i++) {
if (i+1 !== array[i]) {
return i+1;
}
}
}
function findFirstMissing(array) {
for (var i = 0; i < array.length; i++) {
if (array[i+1] - array[i] !== 1) {
return array[i] + 1;
}
}
}
If you do it this way then storing it in a variable is easy:
var missing = findFirstMissing(array);
const firstNonConsecutive = arr => arr.find((el, i, arr) => (arr[i] - arr[i-1]) !== 1 && i !== 0)
this solution work for an array of positive numbers.
A solution using array.reduce to find the first positive missing integer.
function solution(A) {
return [...A].sort().reduce((acc, curr, i, arr) => {
if (acc > curr) {
arr.splice(1);
return acc;
}
else if (arr[i + 1] - curr > 1 || arr.length === i + 1) {
arr.splice(1);
return curr + 1;
}
return acc;
}, 1);
}
And here are few test cases:
console.log('solution([1, 3, 6, 4, 1, 2])', solution([1, 3, 6, 4, 1, 2]) === 5)
console.log('solution([1, 3, 2, 8, 4])', solution([1, 3, 2, 8, 4]) === 5)
console.log('solution([1])', solution([1]) === 2)
console.log('solution([-1])', solution([-1]) === 1)
console.log('solution([0])', solution([0]) === 1)
console.log('solution([-1, -4, -5, -6, -190343])', solution([-1, -4, -5, -6, -190343]) === 1)
Sometimes you just want simple if you know it's a small array:
let numbers = [1,2,3,6,9,10]
let m = 0
for (const i of numbers) if (i > ++m) break
console.log(m) // 4
Works if you remove 1 from start of array:
numbers = [2,3,6,9,10]
m = 0
for (const i of numbers) if (i > ++m) break
console.log(m) // 1
If the array can be contiguous, and if so you want the next highest number, then:
numbers = [1,2,3,4,5,6,7,8,9]
m = 0
for (const i of numbers) if (i > ++m) break
if (m == Math.max(...numbers)) m++
console.log(m) // 10
Short and sweet!
//Find the missing number in a series
//output must be 12 in a table of 3 given in below series
let abc = [3, 6, 9, 15, 18, 21, 24];
var def = [],
ghi = [];
for (var i = 1; i <= abc.length; i++) {
if (i !== abc.length) {
var diff = abc[i] - abc[i - 1];
if (def.includes(diff) === false) {
def.push(diff);
} else {
ghi.push(diff);
}
}
}
var finalArr = [];
if (ghi.length > def.length) finalArr = ghi;
else finalArr = def;
var finaldiff = finalArr[0];
var finalVal = abc.find((e, i) => {
if (e !== abc.length) {
var diff = abc[i] - abc[i - 1];
return diff > finaldiff;
}
})
console.log(finalVal - diff);
for(var i = 1; i < mynumbers.length; i++) {
if(mynumbers[i] - mynumbers[i-1] != 1) {
alert("First missing number id: "+mynumbers[i-1]+1);
i = mynumbers.length; // Replace the break
}
}
If you want you can add an initial check : if (mynumbers[0] != 1) { ... }
I think this is the simplest and optimum form of just a 2-step solution.
I think no better solution can be possible for this problem than this one.
This code uses minimum no. of variables, loops, conditionals, built-in functions and all the shitty, sloppy, unnecessary code.
This code can handle array of any length.
var mynumbers = new Array(76,77,78,79,80,81,82,83,84,125);
if(mynumbers.length > 1) {
for(var i=0; i<=mynumbers.length-1; i++) {
if(mynumbers[i+1] - 1 !== mynumbers[i]) {
alert("First Missing Term is : "+parseInt(mynumbers[i]+1));
break;
}
}
}

Categories