Related
I'm solving the following kata:
Given an input of an array of digits, return the array with each digit incremented by its position in the array: the first digit will be incremented by 1, the second digit by 2, etc. Make sure to start counting your positions from 1 (and not 0).
Your result can only contain single digit numbers, so if adding a digit with it's position gives you a multiple-digit number, only the last digit of the number should be returned.
Notes:
return an empty array if your array is empty
arrays will only contain numbers so don't worry about checking that
Examples
[1, 2, 3] --> [2, 4, 6] # [1+1, 2+2, 3+3]
[4, 6, 9, 1, 3] --> [5, 8, 2, 5, 8] # [4+1, 6+2, 9+3, 1+4, 3+5]
# 9+3 = 12 --> 2
My code:
const incrementer = (arr) => {
if (arr === []) {
return []
}
let newArr = []
for (let i = 0; i <= arr.length; i++) {
let result = arr[i] + (i + 1)
newArr.push(result)
if (newArr[i] > 9 ) {
let singleDigit = Number(newArr[i].toString().split('')[1])
newArr.push(singleDigit)
}
}
const filteredArr = newArr.filter(el => el >= 0 && el <= 9)
return filteredArr
}
I can't seem to pass the latest test case, which is the following:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 8]), [2, 4, 6, 8, 0, 2, 4, 6, 8, 9, 0, 1, 2, 2]
I keep getting back the whole correct array up until the second 0, after which the other numbers, 1,2,2 are missing from the solution. What am I doing wrong?
The problem in your code is that the filter only runs at the end, and so when you have done a double push in one iteration (once with the value that has more than one digit, and once with just the last digit), the next iteration will no longer have a correct index for the next value that is being pushed: newArr[i] will not be that value.
It is better to correct the value to one digit before pushing it to your new array.
Moreover, you can make better use of the power of JavaScript:
It has a nice map method for arrays, which is ideal for this purpose
Use modulo arithmetic to get the last digit without having to create a string first
Here is the proposed function:
const incrementer = (arr) => arr.map((val, i) => (val + i + 1) % 10);
console.log(incrementer([1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 8]));
... so if adding a digit with it's position gives you a multiple-digit number, only the last digit of the number should be returned.
So if the number is 12, it expects only 2 to be added to the array.
So your code should be:
if (newArr[i] > 9)
{
newArr[i] = newArr[i] % 10; // remainder of newArr[i] / 10
}
const incrementer = (arr) => {
if (arr.length === 0) { // CHANGE HERE
return [];
}
let newArr = []
for (let i = 0; i <= arr.length; i++) {
let result = arr[i] + (i + 1)
newArr.push(result)
if (newArr[i] > 9 ) {
newArr[i] = newArr[i] % 10; // CHANGE HERE
}
}
const filteredArr = newArr.filter(el => el >= 0 && el <= 9)
return filteredArr
}
console.log(incrementer([2, 4, 6, 8, 0, 2, 4, 6, 8, 9, 0, 1, 2, 2]));
console.log(incrementer([1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 8]));
Please see below code.
const incrementer = arr => {
if (arr === []) {
return [];
}
let newArr = [];
for (let i = 0; i < arr.length; i++) {
let result = arr[i] + (i + 1);
// newArr.push(result);
if (result > 9) {
let singleDigit = Number(result.toString().split("")[1]);
newArr.push(singleDigit);
} else {
newArr.push(result);
}
}
// const filteredArr = newArr.filter(el => el >= 0 && el <= 9);
return newArr;
};
console.log(incrementer([1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 8]))
const incrementer = (arr) => {
if (arr === []) {
return []
}
return arr.map((number, index) => (number + index + 1) % 10);
}
Doing the needed additions in (number + index + 1) and % 10 operation will get the last digit.
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.
I have an array like so:
[5, 12, 43, 65, 34 ...]
Just a normal array of numbers.
What I wan't to do is write a function group(n, arr) which adds every n numbers in the array.
For example if I call group(2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) it should return
[
3 //1+2,
7 //3+4,
11 //5+6,
15 //7+8,
19 //9+10,
11 //whatever remains
]
I haven't tried anything yet, I will soon update with what I can.
You can use .reduce as follows:
function group(n, arr) {
// initialize array to be returned
let res = [];
// validate n
if(n > 0 && n <= arr.length) {
// iterate over arr while updating acc
res = arr.reduce((acc, num, index) => {
// if the current index has no remainder with n, add a new number
if(index%n === 0) acc.push(num);
// else update the last added number to the array
else acc[acc.length-1] += num;
// return acc in each iteration
return acc;
}, []);
}
return res;
}
console.log( group(2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) );
This approach features two loops, one for checking the outer index and anoter for iterating the wanted count of items for summing.
function group(n, array) {
const result = [];
let i = 0;
while (i < array.length) {
let sum = 0;
for (let j = 0; j < n && i + j < array.length; j++) {
sum += array[i + j];
}
result.push(sum);
i += n;
}
return result;
}
console.log(group(2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]));
You could use Array.from to create the result array and then use its mapper to make the sums. These sums can be made by using reduce on the relevant slice of the array .
This is a functional programming solution:
const group = (step, arr) =>
Array.from({length: Math.ceil(arr.length/step)}, (_, i) =>
arr.slice(i*step, (i+1)*step).reduce((a, b) => a+b)
);
console.log(group(2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]));
function revertNumbers(...numberArray) {
let rev = [];
for(let i = 0; i <numberArray.length; i++)
{
rev.push(numberArray[i])
}
return rev.reverse();
}
console.log("revertNumbers", revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) === "9,8,7,6,5,4,3,2,1,0");
Can you please show me the how to reverse number in this code that the statement will be true? Also without using .reverse method. Is it possible to make it in another for loop by just changing this statement:
(let i = 0; i <numberArray.length; i++)
You just need to reverse the direction of your loop. Means start i with last index and then gradually decrease it to 0
function revertNumbers(...numberArray) {
let rev = [];
for(let i = numberArray.length - 1; i >= 0; i--)
{
rev.push(numberArray[i])
}
return rev.join(",")
}
console.log("revertNumbers", revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) === "9,8,7,6,5,4,3,2,1,0");
This is also a good use case of reduceRight()
const revertNumbers = (...arr) => arr.reduceRight((ac, a) => ([...ac, a]), []).join(',')
console.log("revertNumbers", revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) === "9,8,7,6,5,4,3,2,1,0");
Here is a solution that manipulates the array in place, and only has to traverse half of the original array in order to reverse it. This ekes out some modest performance gains compared to other answers in this thread (my function narrowly beats out or matches the speed of even the native reverse method in ops/sec), but micro-optimizations are largely irrelevant for this problem unless you are talking about a truly massive list of numbers.
Nonetheless, here is my answer:
const revNums = (...numArray) => {
for (
let arrLen = numArray.length,
breakPoint = ((arrLen / 2)|0) - 1,
i = arrLen,
k = 0,
temp;
--i !== breakPoint;
++k
) {
temp = numArray[i];
numArray[i] = numArray[k];
numArray[k] = temp;
}
return numArray.join(',');
};
You could reduce the original array and unshift each element onto the new array.
function revertNumbers(...numberArray) {
return numberArray.reduce((r, e) => { r.unshift(e); return r }, []).join(',')
}
console.log("revertNumbers", revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) === "9,8,7,6,5,4,3,2,1,0")
If you don't want to unshift, you can concat in reverse.
function revertNumbers(...numberArray) {
return numberArray.reduce((r, e, i, a) => r.concat(a[a.length - i - 1]), []).join(',')
}
console.log("revertNumbers", revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) === "9,8,7,6,5,4,3,2,1,0")
You could take a value and the rest of the arguments and use a recursive approach to get a reversed array of arguments.
function revertNumbers(v, ...rest) {
return rest.length
? [...revertNumbers(...rest), v]
: [v];
}
console.log(revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
It is to ask how many solutions can be possible ?
here are 3 of them...
"use strict";
const targetString = '9,8,7,6,5,4,3,2,1,0'
;
function soluce_1(...numberArray)
{
const rev = [];
for( let i=numberArray.length;i--;) { rev.push(numberArray[i]) }
return rev.join(',')
}
function soluce_2(...numberArray)
{
const rev = [];
let pos = numberArray.length;
for(let N in numberArray) { rev[--pos] = N }
return rev.join(",")
}
function soluce_3(...numberArray)
{
const rev = [];
while(numberArray.length) { rev.push(numberArray.pop()) }
return rev.join(',')
}
console.log('soluce_1 ->', (soluce_1(0,1,2,3,4,5,6,7,8,9)===targetString) );
console.log('soluce_2 ->', (soluce_2(0,1,2,3,4,5,6,7,8,9)===targetString) );
console.log('soluce_3 ->', (soluce_3(0,1,2,3,4,5,6,7,8,9)===targetString) );
And yes, I code in Whitesmiths style, please respect this (the reason for the downVote for correct answers ?)
https://en.wikipedia.org/wiki/Indentation_style#Whitesmiths_style
You might reverse like this:
function reverse(...a) {
const h = a.length >> 1, l = a.length-1;
for (let i = 0; i < h; ++i) [a[i], a[l-i]] = [a[l-i], a[i]];
return a;
}
console.log(reverse(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).join(','));
I'm running into a error in stopping the execution when a lower number occurs in the data of an array
Let seat1 = [2, 5, 6, 9, 2, 12, 18];
console should log the values till it gets to 9 since
2 < 5 < 6 < 9
then omit 2 since 9 > 2
then continue from 12 < 18.
let num = [2, 5, 6, 9, 2, 12, 18];
for (let i = 0; i < num.length; i++) {
if ((num[i] + 1) > num[i]) {
console.log(num[i])
} else {
console.log('kindly fix')
}
}
Use Array.reduce() to create a new array without the items that are not larger than the last item in the accumulator (acc) or -Infinity if it's the 1st item:
const num = [2, 5, 6, 9, 2, 3, 12, 18];
const result = num.reduce((acc, n) => {
if(n > (acc[acc.length - 1] || -Infinity)) acc.push(n);
return acc;
}, []);
console.log(result);
simple answer using if and for -
let num = [2, 5, 6, 9, 2 , 3, 12, 16, 9, 18];
let max = 0;
for (let i = 0; i < num.length; i++)
{
if ((i == 0) || (num[i] > max)) {
max = num[i];
console.log (num[i]);
}
}
You could filter the array by storing the last value who is greater than the last value.
var array = [2, 5, 6, 9, 2, 3, 12, 18],
result = array.filter((a => b => a < b && (a = b, true))(-Infinity));
console.log(result)
Store the max value and check num[i] against the current max. If num[i] is bigger, log it and set the new max value. Initial max value should be first num value but smaller so it doesn't fail on the first check.
let num = [2, 5, 6, 9, 2, 12, 18];
let max = num[0] - 1;
for (let i = 0; i < num.length; i++) {
if (num[i] > max) {
console.log(num[i]);
max = num[i];
}
}
let num = [2, 5, 6, 9, 2, 12, 18];
let result = num.sort((a, b) => a - b).filter((elem, pos, arr) => {
return arr.indexOf(elem) == pos;
})
console.log(result)