Number Array and user input - javascript

I need to write a code that will prompt the user for five integer numbers and then determine the product and sum of the values.
It needs to use an array to enter the values, use a for loop to display the numbers and product, a while loop to display numbers and their sum, and then an HTML line that will display "the sum of x y and z is: sum and the product of x y and z is: product". I have this so far, can anyone help me out?
var array = [1, 2, 3, 4, 5, 6],
s = 0,
p = 1,
i;
for (i = 0; i < array.length; i += 1) {
s += array[i];
p *= array[i];
}
console.log('Sum : '+s + ' Product : ' +p);

Using ECMAScript 6, here's one way to do this:
let numbersToEnter = 5;
let numbersEntered = [];
while (numbersToEnter) {
numbersEntered.push(parseInt(prompt(`Enter a number, ${numbersToEnter--} to go:`)));
}
// filter out non-numbers
numbersEntered = numbersEntered.filter(n => !isNaN(parseInt(n)));
const sum = numbersEntered.reduce((acc, val) => acc + val, 0);
const product = numbersEntered.reduce((acc, val) => acc * val, 1);
console.log(`You entered these numbers: ${numbersEntered}`);
console.log(`Sum is ${sum}`);
console.log(`Product is ${product}`);

Related

Filter Specific Numbers and Sum Up

Given:
I have an array that looks like this:
[1, 1, 3, 3, 3, 2, 2, 1, 3, 3, 2, 3, 4, 2, 3, 4, 4, 2, 1, 3, 2, 4, 3, 2];
What I need:
scoreN = sum up all numbers with one
scoreST = sup all numbers with two
scoreO = sum up all numbers with three
scoreAA = sum up all numbers with four
totalScore = scoreN + scoreST + scoreO + scoreAA
Question:
What is the simplest (beginner friendly) JS code to filter the numbers and get the sum?
const array = [1, 1, 3, 3, 3, 2, 2, 1, 3, 3, 2, 3, 4, 2, 3, 4, 4, 2, 1, 3,2, 4, 3, 2];
Something like?
const scoreN = array.filter(1);
const scoreST = array.filter(2);
const scoreO = array.filter(3);
const scoreAA = array.filter(4);
const totalScore = scoreN + scoreST + scoreO + scoreAA
Your approach was quite correct.
But the array method filter takes a function which you can express with a lambda function x => x === 1 in which the argument x represents the current array value. The return value should be a boolean, in this case we want all numbers equal to 1.
The function reduce takes 2 arguments a function with the previous value and the current value and a default value if the array is empty. In this case 0 if there are no elements to sum up.
const numbers = [1, 1, 3, 3, 3, 2, 2, 1, 3, 3, 2, 3, 4, 2, 3, 4, 4, 2, 1, 3, 2, 4, 3, 2];
const sum = (a, b) => a + b;
const scoreN = numbers.filter(x => x === 1).reduce(sum, 0);
const scoreST = numbers.filter(x => x === 2).reduce(sum, 0);
const scoreO = numbers.filter(x => x === 3).reduce(sum, 0);
const scoreAA = numbers.filter(x => x === 4).reduce(sum, 0);
const total = scoreN + scoreST + scoreO + scoreAA;
console.log(total);
Yep, using filter you can filter the arrays down. However if you use reduce then you can filter and sum at the same time. E.g.:
const scoreN = numbers.reduce((sum, val) => {
if (val === 1) {
sum += val;
}
return sum;
}, 0);
The most beginner friendly code, that works the same for most c-like languages would be:
function score(array, value) {
let sum = 0;
for (let i = 0; i < array.length; i++) {
let element = array[i];
if (element === value) {
sum += element;
}
}
return sum;
}
another solutions that makes use of JS array functions would be:
function score(array, value) {
let sum = array
.filter(e => e === value)
.reduce((prev, curr) => prev + curr, 0);
return sum;
}
you would use both functions the same way:
const scoreN = score(array, 1);
const scoreST = score(array, 2);
const scoreO = score(array, 3);
const scoreAA = score(array, 4);
const totalScore = scoreN + scoreST + scoreO + scoreAA;

Given a list of n integers arr[0..(n-1)], determine the number of different pairs of elements within it which sum to k

I'm tackling this problem and I can't seem to arrive at the correct solution. The question is:
"Given a list of n integers arr[0..(n-1)], determine the number of different pairs of elements within it which sum to k. If an integer appears in the list multiple times, each copy is considered to be different; that is, two pairs are considered different if one pair includes at least one array index which the other doesn't, even if they include the same values.
My approach is that I'm building a map that contains each number in the array and the number of times it occurs. Then I iterate over the map to find my answer.
function numberOfWays(arr, k) {
let output = 0;
let map = {};
// put values and # of occurences into map
for(let i = 0; i < arr.length; i++) {
let key = arr[i];
if(!(key in map)) {
map[key] = 1;
} else {
map[key]++;
}
}
for(let key in map) {
let difference = k-key
if((difference) in map) {
if(k/2 === key) {
output += map[key]*(map[key]-1)/2;
} else {
output += map[key] * map[key] / 2; // divide by 2 so that pairs aren't counted twice
}
}
}
return output;
}
The two test cases are:
var arr_1 = [1, 2, 3, 4, 3]; expected result: [2] -- I'm getting [3]
var arr_2 = [1, 5, 3, 3, 3]; expected result: [4] -- I'm getting [5.5]
I'm definitely doing something wrong in my calculations, but I can't seem to wrap my ahead around it.
This is one way to nest the loops to find the pairs in array "arr" with the sum "k".
function numberOfWays(arr, k) {
let output = 0;
for (i = 0; i < arr.length; i++) {
for (n = i+1; n < arr.length; n++) {
if (arr[i] + arr[n] == k)
output++;
}
}
return output;
}
You could count the smaller and greater values for building k and then taker either the product or if only two of the same value is building the sum take factorial of the cound divided by two.
function numberOfWays(array, k) {
const
f = n => +!n || n * f(n - 1),
pairs = {};
for (const value of array) {
const smaller = Math.min(value, k - value);
pairs[smaller] ??= { one: 2 * smaller === k, min: 0, max: 0 };
pairs[smaller][value === smaller ? 'min' : 'max']++;
}
let count = 0;
for (const k in pairs) {
const { one, min, max } = pairs[k];
if (one) {
if (min > 1) count += f(min) / 2;
} else if (min && max) {
count += min * max;
}
}
return count;
}
console.log(numberOfWays([1, 2, 3, 4, 3], 6)); // 2
console.log(numberOfWays([1, 5, 3, 3, 3], 6)); // 4
function numberOfWays(items, k) {
// Clone as to not mutate original array
const arr = [...items]
let count = 0
// Stop comparing when no items left to compare
while (arr.length) {
for (let i = 0; i < arr.length; i++) {
// Compare each item to the first item
const sum = arr[0] + arr[i + 1]
if (sum === k) {
count++
}
}
// Remove the first item after comparing to the others
arr.shift()
}
return count
}
console.log(numberOfWays([1, 2, 3, 4, 3], 6))
console.log(numberOfWays([1, 5, 3, 3, 3], 6))
console.log(numberOfWays([1, 1, 1, 1, 1], 2))
import math
from math import factorial as f
def get_number_of_combination(n,r):
return f(n)//(f(n-r)*f(r))
def numberOfWays(arr, k):
num_count = {}
num_ways = 0
for i in arr:
old_count = num_count.get(i,0)
num_count.update({i: old_count+1})
for i in list(num_count.keys()):
if i == k - i and num_count.get(i,0) > 1:
num_ways += (get_number_of_combination(num_count.get(i,0),2))
num_count.update({i:0})
else:
i_n = num_count.get(i, 0)
ki_n = num_count.get(k-i, 0)
num_ways += i_n * ki_n
num_count.update({i:0,k-i:0})
return num_ways

Calculate average of any two numbers in a given array in JavaScript?

I was asked this question in an interview. I was unable to solve it.
Suppose we an have array let arr = [4,5,10,9,8].
Write a code in JavaScript to print numbers that are greater than the average of any two elements of the given array.
Suppose I decide to calculate the average of 5 & 9. The average would be 7. So the answer would be numbers greater than 7 i.e 8 9 & 10 should print on the console.
NOTE- We have to find the average of any two elements and then check, not the average of all the numbers.
Can someone please help with the logic?
I don' know if this will help you:
let arr = [4,5,10,9,8]
arr.sort((a,b) => a-b) // sorted array
function greaterThanAverage(x,y){
let average = (x+y)/2
let index = arr.findIndex(e => e > average )
return arr.slice(index == -1 ? arr.length : index)
}
console.log(greaterThanAverage(5,9))
console.log(greaterThanAverage(10,9))
console.log(greaterThanAverage(5,4))
console.log(greaterThanAverage(30,4))
So according to the problem we have to display all numbers which are greater than any average of two elements.
So it's better to choose the two smallest elements in the array and find all the numbers which are greater than their average.
function solve(arr) {
arr.sort(function (a, b) { return a - b });
let firstMinimum = arr[0];
let secondMinimun = arr[1];
let avg = (firstMinimum + secondMinimun) / 2;
for (let i = 0; i < arr.length; i++) {
if (arr[i] > avg) console.log(arr[i]);
}
}
solve([4, 5, 10, 9, 8]);
For me, it looks like you could get only two results:
No result if two max values are the same, so no value is greater than the average.
Only the greatest value if a next smaller value exists.
Another solution could be to select a pair and filter the array basex on the average of the pair.
const
values = [4, 5, 10, 9, 8];
for (let i = 0, l = values.length - 1; i < l; i++) {
for (j = i + 1; j < values.length; j++) {
const average = (values[i] + values[j]) / 2;
console.log(values[i], values[j], '|', average, '|', ...values.filter(v => v > average));
}
}
here is O(n) solution.
find min and secondMin, take average and it will give you min average.
const values = [4, 5, 10, 9, 8];
const minValue = Math.min(...values);
values.splice(values.indexOf(minValue),1);
const secondMinValue = Math.min(...values);
const minAverage = (minValue + secondMinValue)/2;
const result = values.filter(val => val > minAverage);

Mini-Max Sum In JavaScript - How to Get the Minimum Sum And Maximum Sum of 4 Elements in a 5-Element Array

Link to HackerRank Challenge
My idea is to loop through the array and sum all elements in the array except for one element each time, then find the smallest sum and the largest sum.
I know that .splice() can remove any element from an array. But currently, with my code, it's only removing one element from the array once. I.e. this is only giving me one chunk:
function miniMaxSum(arr) {
let smallestSum = 0;
let largestSum = 0;
for (let i = 0; i < arr.length; i++) {
let chunk = arr.splice(1);
console.log(chunk);
if (chunk > largestSum) largestSum = chunk;
if (chunk < smallestSum) smallestSum = chunk;
}
return (smallestSum, largestSum);
}
I need to remove one element from the array every time while looping, then get the max and min sums from that array.
So for given array of [1, 2, 3, 4, 5]
I should get the following possible "chunks":
[2, 3, 4, 5], [1, 3, 4, 5], [1, 2, 4, 5], [1, 2, 3, 5], [1, 2, 3, 4].
The chunk with the highest sum is [2, 3, 4, 5]
And the chunk with the smallest sum is [1, 2, 3, 4].
How can I adjust my code to get all of the possible 4-digit arrays within the given array so that I can compare their sums, still using a for-loop? Or if not with a for-loop, what else would you suggest?
EDIT: Now using Math.min() and Math.max() to get the smallest and largest elements in the array. Then using .filter() to remove those elements in order to create new arrays. Then getting the sums of those arrays.
function miniMaxSum(arr) {
let smallest = Math.min(...arr);
let largest = Math.max(...arr);
let smallestArray = arr.filter(element => element !== largest);
let largestArray = arr.filter(element => element !== smallest);
let sumOfSmallestArray = 0;
let sumOfLargestArray = 0;
for (let i = 0; i < smallestArray.length; i++) {
sumOfSmallestArray += smallestArray[i];
}
for (let i = 0; i < largestArray.length; i++) {
sumOfLargestArray += largestArray[i];
}
return ([sumOfSmallestArray, sumOfLargestArray]).toString();
}
But even though it works in my console, it doesn't work in HackerRank.
The key is to sort that array first, then the minimum will be the first element and the maximum will be the last, hence if you want to get the minimum set, it will be the array without the highest value (last element) and if you want to get the maximum set it will be the array without the lowest value (first element).
let data = [1, 3, 2, 4, 5];
// sort first
data = data.sort((a, b) => a - b);
// to get the sets only
let maxSet = data.slice(1);
let minSet = data.slice(0, -1);
console.log(minSet, maxSet);
// to get just the max/min value
const sum = data.reduce((a, total) => a + total, 0);
console.log(sum - data[data.length - 1], sum - data[0]);
The HackerRank challenge just asks for the sums of the, so you can make one pass through the array to calculate 3 facts:
Maximum element (a)
Minimum element (b)
Total sum of all elements (c)
The sum of the smallest chunk will be c - a and the sum of the largest will be c - b.
Here's a one-liner solution using reduce:
var arr = [1, 2, 3, 4, 5];
var [a, b, c] = arr.reduce(([a, b, c], x) => [a > x ? a : x, b < x ? b : x, c + x], [NaN, NaN, 0]);
console.log(c - a, c - b);
Note: the NaN's are just here to force the initial conditions (a > x/b < x to be false)
You could get the min and max values of the array and filter the array by taking not min or max value once.
var data = [1, 2, 3, 4, 5],
min = Math.min(...data),
max = Math.max(...data),
dataMin = data.filter(v => v !== min || !(min = -Infinity)),
dataMax = data.filter(v => v !== max || !(max = Infinity));
console.log(...dataMin);
console.log(...dataMax);
A more classical approach
function minMax(array) {
var min = array[0],
max = array[0],
sum = array[0],
i, v;
for (i = 1; i < array.length; i++) {
v = array[i];
sum += v;
if (v > max) max = v;
if (v < min) min = v;
}
console.log(sum - min, sum - max);
}
minMax([1, 2, 3, 4, 5]);
You can sort the array and for min take first four and add them and for max take last four and add them
let arr = [1, 2, 3, 4, 5]
let minAndMax = (arr) => {
arr = arr.sort((a,b) => a - b)
let op = {}
op.minArr = arr.slice(0,4)
op.min = op.minArr.reduce((a,b) => a+b, 0)
op.maxArr = arr.slice(arr.length-4,)
op.max = op.maxArr.reduce((a,b) => a + b ,0)
return op
}
console.log(minAndMax(arr))
This solution traverses the slice indexes, calculates the sum and when a maximum is found, it is put into result. Finally result is parsed:
var arr = [4, 8, 2, 6, 12];
var ln = arr.length;
var maxSum = undefined;
var result = "";
for (var splIndex = 0; splIndex < ln; splIndex++) {
var item = arr.splice(splIndex, 1);
var sum = 0;
for (var it of arr) sum += it;
if ((maxSum === undefined) || (maxSum < sum)) {
maxSum = sum;
result = JSON.stringify(arr);
}
arr.splice(splIndex, 0, item[0]);
}
console.log(JSON.parse(result));
EDIT
A simpler solution, of course is to find the minimum and calculate the sum without it.
The following function works:
function miniMaxSum(arr) {
var _arr = arr.sort((a, b) = > a - b)
var minVals = _arr.slice(0, 4)
var maxVals = _arr.slice(1)
const arrSum = __arr = > __arr.reduce((a, b) = > a + b, 0)
var minSum = arrSum(minVals)
var maxSum = arrSum(maxVals)
console.log(minSum, maxSum)
}
let arr = [15 ,12, 33, 25, 4];
//sort array
const arrSort = arr.sort((a,b)=> a-b );
console.log(arrSort);
//get values and sum
var max = arrSort.filter(value => value < Math.max(...arrSort)).reduce((ac,at)=>{
ac += at;
return ac;
},0);
var min = arrSort.filter(value => value > Math.min(...arrSort)).reduce((ac,at)=>{
ac += at;
return ac;
},0);
console.log(max);
console.log(min);
This worked for me.
let minValue, maxValue
const ascendingArray = arr.sort((a,b) => a - b)
const smallestNumber = ascendingArray[0]
const biggestNumber = ascendingArray[ascendingArray.length -1]
if(smallestNumber !== biggestNumber){
const biggestArray = arr.filter((number) => {
return number !== smallestNumber
})
const smallestArray = arr.filter((number) => {
return number !== biggestNumber
})
minValue = smallestArray.reduce((a,b) => a + b, 0)
maxValue = biggestArray.reduce((a,b) => a + b, 0)
console.log(minValue, maxValue);
}
else{
const arraySliced = arr.slice(0, 4)
const value = arraySliced.reduce((a,b) => a + b, 0)
console.log(value, value);
}
function miniMaxSum(arr) {
var soma = 0
let t = 0
for (var i = 0; i < arr.length; i++) {
soma += arr[i]
max = soma - arr[i]
}
let min = soma - arr[0]
return max + ' ' + min
}
console.log(miniMaxSum([7, 69, 2, 221, 8974]))
Here is a cleaner approach to solving this problem.
function miniMaxSum(arr) {
let min, max, sum, arrMin, arrMax; // declare variables
min = Math.min(...arr) // gets the smallest value from the arr
max = Math.max(...arr) // gets the largest number from the arr
sum = arr.reduce((a,b) => a+b, 0); // reduce used to add all values in arr
arrMin = sum - max; // excludes the largest value
arrMax = sum - min; // excludes the smallest value
console.log(arrMin+' '+arrMax) // output
}
easy solution
const miniMax = arr => {
let min = arr[0];
let max = arr[0];
for(let i = 0; i < arr.length; i++) {
if(arr[i] <= min) {
min = arr[i];
}
if (arr[i] >= max) {
max = arr[i];
}
}
let sum = arr.reduce((acc,curr) => acc + curr);
console.log(sum - max, sum - min);
}
miniMax([5,5,5,5,5]);
// result : 20 20
miniMax([1,2,3,4,5]);
// result : 10 14
I get Answer in very Simple way
function miniMaxSum(arr) {
let minval=arr[0];
let maxval=0;
let totalSum=0;
for(let i=0;i<arr.length;i++){
if (arr[i]>maxval){
maxval=arr[i];
}
if (arr[i]<minval){
minval=arr[i];
}
totalSum=totalSum+arr[i];
}
let minsum=totalSum - maxval;
let maxsum=totalSum - minval;
console.log( minsum,maxsum);
}
Use build Math methods to find max and min:
function miniMaxSum(arr) {
const min = Math.min(...arr);
const max = Math.max(...arr);
const sum = arr.reduce((a, b) => a + b);
console.log(sum - max, sum - min);
}

Convert an array into cumulative% array

I have an array like this one:
[30, 10, 4, 3, 3]
And I need to transform this to a cumulative% array in such a way that each value is the sum of all values upto there divided by sum of all values in the array.
In this case, the total is 50. So, the first value will be 30/50, i.e., 0.6 or 60%. The 2nd value will be (30+10)/50, i.e., 0.8 or 80% and so on.
The final array in this will be:
[60%, 80%, 88%, 94%, 100%]
How can I do this transformation with JavaScript? What would be the most efficient way to do so?
Try,
var x = [30, 10, 4, 3, 3];
var y = x.reduce(function(a,b){ return a+b; }, 0)
x = x.map(function(itm, index){
for(var i=0;i<index;i++) itm += x[i];
return (itm/y * 100);
});
x; //[60, 80, 88, 94, 100]
And this will look more elegant,
var x = [30, 10, 4, 3, 3];
var y = x.reduce(function(a,b){ return a+b; }, 0), sum = 0;
x = x.map(function(itm) { return sum += itm, (sum / y) * 100; });
Try
let nums = [30, 10, 4, 3, 3];
let sum = nums.reduce((prev,curr) => prev + curr);
let result = nums.map((num,i) => Math.round(nums.slice(0,i + 1).reduce((prev,curr) => prev + curr) / sum * 100) + '%');
You first need to compute the sum to get the denominator (50).
Then you need to apply the treatment for each element (new_value=value/denominator)
To do so you can use simple for loops, or even cleaner with arrays specific functions, to avoid any error:
var array = [30, 10, 4, 3, 3];
// Compute the denominator
var sum = array.reduce(function(pv, cv) { return pv + cv; }, 0);
// Duplicate the array
var arrayResult = array;
// Apply the function to each given "myArray[ind]" element
arrayResult.forEach( function(cv,ind,myArray) {
myArray[ind] = cv/sum;
// Add the previous accumulator if any
if( ind>0 ) {myArray[ind] += myArray[ind-1];}
} );
See it running on JSFiddle
edited to add the accumulator
Combine two maps, one to create an array with cumulative sums, the second to divide by the sum.
function cumulative_ratio(array) {
var x = 0;
return array .
map(v => x += v) .
map(v => v / x);
}

Categories

Resources