I am trying to see if I can get my function to determine the "odd man out" in the array living within the function. Specifically, after I take a string, convert it into numbers and push it into an array -- I want it to be able to loop through the output array and return the index of which number is "the odd man out" (i.e. "2 2 2 2 4 6 8 1" should return index 7 as it is the only odd number). However, I'm having trouble figuring out how to return the index, when the function faces both situations that I listed below in the code.
function notSame(numbers){
var notString = parseInt(numbers.replace(/\s+/g, ''), 10),
sNumber = notString.toString(),
output =[];
console.log(sNumber);
for(var i = 0; i < sNumber.length; i+=1) {
output.push(+sNumber.charAt(i));
}
for(var num1 = 0; num1 < output.length; num1++) {
for(var num2 = 1; num2 < output.length; num2++) {
if(output[num1] % output[num2] === 1) {
return num1;
}
}
}
}
notSame("2 2 2 2 4 6 8 1"); /// Situation 1: should output index 7 as it is the only odd number
notSame("5 7 9 2 1" ); ///Situation 2: should output index 4 as it is the only even number
Once you have your integers in the output array,
// test the first three array members
var test = Math.abs(output[0])%2 + Math.abs(output[1])%2 + Math.abs(output[2])%2;
// if the sum of the mods of the first three integers in the
// array is more than 1, the array is mostly odd numbers, hence
// the odd one out will be even, else it will be odd
var outlierIsOdd = test >= 2 ? false : true;
// find the odd one out and return it's index
return output.indexOf(output.filter(function(e){
return (Math.abs(e)%2 === +outlierIsOdd);
})[0]);
You might find it easier to break down the problem into smaller units.
// return an array from a string
function toArray(str) { return str.split(' '); }
// return the element if it's even
function even(el) { return el % 2 === 0; }
// return the index of either true/false
function getIndex(arr, flag) { return arr.indexOf(flag); }
// count how many instances of true are in the array
function count(arr) {
return arr.filter(function (el) {
return el;
}).length;
}
function check(str) {
// return an array of true/false values
var evens = toArray(str).map(even);
// if there is more than 1 true value in `evens`
// return the index of false from the array
// otherwise return the index of the only true element
return count(evens) > 1 ? getIndex(evens, false) : getIndex(evens, true);
}
check('2 2 2 2 4 6 8 1'); // 7
check('5 7 9 2 1'); // 3
check('2 5 2 6 6'); // 1
check('7 7 7 9 1 3 8 1 5') // 6
DEMO
function notSame(string) {
var even = [];
var odd = [];
string.split(" ").forEach(function(e, i) {
string.split(" ")[i] % 2 ? odd.push(i) : even.push(i);
})
even > odd ? document.write(even) : document.write(odd);
}
notSame("2 2 2 2 4 6 8 1");
Fill up 2 arrays with index:
one for odds and one for evens and compare the length.
Related
This question already has answers here:
What is the purpose of the var keyword and when should I use it (or omit it)?
(19 answers)
Does return stop a loop?
(7 answers)
Closed 12 months ago.
I'm a beginner in JavaScript and doing an online test to improve my skills. I came across to this question:
Add 1 point for each even number in the array
Add 3 points for each odd number in the array
Add 5 points every time the number 5 appears in the array
So if I am given this array as an example:
([1,2,3,4,5])
the output should be 13
This is what I have got so far:
export function find_total( my_numbers ) {
for(let i = 0; i < my_numbers.length; i++){
if(my_numbers[i] % 2 === 0) {
total = total + 1
}
if(my_numbers[i] % 2 === 1) {
total = total + 3
}
if(my_numbers[i] === 5) {
total = total + 5
}
return total
}
console.log(total)
}
But it is giving me errors. I get the logic in English but couldn't put it in JS.
What would be the right syntax here?
The problem is with your if statements.
function find_total( my_numbers ) {
let total = 0;
for(let i = 0; i < my_numbers.length; i++){
if(my_numbers[i] === 5) {
total = total + 5
}
else if(my_numbers[i] % 2 === 0) {
total = total + 1
}
else if(my_numbers[i] % 2 === 1) {
total = total + 3
}
}
return total;
}
console.log(find_total([1,2,3,4,5]))
This code should print the correct result of 13.
You were not getting an answer of 13 because 5 is odd so has 3 point and 5 point exclusive to 5. The key is not to treat 5 as having point of odd number but having it's own point irrespective of either it is odd or even.
There are following issues in your code:
total in the function find_total is never initialized
return statement is misplaced inside the for loop, it must be outside, signifying return value of the function find_total
Better to console.log the value of the function, instead of logging it inside. eg. console.log(find_total(...))
Fixing these, you will indeed get the return value as 16 for input [1, 2, 3, 4, 5] as pointed out in the comments.
function find_total(my_numbers) {
let total = 0 // Initialize total with a value of 0
for (let i = 0; i < my_numbers.length; i++) {
if (my_numbers[i] % 2 === 0) {
total = total + 1
}
if (my_numbers[i] % 2 === 1) {
total = total + 3
}
if (my_numbers[i] === 5) {
total = total + 5
}
}
return total // return outside the loop
}
console.log(find_total([1, 2, 3, 4, 5])) // console.log outside
This question already has answers here:
How do I extract even elements of an Array?
(8 answers)
How to do a script for odd and even numbers from 1 to 1000 in Javascript?
(8 answers)
Closed 2 years ago.
I've spent an embarrassing amount of time on this question only to realize my function is only right 50% of the time. So the goal here is to return only the odd numbers of all the numbers in between the two arguments. (for instance if the arguments are 1 and 5 i'd need to return 2 & 3) the function I wrote is completely dependent on the first argument. if it's even my function will return odds, but if the first number is odd it'll return evens. does anyone know how i can fix this?
function oddNumbers(l, r) {
const arr = [];
const theEvens = [];
for (let i= l; i<r; i++) {
arr.push(i)
}
console.log(arr)
for (let i= 0; i < arr.length; i+= 2 ) {
const evens = arr[0] + i;
theEvens.push(evens);
}
theEvens.forEach(item => arr.splice(arr.indexOf(item), 1));
console.log(arr)
}
oddNumbers(2, 20);
I modified the code a bit to return only odd numbers
We use the % operator that behaves like the remainder operator in math:
so when we say i % 2 if the number is even the result of the operation will be 0
but when the "i" is an odd number the result will be 1
so now we can filter the even from the odd numbers using this operation
function oddNumbers(l, r) {
const arr = [];
for (let i= l; i<r; i++) {
if(i % 2 !== 0) arr.push(i);
}
console.log(arr);
}
oddNumbers(2, 20);
You can loop from initial to end parameters and get odd numbers using modulo, try this:
let result = [];
let returnOdd = (n1, n2) => {
for(i = n1; i < n2; i++){
if(i % 2 != 0){
result.push(i)
}
}
return result;
}
console.log(returnOdd(2, 20));
You could use the filter method.
This method creates a new array based on the condition it has. In this case it will to go through all the numbers in the array, and check if the number is odd (though the remainder operator).
For example:
1 % 2 = 1 ( true, keep in the new array )
2 % 2 = 0 ( false ignore in the new array )
function OddNumbers(start, end) {
// Create an array from the given range
const nums = Array(end - start + 1).fill().map((_, idx) => start + idx);
// Use filter to return the odd numbers via the % operator
return nums.filter(num => num % 2);
}
console.log(OddNumbers(2,20))
I'm trying to get an odd number and even numbers in a given string, and the return value should be an index of the odd number or even number.
for example
oddOrEvenValue('2 4 9 6 10'); // => should return 3 as an index of odd number in the string
oddOrEvenValue('1 4 5 11'); // => should return 2 as an index of even number in the string
This is my code
const oddOrEvenValue = str => {
//convert the string into an array
let strToArr = str.split(' ');
//filtering the Even numbers
const evenNumbers = strToArr.filter(e => e % 2 === 0);
//filtering Odd numbers
const oddNumbers = strToArr.filter(od => od % 2 !== 0);
//comparing the even and odd arrays
if(Number(evenNumbers.length) > Number(oddNumbers.length)) {
return oddNumbers;
} else {
return evenNumbers;
}
}
console.log(oddOrEvenValue('2 4 9 6 10')); // => 3 is the index of an odd number
so i'm wondering how to get the index of an odd number instead of getting the the number itself?
const oddOrEvenValue = str => {
//convert the string into an array
let strToArr = str.split(' ');
//filtering the Even numbers
const evenNumbers = strToArr.filter(e => e % 2 === 0);
//filtering Odd numbers
const oddNumbers = strToArr.filter(od => od % 2 !== 0);
//comparing the even and odd arrays
if(Number(evenNumbers.length) > Number(oddNumbers.length)) {
return oddNumbers;
} else {
return evenNumbers;
}
}
console.log(oddOrEvenValue('2 4 9 6 10'));
Use the indexOf array method.
const oddOrEvenIndex = str => {
//convert the string into an array
let strToArr = str.split(' ');
//filtering the Even numbers
const evenNumbers = strToArr.filter(e => e % 2 === 0);
//filtering Odd numbers
const oddNumbers = strToArr.filter(od => od % 2 !== 0);
//comparing the even and odd arrays
if(evenNumbers.length > oddNumbers.length) {
return strToArr.indexOf(oddNumbers[0]);
} else {
return strToArr.indexOf(evenNumbers[0]);
}
}
console.log(oddOrEvenIndex('2 4 9 6 10'));
console.log(oddOrEvenIndex('1 4 5 11'));
The length property is always a number, there's no need to convert it with the Number() function.
Also, array indexes start from 0. If you want the result to be 1-based, add + 1 to the return statements.
Iterate over the whole array, check if value is odd or even, then store the index of that value into evenNumberIndexes/ oddNumberIndexes accordingly.
const oddOrEvenIndex = str => {
//convert the string into an array
let strToArr = str.split(' ');
let evenNumberIndexes = [];
let oddNumberIndexes = [];
// iterate over array
for (var i = 0; i < strToArr.length; i = i + 1) {
// CHeck if number is odd or even and add the index to the arrays accordingly
if (strToArr[i] % 2 ==0) {
evenNumberIndexes.push(i+1);
} else {
oddNumberIndexes.push(i+1);
}
}
// comparing the even and odd arrays
if(Number(evenNumberIndexes.length) > Number(oddNumberIndexes.length)) {
return oddNumberIndexes;
} else {
return evenNumberIndexes;
}
}
console.log(oddOrEvenIndex('2 4 9 6 10'));
console.log(oddOrEvenIndex('1 4 5 11'));
console.log(oddOrEvenIndex('2 4 9 6 10 8 9 9 6 6'));
This question already has answers here:
Looping through array and removing items, without breaking for loop
(17 answers)
Closed 2 years ago.
I'm making a function to create a list of prime numbers from 0 to num. I start off with a list of integers from 2 to num, and iterate over each one that goes from 2 to i < num; if at any point item % i === 0, the item is removed from the list. This works fine:
function getPrimes(num) {
// get list of ints from 2 to num
let primes = [...Array(num + 1).keys()];
primes = primes.splice(2);
let lastNumber = primes[primes.length - 1];
// make iterable, run its loop
// for each number in primes
for (let number of primes) {
// use iterable to remove if not prime
for (let i = 2; i < num; i++) {
if (number % i === 0) {
primes.splice(primes.indexOf(number), 1);
}
}
}
// add back two
primes.unshift(2);
return primes;
But when I try and make the iterable for each number only to up to Math.floor(num / 2) for the sake of efficiency, it breaks the code somehow:
function getPrimes(num) {
// get list of ints from 2 to num
let primes = [...Array(num + 1).keys()];
primes = primes.splice(2);
let lastNumber = primes[primes.length - 1];
// make iterable, run its loop
// for each number in primes
for (let number of primes) {
// use iterable to remove if not prime
for (let i = 2; i < Math.floor(num / 2); i++) {
if (number % i === 0) {
primes.splice(primes.indexOf(number), 1);
}
}
}
// add back two
primes.unshift(2);
return primes;
When I tried it out, getPrimes(10) gives me [ 2, 3, 5 ]. So seven is missing from the list of prime numbers from 0 to 10. Why is that? I checked and 7 modulo 2, 3, and 4 returns 1, 1, and 3, respectively. So why is the code in the loop running that removes 7 from primes? It's the only place in the code where I put that I wanted to remove a number from the array.
The first issue is that you are looping while removing items, which causes some items to be skipped. Loop backwards instead, so that only items that have already been checked are shifted. Second, num / 2 should be changed to Math.sqrt(number), as that is the maximum factor that needs to be checked before we can be sure that a number is prime. With this method, there is no need to add 2 back to the array.
function getPrimes(num) {
// get list of ints from 2 to num
let primes = [...Array(num + 1).keys()];
primes = primes.splice(2);
let lastNumber = primes[primes.length - 1];
// make iterable, run its loop
// for each number in primes
for(let i = primes.length - 1; i >= 0; i--){
let number = primes[i];
// use iterable to remove if not prime
for (let j = 2; j * j <= number; j++) {
if (number % j === 0) {
primes.splice(i, 1);
break;
}
}
}
return primes;
}
console.log(...getPrimes(10));
Given the triangle of consecutive odd numbers:
1
3 5
7 9 11
13 15 17 19
21 23 25 27 29
// Calculate the row sums of this triangle from the row index (starting at index 1) e.g.:
rowSumOddNumbers(1); // 1
rowSumOddNumbers(2); // 3 + 5 = 8
I tried to solve this using for loops:
function rowSumOddNumbers(n){
let result = [];
// generate the arrays of odd numbers
for(let i = 0; i < 30; i++){
// generate sub arrays by using another for loop
// and only pushing if the length is equal to current j
let sub = [];
for(let j = 1; j <= n; j++){
// if length === j (from 1 - n) keep pushing
if(sub[j - 1].length <= j){
// and if i is odd
if(i % 2 !== 0){
// push the i to sub (per length)
sub.push(i);
}
}
}
// push everything to the main array
result.push(sub);
}
// return sum of n
return result[n + 1].reduce(function(total, item){
return total += item;
});
}
My code above is not working. Basically I was planning to 1st generate an array of odd numbers less than 30. Next I need to create a sub array base on the length of iteration (j) that would from 1 - n (passed). Then finally push it to the main array. And then use reduce to get the sum of all the values in that index + 1 (since the index starts at 1).
Any idea what am I missing and how to make this work?
Most code problems involve some analysis first in order to spot patterns which you can then convert into code. Looking at the triangle, you'll see the sum of each row follows a pattern:
1: 1 === 1 ^ 3
2: 3 + 5 = 8 === 2 ^ 3
3: 7 + 9 + 11 = 27 === 3 ^ 3
... etc
So from the analysis above you can see that your code could probably be simplified slightly - I won't post an answer, but think about using Math.pow.
No need for any loops.
function rowSumOddNumbers(n) {
// how many numbers are there in the rows above n?
// sum of arithmetic sequence...
let numbers_before_n_count = (n - 1) * n / 2;
let first_number_in_nth_row = numbers_before_n_count * 2 + 1;
let last_number_in_nth_row = first_number_in_nth_row + 2 * (n - 1);
// sum of arithmetic sequence again...
return n * (first_number_in_nth_row + last_number_in_nth_row) / 2;
}