Make a function that returns twenty two - javascript

I am trying to Write a function that a given array consisting of N integers, return the minimum among all integers which are multiples of 11.
let arr = [-6, -91, 1011, -100, 84, -22, 0, 1, 473]
function solution(A) {
let mult = A.filter(x => x % 11 == 0 && x / 11 >=0 && x / 11 < 1000).map(x => x / 11)
return mult
}
solution(arr)

function solution(arr){
let value = arr[i]
for (let i=0; i< arr.length;i++){
if(arr[i]%11 == 0)
{
if(arr[i] < value)
{
value = arr[i]
}
}
}
return value
}

The question should be broken into two parts, then solved.
First, get all the numbers that are divisible by 11, then find the minimum of them.
So, something like:
function getSmallestDivisibleBy11(arr) {
let divisibleBy11 = []
for (let i = 0; i < arr.length; i++){
if (arr[i] % 11 === 0){
divisibleBy11.push(arr[i])
}
}
let returnVal = Infinity;
for (let i = 0; i < divisibleBy11.length; i++){
if (divisibleBy11[i] < returnVal){
returnVal = divisibleBy11[i]
}
}
return returnVal
}

Logic
From the list of input array, filter the array where the number is divisible by 11. Condition number % 11 === 0.
This will give an array of numbers which are divisible by 11. Here it will be [-22, 0, 473].
To make pick the minimum value. Just sort the array and select the zeroth node of sorted array. Since the array of numbers divisible by 11 are already sorted the value for sorted array will be [-22, 0, 473] and the least value of them will be -22
let arr = [-6, -91, 1011, -100, 84, -22, 0, 1, 473]
function solution(list) {
const divisibleArray = list.filter(x => x % 11 == 0); // This will return all numbers which are divisible by 11
const sortedDivisibleArray = divisibleArray.sort((a, b) => a - b); // Sort the array. The minimum value will be zero th node of sorted array
return sortedDivisibleArray.length > 0 ? sortedDivisibleArray[0] : null;
}
const result = solution(arr);
console.log(result);
Single Line Solution
let arr = [-6, -91, 1011, -100, 84, -22, 0, 1, 473];
const solution = (list) => list.filter(x => x % 11 == 0).sort((a, b) => a - b)[0] || null;
const result = solution(arr);
console.log(result);

you can try this
function solution(A) {
var minElement = 100001;
arr.forEach(element => {
let e = element % 11;
if (e === 0 && e < minElement) {
minElement = element;
}
});
console.log(minElement);
return minElement;
}

You can first filter out multiples of 11 from the array and find the minimum among them.
You can use a for...of loop as given below
function solution(A) {
let mult11s = A.filter(x => x % 11 == 0);
let minMult11 = Number.POSITIVE_INFINITY;
for(const mult11 of mult11s){
minMult11 = Math.min(minMult11, mult11);
}
return minMult11;
}
or you can use reduce if you are comfortable with that.
function solution(A) {
return A
.filter(x => x % 11 == 0)
.reduce((acc, curr) => Math.min(acc, curr), Number.POSITIVE_INFINITY);
}

Related

Maintain the duplicates in the sum of array integers

I wrote a program to:
Print the new array of elements
Print the sum of all elements (or integers)
Actually, I got it right, however, the little problem is, I want to maintain all the duplicates (still within the range of four largest elements). Here's what I mean:
Take an array of numbers: [4,5,-2,3,1,2,6,6]
The four largest numbers are 4,5,6,6. And their sum is 4+5+6+6=21
What the code is doing (not good):
Instead of getting "6,6,5,4" as (described above), the code is printing "6,5,4,3" with the sum as 18.
ALSO, when there are only four elements [with or without duplicates] as in [1,1,1,-5],
let it just add ALL elements. You guessed it, the sum of all elements is -2
How do I order the program to print the necessary duplicate(s) to make the four largest integers?
Here's my code...
var arr = new Array(4,5,-2,3,1,2,6,6);
// var arr = new Array(1,1,1,-5);
// var largArr = new Array();
function largest() {
largArr = Array(0, 0, 0, 0)
for (i = 0; i < arr.length; i++) {
if (arr[i] > largArr[0]) {
largArr[0] = arr[i];
}
}
for (i = 0; i < arr.length; i++) {
if (arr[i] > largArr[1] && arr[i] < largArr[0]) {
largArr[1] = arr[i];
}
}
for (i = 0; i < arr.length; i++) {
if (arr[i] > largArr[2] && arr[i] < largArr[1]) {
largArr[2] = arr[i];
}
}
for (i = 0; i < arr.length; i++) {
if (arr[i] > largArr[3] && arr[i] < largArr[2]) {
largArr[3] = arr[i];
}
}
console.log(largArr[0], largArr[1], largArr[2], largArr[3]);
console.log(largArr[0] + largArr[1] + largArr[2] + largArr[3]);
}
largest();
I believe there is a genius out there who can help me solve this :)
You could get the top four and filter the original array.
function get4Largest(array) {
const top4 = [...array].sort((a, b) => b - a).slice(0, 4);
return array.filter(v => {
if (top4.includes(v)) {
top4.splice(top4.indexOf(v), 1);
return true;
}
});
}
console.log(get4Largest([4, 5, -2, 3, 1, 2, 6, 6]));
A different approach by keeping indices.
function get4Largest(array) {
return array
.map((v, i) => [v, i])
.sort(([a], [b]) => b - a)
.slice(0, 4)
.sort(([, a], [, b]) => a - b)
.map(([v]) => v);
}
console.log(get4Largest([4, 5, -2, 3, 1, 2, 6, 6]));
If you want sum of largest four numbers then you can easily do with sort, slice and reduce:
numbers.sort((a, b) => b - a).slice(0, 4).reduce((acc, curr) => acc + curr, 0)
const numbers = [4, 5, -2, 3, 1, 2, 6, 6];
const result = numbers
.sort((a, b) => b - a)
.slice(0, 4)
.reduce((acc, curr) => acc + curr, 0);
console.log(result);
You can use a reduce, sort and slice methods of an array like so:
function sumMaxValues (maxLength, values) {
return values
.sort((v1, v2) => v1 > v2 ? -1 : 1)
.slice(0, maxLength)
.reduce((sum, v) => sum + v, 0)
}
console.log(
sumMaxValues(4, [4, 5, -2, 3, 1, 2, 6, 6, 10]),
)
Edit: I fixed, a bug that #gog pointed out. The root cause of a problem was that sort when invoked without a compareFn then "the array elements are converted to strings, then sorted according to each character's Unicode code point value."(sort docs)
If for some reason you want to have a classical type of solution, that avoids modern javascript methods, here's one
const arr = Array(4, 5, -2, 3, 1, 2, 6, 6);
//const arr = Array(1, 1, 1, -5);
function largest(){
const largArr = Array(-1/0, -1/0, -1/0, -1/0);
for(let i = 0; i < arr.length; i++){
for(let j = 0; j < largArr.length; j++){
if(arr[i] > largArr[j]){
for(let k = largArr.length - 2; k >= j; k--){
largArr[k + 1] = largArr[k];
}
largArr[j] = arr[i];
break;
}
}
}
let sum = 0;
for(let j = 0; j < largArr.length; j++){
if(largArr[j] === -1/0){
largArr[j] = 0;
}
sum += largArr[j];
}
console.log(largArr, sum);
}
largest();
-1/0 stands for minus infinity (there can be no smaller number); you may also use Number.NEGATIVE_INFINITY for it. If it's too exotic for your needs, replace -1/0 with any number you are certain is less than any possible number in the array (that however, cannot be zero, since you allow negative numbers also).

i cant get the right result of the contiguous subarray of arr with the maximal sum of items

so i found a solution for this mathematical problem which is this one
function getMaxSubSum(arr) {
let maxSum = 0;
let partialSum = 0;
for (let item of arr) { // for each item of arr
partialSum += item; // add it to partialSum
maxSum = Math.max(maxSum, partialSum); // remember the maximum
if (partialSum < 0) partialSum = 0; // zero if negative
}
return maxSum;
}
alert ( getMaxSubSum([1,-2,3,9,-9,6]) )
BUT i want to achieve it with another way and im trying this code
function kadane () {
arr = [1,-2,3,9,-9,6]
let maxSub = maxGlobal = arr[0]
for (i=3 ; i<arr.length-1; i++ ) {
maxSub = Math.max(arr[i], maxSub + arr[i])
if (maxSub > maxGlobal) {
maxSub = maxGlobal
}
}
return maxSub
}
alert (kadane())
does anyone know what im doing wrong?
Your solution were really close !
Here you inverted maxSub and maxGlobal in the if section.
Also, I don't know why but your for loop where starting at 3 instead of 1.
Here is your working example
function kadane(arr) {
let maxSub = arr[0]
let maxGlobal = arr[0]
for (i = 1; i < arr.length; i++) {
maxSub = Math.max(arr[i], maxSub + arr[i])
if (maxSub > maxGlobal) {
maxGlobal = maxSub
}
}
return maxGlobal
}
const arr = [1, -2, 3, 9, -9, 6]
alert(kadane(arr))
A little more...
Also, note that you could also have checked the maximum of 2 numbers consecutively.
Example using Array#reduce
function kadane(arr) {
return arr.reduce((acc, curr, index) => {
if(index === 0) return curr > 0 ? curr : 0
else {
const sum = curr + arr[index-1]
return sum > acc ? sum : acc
}
}, 0)
}
console.log(kadane([1, -2, 3, 9, -9, 6]))
console.log(kadane([-1, -2, -3, -4, -5, -6]))

Return indexes of greatest value in a 3 dimensional array using JavaScript

I have an array of this:
[34, 12, 56]
[100,125,19]
[30,50,69]
125 has been the highest value, it will return the index [1,1] format. Meaning 125 which is the highest value will return row 1 column 1
I was able to get the index in an array using this code
var a = [0, 21, 22, 7, 12];
var indexOfMaxValue = a.reduce((iMax, x, i, arr) => x > arr[iMax] ? i :
iMax, 0);
document.write("indexOfMaxValue = " + indexOfMaxValue); // prints
"indexOfMaxValue = 2"
Here's my approach. It flattens out all the arrays into more managable one, finds the max number and its index, and then calculates it's position using some math. Using a single array makes this calculation much easier.
const arr = [[34, 12, 56], [100,125,19], [30,50,69]];
const arr2 = [0, 21, 22, 7, 12];
function findHighest(arr) {
// Get the number of columns
const cols = arr.length;
// Flatten out the arrays
const tempArr = arr.flatMap(el => el);
// Get the max number from the array
const max = Math.max.apply(null, tempArr);
// Find its index
const indexMax = tempArr.findIndex(el => el === max);
// Find the remainder (modulo) when you divide the index
// by the number of columns
const mod = indexMax % cols;
// Return the final array output
return [Math.floor(indexMax / cols), mod];
}
console.log(findHighest(arr))
console.log(findHighest(arr2))
This will give the expected output but not sure is it good way to solve this:
var arr = [
[34, 12, 56],
[100, 125, 19],
[30, 50, 69]
];
var maxValue, maxIndex;
arr.forEach((arr1, i) => {
arr1.forEach((value, j) => {
if (i == 0 && j == 0) {
maxValue = value;
maxIndex = [i, j]
} else {
if (maxValue < value) {
maxValue = value;
maxIndex = [i, j];
}
}
});
});
console.log("Max Number Index", maxIndex);
If you mean 2d solution, try this. Should work for dynamic length arrays
This should be extendable with a new forEach for a new dimension
[100,125,19],
[30,50,69]];
maxIndex = [-1, -1];
maxElem = 0;
input.forEach(function(arr, row) {
console.error(row);
arr.forEach(function(e, col) {
if( maxElem <= e ) {
maxElem = e;
maxIndex = [row, col];
}
})
})
console.log(maxIndex)

Why is this Javascript code returning the last number only?

I have a Javascript array which I wanted to slice and put in a new array, but the new array prints out only the last value.
I tried using for loop
let array = [5, 6, 9, 7, 10, 17, 20, 35, 105, 140];
let slicedArray;
const removeNumbers = () => {
for (let i = 0; i < array.length; i++) {
if (array[i] % 5 === 0 && array[i] % 7 === 0) {
slicedArray = [...array.splice(i, 1)];
}
}
return slicedArray;
}
console.log(removeNumbers());
I expected 35,105, and 140 as an output, but the actual output is just 140.
Use .filter instead, to create a new array based on elements of a different array that pass a test:
let array = [5, 6, 9, 7, 10, 17, 20, 35, 105, 140];
const newArr = array.filter(num => num % 5 === 0 && num % 7 === 0);
console.log(newArr);
If you have to mutate the existing array as well, then push the spliced element to the new array while splicing (don't reassign the slicedArray, just push to it):
const array = [5, 6, 9, 7, 10, 17, 20, 35, 105, 140];
const removeNumbers = () => {
const slicedArray = [];
for (let i = 0; i < array.length; i++) {
if (array[i] % 5 === 0 && array[i] % 7 === 0) {
slicedArray.push(...array.splice(i, 1));
// Need to subtract 1 from i here, so that this removed index gets iterated over again next time
i--;
}
}
return slicedArray;
}
console.log(removeNumbers());
7 is not included because it's not a multiple of 5.
Try pushing the elements in the array like this:
let array = [5,6,9,7,10,17,20,35,105,140];
let slicedArray;
const removeNumbersTest = () => {
for(let i = 0; i < array.length; i++){
if(array[i] % 5 === 0 && array[i] % 7 === 0){
slicedArray.push(...array.splice(i,1));
}
}
return slicedArray;
}
The code above should do what you wanted it to do, just check the logic before pushing the elements in the array.
Hope it helps!
You should only be getting 35, 105 and 140 according to your if statement. Since you want your numbers to bi divisible by 5 and 7.
The problem was you did not append your numbers in the array and mutated the array when using splice method. Because of mutation number 105 wasn't included.
let array = [5, 6, 9, 7, 10, 17, 20, 35, 105, 140];
let slicedArray = [];
const removeNumbers = () => {
for (let i = 0; i < array.length; i++) {
if (array[i] % 5 === 0 && array[i] % 7 === 0) {
slicedArray = [...slicedArray, ...[...array].splice(i, 1)];
}
}
return slicedArray;
}
console.log(removeNumbers());
You simply can push the target items on the slicedArray:
let array =[5,6,9,7,10,17,20,35,105,140];
const slicedArray=[]; //Array is mutable with const keyword
const removeNumbers= () =>{
for(let i=0; i<array.length; i++){
if(array[i] % 5 === 0 && array[i] % 7 === 0){
slicedArray.push(array[i]);
}
}
return slicedArray;
}
console.log(removeNumbers());
Two problems with your code and some minor issues:
array.slice() returns removed items and you have to collect them sequentially.
Solution: Push the items returned from array.slice() to the collecting array using array.push().
array.slice() modifies the array in place. Say the current index i is set to 7, that item 35 gets removed by the slicing operation from array. But now the next number 105 is shifted one position downwards. The for-loop continues with index 8 which now contains number 140.
Solution: Modify the for-loop index when an item is removed.
The naming slicedArray is misleading. Better name would be removedNumbers.
The variable removedNumbers should be a local to the function removeNumber().
Using a global variable array is not perfect. Maybe you would like to change your code to removeNumbers() takes a parameter. I omitted this fix from my example.
A fixed solution could look like:
(Please note the i-- which fixes the index to test in the next for-loop iteration the same position again.)
let array = [5,6,9,7,10,17,20,35,105,140];
const removeNumbers = () => {
let removedNumbers = [];
for(let i=0; i<array.length; i++){
if(array[i] % 5 === 0 && array[i] % 7 === 0) {
removedNumbers.push(...array.splice(i--,1));
}
}
return removedNumbers;
}
console.log("Removed numbers:", removeNumbers());
console.log("Remaining numbers:", array);
If you expect 7, 35,105, and 140 then append to the list and change your if to
if (array[i] % 7 === 0 && array[i] % 5 === 0)

Highest Product you can get from k of the integers

I am working on the following problem:
Given an arrayOfInts, find the highestProduct you can get from k of the integers.
This is the solution I have come up with so far based on a generalization of getting the highestProduct from 3 of the integers.
var getHighestProductOfk = function (arrayOfInts, k) {
if (arrayOfInts.length < k) {
throw Error('Array should be higher than k');
}
highestProductArray = [arrayOfInts[0]];
lowestProductArray = [arrayOfInts[0]];
for (let i=1; i<k; i++) {
highestProductArray[i] = highestProductArray[i-1]*arrayOfInts[i];
lowestProductArray[i] = lowestProductArray[i-1]*arrayOfInts[i];
}
for(let i=1; i<arrayOfInts; i++) {
let currentInt = arrayOfInts[i];
for(let j=k-1; j>=0; j--) {
highestProductArray[j] = Math.max(
highestProductArray[j],
highestProductArray[j-1]*currentInt,
lowestProductArray[j-1]*currentInt
);
lowestProductArray[j] = Math.min(
lowestProductArray[j],
lowestProductArray[j-1]*currentInt,
highestProductArray[j-1]*currentInt
);
}
// highest number
highestProductArray[0] = Math.max(highestProductArray[0], currentInt)
// lowest number
lowestProductArray[0] = Math.max(lowestProductArray[0], currentInt)
}
return highestProductArray[k-1];
}
Any idea what I do wrong?
for the following example [1, 10, -5, 1, -100], the result is -50 instead of 5000.
lowest number is 1 and the highest is 1 instead of -100 and 10
The solution for the highestProduct of three of the integers:
var getHighestProductOfThree = function (arrayOfInts) {
if (arrayOfInts.length < 3) {
throw Error('Array should be higher than 3');
}
let highestProductOfThree = arrayOfInts[0]*arrayOfInts[1]*arrayOfInts[2];
let highestProductOfTwo = arrayOfInts[0]*arrayOfInts[1];
let lowestProductOfTwo = arrayOfInts[0]*arrayOfInts[1];
let highest = arrayOfInts[0];
let lowest = arrayOfInts[0];
for (let i=1; i<arrayOfInts.length; i++) {
let currentInt = arrayOfInts[i];
highestProductOfThree = Math.max(
highestProductOfThree,
highestProductOfTwo*currentInt,
lowestProductOfTwo*currentInt
);
highestProductOfTwo = Math.max(
highestProductOfTwo,
currentInt*highest,
currentInt*lowest
);
lowestProductOfTwo = Math.min(
lowestProductOfTwo,
currentInt*lowest,
currentInt*highest
);
highest = Math.max(
highest,
currentInt
);
lowest = Math.min(
lowest,
currentInt
);
}
return highestProductOfThree;
}
Here's an idea. Sort the numbers. Next, pick from the largest positive numbers as many as you can, up to k of them. Now pick the largest even group from the smallest negative numbers that form a larger product than the smallest positive numbers, which we will replace with them. (There are some edge cases, such as only one negative and k - 1 positives).
Pick 3 from [1, 10, -5, 1, -100]
Sort => [-100,-5,1,1,10]
Pick largest positives => 10 * 1 * 1
Pick largest even number of smallest negatives we can,
whose product is greater than the one replaced
=> (-100) * (-5) > 1 * 1
Answer => 10 * (-100) * (-5)
Based on my preliminary thoughts, I suggest to sort the values ascending, take the highest value, if the count is odd and use the rest with pairs.
This keeps a positive product with a loop until all needed factors are used.
In a while loop with a check for count, the pairs are chosen, if the product is greate than of the beginning of the array. This includes negative numbers, but works for only positive or negative numbers as well.
function getHighestProductOfK(a, k) {
var p = 1;
a.sort(function (a, b) { return a - b; });
if (k > a.length || k & 2 && a[a.length - 1] < 0) {
return;
}
if (k % 2) {
p = a.pop();
k--;
}
while (k) {
p *= a[0] * a[1] > a[a.length - 2] * a[a.length - 1] ? a.shift() * a.shift() : a.pop() * a.pop();
k -= 2;
}
return p;
}
console.log(getHighestProductOfK([1, 10, -5, 1, -100], 3));
console.log(getHighestProductOfK([3, 4, 5, 6, 7], 3));
console.log(getHighestProductOfK([-3, -4, -5, -6, -7], 3));
console.log(getHighestProductOfK([3, 4, -5, -6, -7], 3));
Needs some testing to make sure it always gives good answers..
function largestProduct(k, arr) {
if (k > arr.length) throw new RangeError('Not enough numbers');
let pos = [],
neg = [];
arr.forEach(e => {
if (e >= 0) pos.push(e);
else neg.push(e);
});
pos.sort((a, b) => a < b); // 9, 8, 7, ...
neg.sort((a, b) => a > b); // -9, -8, -7, ...
if (pos.length === 0 && k % 2) // k requires odd number of negatives
return neg.slice(-k); // give the smallest number TODO: same return
let big = [];
while (k > 1) grow();
if (k === 1) { // we've reached the end of doubles but still need more
if (pos.length) big.push(pos[0]);
else { // ran out of positives, backtrack
big = big.slice(0, -1);
big.push(neg[0], neg[1]);
}
}
return {
factors: big,
product: big.reduce((a, b) => a * b, 1)
};
function grow() { // choose the next best number
let doublepos = pos[0] * pos[1],
doubleneg = neg[0] * neg[1];
if (doublepos > doubleneg || doubleneg !== doubleneg) {
big.push(pos[0]);
pos = pos.slice(1);
k -= 1;
} else {
big.push(neg[0], neg[1]);
neg = neg.slice(2);
k -= 2;
}
}
}

Categories