Even Position Element - javascript

I am having difficulties solving the following math problem:
'Write a JS function that finds the elements at even positions in an array.
The input comes as an array of number elements.
The output must be displayed into element with id result like a text/string.'
Input : [1, 2, 3, 4, 5, 6, 7, 8, 9]
Output: 1 x 3 x 5 x 7 x 9
This is my code until now:
function evenPosition(arr) {
let evenIndexes = [];
let oddIndexes = [];
for (let i = 1; i < arr.length + 1; i++) {
if (i % 2 !== 0) {
oddIndexes.push(i)
} else {
evenIndexes.push(i)
}
}
}
evenPosition([1, 2, 3, 4, 5, 6, 7, 8, 9])
I cannot sort the elements though as it is shown in the output... Can you guys please help?

Is this you want?
function evenPosition(arr) {
let str = "";
for (let i = 0; i < arr.length; i++) {
if (i % 2 !== 0) {
str += " x ";
} else {
str += arr[i];
}
}
return str;
}
console.log(evenPosition([1, 2, 3, 4, 5, 6, 7, 8, 9]))

The example in the OP is incorrect. In the array [1, 2, 3, 4, 5, 6, 7, 8, 9], the odd values are at even indexes and the even values are at odd indexes. So the result of replacing the values at even indexes should be "x 2 x 4 x 6 x 8 x".
There are of course many ways to achieve the required outcome, e.g.
// Return string with values at even indexes replaced by "x"
function evenPosition(arr) {
let acc = 'x';
return arr.slice(-(arr.length - 1)).reduce(
(acc, curr, i) => acc += ' ' + (i%2? 'x' : curr), acc
);
}
// Indexes start at 0, so even numbers are at odd indexes
let a = [1,2,3,4,5,6,7,8,9];
console.log('Input: ' + a + ' Output: ' + evenPosition(a));
// Array with ellisions (sparse)
let b = [1,,,,5,6,,,9,10];
console.log('Input: ' + b + ' Output: ' + evenPosition(b));
// Using map and join
console.log('Input: ' + a +
' Output: ' + (a.map((v, i) => i%2? v : 'x').join(' ')));

You can use array's join method to convert array into string with the character's you want to join. Something like this.
function evenPosition(arr) {
let evenArr = [];
for (let i = 0; i < arr.length; i++) {
if (i % 2 === 0) {
evenArr.push(arr[i]);
}
}
return evenArr.join(" x ");
}
console.log(evenPosition([1, 2, 3, 4, 5, 6, 7, 8, 9]))
If you want to sort the array also then you can return something like this.
return evenArr.sort().join(" x ");

Related

Javascript Challenge: Loops - Multiple Conditions - stuck and can't figure this out

I did this module on functions and execution context - all questions have gone well but there is one challenge I have spent a lot of time on and still can't figure it out. Any help will be greatly appreciated. Thank you
Challenge question says:
Write a function addingAllTheWeirdStuff which adds the sum of all the odd numbers in array2 to each element under 10 in array1.
Similarly, addingAllTheWeirdStuff should also add the sum of all the even numbers in array2 to those elements over 10 in array1.
BONUS: If any element in array2 is greater than 20, add 1 to every element in array1.
// Uncomment these to check your work!
// console.log(addingAllTheWeirdStuff([1, 3, 5, 17, 15], [1, 2, 3, 4, 5])); // expected log [10, 12, 14, 23, 21]
// console.log(addingAllTheWeirdStuff([1, 3, 5, 17, 15, 1], [1, 2, 3, 4, 5, 22])); // expected log [11, 13, 15, 46, 44, 11]
// my attempt so far:
function addingAllTheWeirdStuff(array1, array2) {
// ADD CODE HERE
let result = []
for (let i = 0; i < array2.length; i++) {
if (array2[i] > 20) {
result = array1[i] += 1
}
}
for (let i = 0; i < array2.length; i++) {
if (array2[i] % 2 === 0 && array1[i] > 10) {
result = array1[i] + array2[i]
}
}
for (let i = 0; i < array2.length; i++) {
if (array2[i] % 2 !== 0 && array1[i] < 10) {
result = array1[i] + array2[i]
}
}
return result
}
You can easily achieve this using reduce and map array method, with the ternary operator:
const array1 = [1, 3, 5, 17, 15];
const array2 = [1, 2, 3, 4, 5];
function addingAllTheWeirdStuff(array1, array2) {
const oddSum = array2.reduce((sum, current) => current % 2 ? current + sum : 0 + sum, 0)
const oddEven = array2.reduce((sum, current) => current % 2 == 0 ? current + sum : 0 + sum, 0)
return array1.map(num => num < 10 ? num + oddSum : num + oddEven)
}
console.log(addingAllTheWeirdStuff(array1, array2))
If you break the challenge into smaller pieces, you can deconstruct it better and come up with your solutions.
This is what I did... I will be adding more comments shortly with more explanations
I chose to keep using loops as I assumed this was the point of the challenges (to practice for loops, multiple conditions, etc) - In other words, I chose to not use map / reduce on purpose but if that's allowed, use the answer by #charmful0x as it results in less code :)
// function to get sum of all odd numbers in array
function getSumOfAllOddNumbersInArray( elementArray ){
var sumOfOddNumbers = 0;
for (let i = 0; i < elementArray.length; i++) {
// use remainder operator to find out if element is odd or not
if (elementArray[i] % 2 !== 0 ) {
sumOfOddNumbers += elementArray[i];
}
}
return sumOfOddNumbers;
}
// function to get sum of all EVEN numbers in array
function getSumOfAllEvenNumbersInArray( elementArray ){
var sumOfEvenNumbers = 0;
for (let i = 0; i < elementArray.length; i++) {
// use remainder operator to find out if element is odd or not
if (elementArray[i] % 2 === 0 ) {
sumOfEvenNumbers += elementArray[i];
}
}
return sumOfEvenNumbers;
}
// Return true if there is at least one element in array that is greater than 20
function hasElementOverTwenty( elementArray ){
for (let i = 0; i < elementArray.length; i++) {
if (elementArray[i] > 20 ) {
// no need to keep looping, we found one - exit function
return true;
}
}
return false;
}
function addingAllTheWeirdStuff( firstArray, secondArray ){
var sumOfOddNumbersInArray = getSumOfAllOddNumbersInArray( secondArray );
var sumOfEvenNumbersInArray = getSumOfAllEvenNumbersInArray( secondArray );
var needToAddOne = hasElementOverTwenty( secondArray );
for (let i = 0; i < firstArray.length; i++) {
// Challenge One
if (firstArray[i] < 10) {
firstArray[i] = firstArray[i] + sumOfOddNumbersInArray;
} else if (firstArray[i] > 10) {
// Challenge Two
firstArray[i] = firstArray[i] + sumOfEvenNumbersInArray;
}
// bonus
if( needToAddOne ){
firstArray[i]++;
}
}
return firstArray;
}
// Uncomment these to check your work!
console.log(addingAllTheWeirdStuff([1, 3, 5, 17, 15], [1, 2, 3, 4, 5]));
console.log('expected:' + [10, 12, 14, 23, 21] );
console.log(addingAllTheWeirdStuff([1, 3, 5, 17, 15, 1], [1, 2, 3, 4, 5, 22]));
console.log('expected:' + [11, 13, 15, 46, 44, 11] );
Challenge question says: Write a function addingAllTheWeirdStuff which adds the sum of all the odd numbers in array2 to each element under 10 in array1.
Similarly, addingAllTheWeirdStuff should also add the sum of all the even numbers in array2 to those elements over 10 in array1.
BONUS: If any element in array2 is greater than 20, add 1 to every element in array1.

How to write the code with less time complexity for finding the missing element in given array range?

My function should return the missing element in a given array range.
So i first sorted the array and checked if the difference between i and i+1 is not equal to 1, i'm returning the missing element.
// Given an array A such that:
// A[0] = 2
// A[1] = 3
// A[2] = 1
// A[3] = 5
// the function should return 4, as it is the missing element.
function solution(A) {
A.sort((a,b) => {
return b<a;
})
var len = A.length;
var missing;
for( var i = 0; i< len; i++){
if( A[i+1] - A[i] >1){
missing = A[i]+1;
}
}
return missing;
}
I did like above, but how to write it more efficiently??
You could use a single loop approach by using a set for missing values.
In the loop, delete each number from the missing set.
If a new minimum value is found, all numbers who are missing are added to the set of missing numbers, except the minimum, as well as for a new maximum numbers.
The missing numbers set contains at the end the result.
function getMissing(array) {
var min = array[0],
max = array[0],
missing = new Set;
array.forEach(v => {
if (missing.delete(v)) return; // if value found for delete return
if (v < min) while (v < --min) missing.add(min); // add missing min values
if (v > max) while (v > ++max) missing.add(max); // add missing max values
});
return missing.values().next().value; // take the first missing value
}
console.log(getMissing([2, 3, 1, 5]));
console.log(getMissing([2, 3, 1, 5, 4, 6, 7, 9, 10]));
console.log(getMissing([3, 4, 5, 6, 8]));
Well, from the question (as it's supposed to return a single number) and all the existing solution (examples at least), it looks like list is unique. For that case I think we can sumthe entire array and then subtracting with the expected sum between those numbers will generate the output.
sum of the N natural numbers
1 + 2 + ....... + i + ... + n we can evaluate by n * (n+1) / 2
now assume, in our array min is i and max is n
so to evaluate i + (i+1) + ..... + n we can
A = 1 + 2 + ..... + (i-1) + i + (i+1) + .... n (i.e. n*(n+1)/2)
B = 1 + 2 + ..... + (i-1)
and
C = A - B will give us the sum of (i + (i+1) + ... + n)
Now, we can iterate the array once and evaluate the actual sum (assume D), and C - D will give us the missing number.
Let's create the same with each step at first (not optimal for performance, but more readable) then we will try to do in a single iteration
let input1 = [2, 3, 1, 5],
input2 = [2, 3, 1, 5, 4, 6, 7, 9, 10],
input3 = [3, 4, 5, 6, 8];
let sumNatural = n => n * (n + 1) / 2;
function findMissing(array) {
let min = Math.min(...array),
max = Math.max(...array),
sum = array.reduce((a,b) => a+b),
expectedSum = sumNatural(max) - sumNatural(min - 1);
return expectedSum - sum;
}
console.log('Missing in Input1: ', findMissing(input1));
console.log('Missing in Input2: ', findMissing(input2));
console.log('Missing in Input3: ', findMissing(input3));
Now, lets try doing all in a single iteration (as we were iterating 3 times for max, min and sum)
let input1 = [2, 3, 1, 5],
input2 = [2, 3, 1, 5, 4, 6, 7, 9, 10],
input3 = [3, 4, 5, 6, 8];
let sumNatural = n => n * (n + 1) / 2;
function findMissing(array) {
let min = array[0],
max = min,
sum = min,
expectedSum;
// assuming the array length will be minimum 2
// in order to have a missing number
for(let idx = 1;idx < array.length; idx++) {
let each = array[idx];
min = Math.min(each, min); // or each < min ? each : min;
max = Math.max(each, max); // or each > max ? each : max;
sum+=each;
}
expectedSum = sumNatural(max) - sumNatural(min - 1);
return expectedSum - sum;
}
console.log('Missing in Input1: ', findMissing(input1));
console.log('Missing in Input2: ', findMissing(input2));
console.log('Missing in Input3: ', findMissing(input3));
Instead of sorting, you could put each value into a Set, find the minimum, and then iterate starting from the minimum, checking if the set has the number in question, O(N). (Sets have guaranteed O(1) lookup time)
const input1 = [2, 3, 1, 5];
const input2 = [2, 3, 1, 5, 4, 6, 7, 9, 10];
const input3 = [3, 4, 5, 6, 8];
function findMissing(arr) {
const min = Math.min(...arr);
const set = new Set(arr);
return Array.from(
{ length: set.size },
(_, i) => i + min
).find(numToFind => !set.has(numToFind));
}
console.log(findMissing(input1));
console.log(findMissing(input2));
console.log(findMissing(input3));
If the array is items and the difference between missing and present diff is 1:
const missingItem = items => [Math.min(...items)].map(min => items.filter(x =>
items.indexOf(x-diff) === -1 && x !== min)[0]-diff)[0]
would give complexity of O(n^2).
It translates to: find the minimum value and check if there isn't a n-diff value member for every value n in the array, which is also not the minimum value. It should be true for any missing items of size diff.
To find more than 1 missing element:
([Math.min(...items)].map(min => items.filter(x =>
items.indexOf(x-diff) === -1 && x !== min))[0]).map(x => x-diff)
would give O((m^2)(n^2)) where m is the number of missing members.
Found this old question and wanted to take a stab at it. I had a similar thought to https://stackoverflow.com/users/2398764/koushik-chatterjee in that I think you can optimize this by knowing that there's always only going to be one missing element. Using similar methodology but not using a max will result in this:
function getMissing(arr) {
var sum = arr.reduce((a, b) => a + b, 0);
var lowest = Math.min(...arr);
var realSum = (arr.length) * (arr.length + 1) / 2 + lowest * arr.length;
return realSum - sum + lowest;
}
With the same inputs as above. I ran it in jsperf on a few browsers and it is faster then the other answers.
https://jsperf.com/do-calculation-instead-of-adding-or-removing.
First sum everything, then calculate the lowest and calculate what the sum would be for integers if that happened to be the lowest. So for instance if we have 2,3,4,5 and want to sum them that's the same as summing 0,1,2,3 and then adding the lowest number + the amount of numbers in this case 2 * 4 since (0+2),(1+2),(2+2),(3+2) turns it back into the original. After that we can calculate the difference but then have to increase it once again by the lowest. To offset the shift we did.
You can use while loop as well, like below -
function getMissing(array) {
var tempMin = Math.min(...array);
var tempMax = tempMin + array.length;
var missingNumber = 0;
while(tempMin <= tempMax){
if(array.indexOf(tempMin) === -1) {
missingNumber = tempMin;
}
tempMin++;
}
return missingNumber;
}
console.log(getMissing([2, 3, 1, 5]));
console.log(getMissing([2, 3, 1, 5, 4, 6, 7, 9, 10]));
console.log(getMissing([3, 4, 5, 6, 8]));
My approach is based on in place sorting of the array which is O(N) and without using any other data structure.
Find the min element in the array.
Sort in place.
Again loop the array and check if any element is misplaced, that is the answer!
function getMissing(ar) {
var mn = Math.min(...ar);
var size = ar.length;
for(let i=0;i<size;i++){
let cur = ar[i];
// this ensures each element is in its right place
while(cur != mn +i && (cur - mn < size) && cur != ar[cur- mn]) {
// swap
var tmp = cur;
ar[i] = ar[cur-mn];
ar[cur-mn] = tmp;
}
}
for(let i=0; i<size; i++) {
if(ar[i] != i+mn) return i+mn;
}
}
console.log(getMissing([2, 3, 1, 5]));
console.log(getMissing([2, 3, 1, 5, 4, 6, 7, 9, 10]));
console.log(getMissing([3, 4, 5, 6, 8]));

Find missing item from 1..N items array

I was asked to find the missing number from 1..N array.
For instance, for array: let numArr = [2,4,6,8,3,5,1,9,10]; the missing number is 7
let numArr=[2,4,6,8,3,5,1,9,10];
numArr.sort(function(a,b){ //sort numArr
return a-b;
});
let newNumArr=[];
for(let i=1;i<=10;i++){
newNumArr.push(i);
}
for(let i=0;i<newNumArr.length;i++){ //compare with new arr
if(newNumArr[i] !== numArr[i]){
console.log('The missing num is:'+newNumArr[i]); //The missing num is:7
break;
}
}
You can use MAP and FILTER to find out the missing number in seperate array
const numArr = [2, 4, 6, 8, 3, 5, 1, 9, 10];
const missingNumberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(number => {
if (!numArr.includes(number)) {
return number;
}
}).filter(y => y !== undefined);
You can use the simple logic of sum of consecutive n numbers is n*(n+1)/2. Subtracting the sum of array numbers from above will give the missing number
let numArr=[2,4,6,8,3,5,1,9,10];
var sum = numArr.reduce((a,c) => a+c, 0);
// As the array contains n-1 numbers, here n will be numArr.length + 1
console.log(((numArr.length + 1) * (numArr.length + 2))/2 - sum);
It would be easier to use .find:
function findMissing(input) {
input.sort((a, b) => a - b);
const first = input[0];
return input.find((num, i) => first + i !== num) - 1;
}
console.log(findMissing([2, 4, 6, 8, 3, 5, 1, 9, 10]));
console.log(findMissing([3, 4, 5, 6, 8, 9, 2]));
(note that this also works for finding missing values from arrays that don't start at 1)
You can use XOR features.
XOR all the array elements, let the result of XOR be arr_xor.
XOR all numbers from 1 to n, let XOR be interval_xor .
XOR of arr_xor and interval_xor gives the missing number.
let numArr=[2,4,6,8,3,5,1,9,10];
function getMissingNo(arr){
arr = arr.sort()
n = arr.length
arr_xor = arr[0]
interval_xor = 1
for(i = 0; i < n; i++)
arr_xor ^= arr[i]
for( i = 0; i<n + 2; i++)
interval_xor ^= i
return arr_xor ^ interval_xor
}
console.log(getMissingNo(numArr));

Filling array with averages

Im wondering about a problem I have in Javascript. I have a scenario where I need to fill gaps in an array with averages of the surrounding values. Let me give an example:
Array:
1, 2, 3, ,4, 5
In this particular case I would need to fill the gap with average of the surrounding numbers, i.e. 3.5. I think this is relatively easy to do.
However, I also need to make sure this works when there is more subsequent gaps in the array.
Example:
1, 2, 3, , , 5, 6
In this case the two gaps should be filled with the average of 3 and 5, resulting in ... 3, 4, 4, 5.
The moment I got stuck was when I tried iterating the array and filling the gaps because I filled the first gap with 4, but at that moment, the surrounding numbers for the second gap were 4 (the original gap) and 5, so I ended up with
... 3, 4, 4.5, 5, ...
which is not what I need.
Im using jQuery to iterate the array and get the values from a table.
This is how Im loading the array:
var list = [];
$('#mytable > tbody > tr').each(function() {
$this = $(this);
list.push(eval($this.find("input.number").val());
}
Now I need to iterate and fill the gaps in "list"
Here's one possible implementation:
function fill(arr) {
while (arr.includes(undefined)) {
const startIndex = arr.findIndex(num => num === undefined);
const endIndex = arr.findIndex((num, i) => i >= startIndex && num !== undefined);
const avg = (arr[startIndex - 1] + arr[endIndex]) / 2;
for (let i = startIndex; i < endIndex; i++) arr[i] = avg;
}
return arr;
}
console.log(fill([1, 2, 3, , , 5, 6]));
console.log(fill([1, , , , , , 6]));
console.log(fill([1, , , , 3, 4, , , 6]));
Try this code
var x = "1, 2, 3, ,4, 5";
var y = "1, 2, 3, , , 5, 6";
var z = "1, , , , , , 6";
var q = "1, , , , 3, 4, , , 6";
function removeSpace(str) {
return str.replace(/ /g, "");
}
function splitString(str) {
return str.split(',');
}
function fill(str) {
var z = removeSpace(str);
var zPrime = splitString(z);
for (var i = 0; i < zPrime.length; i++) {
if (zPrime[i] == "") {
if (i + 1 < zPrime.length && zPrime[i + 1] != "") {
zPrime[i] = (Number(zPrime[i - 1]) + Number(zPrime[i + 1])) / 2;
} else {
var j = i + 1;
while (j < zPrime.length && zPrime[j] == "") j++;
var tp = (j < zPrime.length) ? Number(zPrime[j]) : 0;
var dn = (i - 1 > -1) ? Number(zPrime[i - 1]) : 0;
for (var k = i; k < j; k++) {
zPrime[k] = ((tp + dn) / 2) + '';
}
}
}
}
return zPrime;
}
console.log(fill(x));
console.log(fill(y));
console.log(fill(z));
console.log(fill(q));
You can do something like this using simple iteration.
function fillMissing(arr) {
// array for storing result
var res = [];
// iterate over the array
for (i = 0; i < arr.length; i++) {
// if undefined then call the function to calculate average or set the value
res[i] = arr[i] == undefined ? calculateAverage(arr, i) : arr[i];
}
return res;
}
function calculateAverage(arr1, i) {
// set preve and next value as nearest element
var prev = arr1[i - 1],
next = arr1[i + 1],
j = 1; // variable for iterating
// iterate to find out nearest defined value
// after the element
while (prev == undefined) { prev = arr1[i - ++j]; }
j = 1; // reset for next iteration
// iterate to find out nearest defined value
// before the element
while (next == undefined) { next = arr1[i + ++j]; }
//find average and return
return (prev + next) / 2;
}
console.log(fillMissing([1, 2, 3, , , 5, 6]));
console.log(fillMissing([1, 2, 3, , , 5, 6]));
console.log(fillMissing([1, , , , , , 6]));
console.log(fillMissing([1, , , , 3, 4, , , 6]));
You could iterate the sparse array and store the last index and value. If a gap is found, the gap is filled with the average of the last value and the actual value.
function fill(array) {
array.reduce((last, v, i, a) => {
var j, avg;
if (last.index + 1 !== i) {
avg = (v + last.value) / 2;
for (j = 1; j < i - last.index; j++) {
a[last.index + j] = avg;
}
}
return { index: i, value: v };
}, { index: -1 });
return array;
}
console.log(fill([1, 2, 3, , , 5, 6]));
console.log(fill([1, , , , , , 6]));
console.log(fill([1, , , , 3, 4, , , 6]));
Interesting question that made me think a bit.
My first idea was to use map but I found that it does not consider holes. Fixed that with Array.from that converts holes to undefined
I was hoping to find a more concise solution but I'm posting it anyways
function fillMissing(a){
return Array.from(a).map((e,i)=> e !== undefined ? e : averageAround(i,a))
}
const averageAround = (index, array) => average(before(index, array), after(index, array))
const average = (a, b) => (a+b)/2
const before = findFirstNotUndefined.bind(null, -1)
const after = findFirstNotUndefined.bind(null, 1)
function findFirstNotUndefined(direction, index, array){
if (array[index] !== undefined) return array[index]
return findFirstNotUndefined(direction, index+direction, array)
}
console.log(fillMissing([1, 2, 3, , , 5, 6]));
Some thoughts:
recursive call to findFirstNotUndefined is in tail call position
findFirstNotUndefined should be memoizable, (maybe) useful for large holes
average around can be written point free style but not without adding another function or importing some fp library like ramda
Modifying the signature of averageAround like (_, index, array), it can be used directly in the map: Array.from(a).map(averageAround). Cool to read even if it computes the average on every value ((val + val)/2)
There is a recursive way to do this, Basically it counts the empty spots between two values and divides the difference over these empty spots:
var arr = [1, , , , 3, 4, , , 6];
for( var i = 0; i < arr.length; i++ ){
if( arr[ i ] === undefined )
arr[ i ] = avg( arr[ i - 1 ], arr.slice( i + 1, arr.length ), 1 );
}
function avg( low, arr, recursion ){
if( arr[ 0 ] === undefined )
return avg( low, arr.slice( 1, arr.length ), recursion + 1 );
return low + ( ( arr[0] - low ) / ( recursion + 1 ) );
}
console.log( arr );
Works like a charm:
arr = [1, 2, 3, ,4, 5] => [1, 2, 3, 3.5, 4, 5]
arr = [1, 2, 3, , , 5, 6] => [1, 2, 3, 3.6665, 4.3333, 5, 6]
arr = [1, , , , 3, 4, , , 6] => [1, 1.5, 2, 2.5, 3, 4, 4.6667, 5.3334, 6]
Another functional recursive version
const arr = [1,2,3,,,5,6]
function fill([head,...tail], lastNotNull, holeWidth = 0){
if (tail.length === 0 ) return head
if (head === undefined) return fill(tail, lastNotNull, ++holeWidth)
return Array(holeWidth).fill((lastNotNull+head)/2).concat(head).concat(fill(tail, head))
}
console.log(fill(arr))
Explanation:
First parameter of fill function is destructured into head and tail. Head represent the current value and tail next values
Base case: tail empty -> we just return head
If current value head is undefined, we recurse increasing the size of the hole and keeping the last not null value, to compute the average
In all other cases we fill the hole with the average, we add the current value and then recurse onto remaining array, resetting lastNotNull to head and holeWidth to 0 with default value
I feel that the last step could be optimized in terms of execution time but I like the fact that it's compact and clear (if already comfortable with recursion)
Bonus: I love the fact that the hole is filled with the Array.prototype.fill function

JavaScript - Print a Histogram from a given array

// Given an array of integers [2, 1, 2, 101, 4, 95, 3, 250, 4, 1, 2, 2, 7, 98, 123, 99, ...]
I'm trying to Write a function (with linear run-time complexity) to print the following tabular output with ‘xxx' that resembles a histogram (the output should closely match the sample output below, including "99+" to capture the count for all numbers > 99):
Num | count
1 | xx
2 | xxxx
3 | x
4 | xx
98 | x
99 | x
99+| xxx
const dict = {}; // Empty dictionary
var min = Number.MAX_VALUE;
const maxRange = 5; // elements above maxRange will be clubbed in the same range.
//var arr = [2, 1, 2, 101, 4, 95, 3, 250, 4, 1, 2, 2, 7, 98, 123, 99];
const arr = [1, 2, 5, 3, 2, 2, 1, 5, 5, 6, 7, 1, 8, 10, 11, 12];
// iterate the array and set and update the counter in map
arr.forEach(function(num) {
min = Math.min(min, num); // find min
if (num > maxRange) {
num = maxRange + 1;
}
dict[num] = dict[num] ? dict[num] + 1 : 1;
});
console.log("Num | Count");
// Print the occurrences per item in array starting from min to max
while (min <= maxRange + 1) {
if (!dict[min]) { // print only those numbers which are defined in dictionary
min++;
continue;
}
var xArr = []
var range = dict[min];
for (i = 0; i < range; i++) {
xArr.push('x');
}
var disp = (min <= maxRange) ? (min + " | " + xArr.join("")) : (maxRange + "+ | " + xArr.join(""));
console.log(disp);
min = min + 1;
}
You might want to try iterating over the array using the forEach() method. then create an array of "x"'s as long as the current item in the array. Then use the join method to join the array into a string of x's.
I haven't included how to handle numbers over 99 but I think you this should be enough to get you started. The solution would involve using a conditional statement to check if the number is above 99 and printing accordingly.
i got the following output from my example:
Num | Count
2 ' |' 'xx'
4 ' |' 'xxxx'
6 ' |' 'xxxxxx'
8 ' |' 'xxxxxxxx'
have fun!
var arr = [2,4,6,8]
printHistogram = (array) => {
console.log("Num", '|', "Count")
array.forEach((x, i) => { //iterate over the array (x = current item, i = index)
var arrToJoin =[] //create an empty array
for(i = 0; i < x; i++) {
arrToConcat.push('x') //add an "x" to the array
}
console.log(i, ' |', arrToConcat.join(''))
})
}
printHistogram(arr)
How about this?
create an array of all the unique numbers called arrToCompare
then iterate over that array and compare each number to each number in the original array. If they are equal push an x to the array to join. Join it and log it with the appropriate symbols.
var arr = [7, 7, 8, 9, 2,4,6,8,2]
printHistogram = (array) => {
var arrToCompare =[]
console.log("Num", '|', "Count")
array.forEach((x, i) => {
arrToCompare.includes(x) ? "" : arrToCompare.push(x)
})
arrToCompare.forEach(function(x) {
var arrToJoin = []
array.forEach(function(i) {
if(i === x) {
arrToJoin.push('x')
}
})
console.log(x, '|', arrToJoin.join(''))
})
}
printHistogram(arr)

Categories

Resources