fizzBuzz array issues - javascript

I am doing a fizzbuzz challenge in JavaScript where I create a function that accepts a number and returns an array that is the length of the number. When there is a multiple of 3 it will say "fizz" and when there is a multiple of 5 it will say "buzz", and then lastly if it is a multiple of 3 and 5 it will say "fizzBuzz".
[0, 1, 'fizz', 3, 'buzz', 'fizz', 6, 7, 'fizz', 'buzz', 10, 'fizz', 12, 13, 'fizzBuzz']
I do it this way because the array starts at 0. But when I try to do this it ends up getting an output like this:
['fizzBuzz', 1, 'fizz', 3, 'buzz', 'fizz', 6, 7, 'fizz', 'buzz', 10, 'fizz', 12, 13, 'fizzBuzz']
Code:
let someArray = []
const fizzBuzz = () => {
for (let i = 0; i <= 15; i++) {
if (i % 3 === 0) {
someArray.pop()
someArray.push("fizz")
} if (i % 5 === 0) {
someArray.pop()
someArray.push("buzz")
} if (i % 15 === 0) {
someArray.pop()
someArray.push("fizzBuzz")
} else {
someArray.push(i)
}
}
}
fizzBuzz()
I have also seen where you can do it this way:
let someArray = []
const fizzBuzz = () => {
for (let i = 0; i <= 15; i++) {
if (i % 15 === 0) {
someArray.push("fizzbuzz")
} else if (i % 3 === 0) {
someArray.push("fizz")
} else if (i % 5 === 0) {
someArray.push("buzz")
} else {
someArray.push(i)
}
}
}
fizzBuzz()
This gets it right on 3 and 5, but still adds the "fizzBuzz" to the beginning of the array:
['fizzbuzz', 1, 2, 'fizz', 4, 'buzz', 'fizz', 7, 8, 'fizz', 'buzz', 11, 'fizz', 13, 14, 'fizzbuzz']
Is there something that I am doing wrong? and which way would be the correct way to do this? Or if there is a better way to do this?

You can either start the loop at 1 or handle the condition for zero in the if statements...
const fizzBuzz = () => {
for (let i = 0; i <= 15; i++) {
if (i === 0) {
someArray.push(i)
} else if (i % 15 === 0) {
someArray.push("fizzbuzz")
} else if (i % 3 === 0) {
someArray.push("fizz")
} else if (i % 5 === 0) {
someArray.push("buzz")
} else {
someArray.push(i)
}
}
}

Related

latest elements in array not found? codewars kata

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.

Recursion method

Something's not working with this method. Where's the error?
find the Odd numbers:
array = [1,2,3,4,5,6,7,8,9,10]
function findOddNum(array) {
let result = [];
let i = 0;
function helper_func(inputArray) {
if (inputArray.length === 0) {
return false;
}
if (inputArray[i] % 2 !== 0) {
result = inputArray[i];
}
i++;
helper_func(array);
}
helper_func(array);
return result;
}
const res = findOddNum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
console.log(res);
It returns the following error:
maximum call stack size not exceeded
You haven't added the nested function termination condition
if (i >= inputArray.length) return;
Without termination condition, it will go infinite recursion. That's the reason it gives you maximum call stack size not exceeded
function findOddNum(array) {
let result = [];
let i = 0;
function helper_func(inputArray) {
if (i >= inputArray.length) return; // change
if (inputArray.length === 0) {
return false;
}
if (inputArray[i] % 2 !== 0) {
result.push(inputArray[i]);
}
i++;
helper_func(array);
}
helper_func(array);
return result;
}
const res = findOddNum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
console.log(res);
BTW You don't have to use recursion just to get the odd numbers, It is one liner solution
array.filter((num) => num % 2)
function findOddNum(array) {
return array.filter((num) => num % 2);
}
const res = findOddNum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
console.log(res);
in case of recursion you need to give a base condition (termination condition), else it would go in an infinite loop
add the below line in helper_func
if(i>=inputArray.length)
return false;
function findOddNum(array) {
let result = [];
let i = 0;
function helper_func(inputArray) {
if (inputArray.length === 0) {
return false;
}
if(i>=inputArray.length){
return false;
}
if (inputArray[i] % 2 !== 0) {
result = inputArray[i];
}
i++;
helper_func(array);
}
helper_func(array);
return result;
}
const res = findOddNum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
console.log(res);

Solution to Euler Problem 5: My code doesn't work

I have a problem with Project Euler challenge 5. The challenge is based on finding the smallest positive number that is divisible by all the numbers from 1 to 20. This is my code:
let i = 1;
function myFunction (num) {
return i % num == 0
}
while (true) {
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
if (arr.every(myFunction)) {
console.log(i)
break;
} else {
i++
continue;
}
}
The code up to number 16 works fine (720720), but once I add another number to the array, in order (16, 17, 18, ...) it doesn't work anymore. I don't know why, I'm very new to programming. If you could instruct me.
The answer above takes way to long, like he said, quite a few seconds.
This code is longer but takes less than a second to come up with the result.
const divisibleByAllToN = (n) => {
const twoToN = Array(n - 1)
.fill(2)
.map((item, index) => item + index);
let numbersToBeMultiplied = twoToN.filter((item) => {
for (var i = 2; i < item; i++) if (item % i === 0) return false;
return item > 1;
});
numbersToBeMultiplied = numbersToBeMultiplied.map((item) => {
let value = item;
while (value * item <= n) {
value = value * item;
}
return value;
});
return numbersToBeMultiplied.reduce((acc, val) => acc * val);
};
divisibleByAllToN(20);
solved :
you need to return a condition in myFunction in order for array.every to work properly :
let i = 1;
function myFunction (num) {
var result = i / num
return parseInt(result) === result // condition HERE to check if result is an int
}
while (true) {
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
if (arr.every(myFunction)) {
console.log(i)
break;
} else {
i++
continue;
}
}
doing this we get (after about 20 seconds) the right result : 232792560

Function that removes every second element [duplicate]

This question already has answers here:
Remove items from array with splice in for loop [duplicate]
(5 answers)
Closed 2 years ago.
I want to write a function that removes every second element given that the array is longer than length 2. For instance:
removeEveryOther([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) returns [1, 3, 5, 7, 9]);
removeEveryOther([[1, 2]]) returns [[1, 2]])
Here is my try:
function removeEveryOther(arr){
for (i=0; i < arr.length; i++) {
if (arr.length>2) {
arr.splice((2*i), 1);
}
}
return arr
}
When invoked the function:
removeEveryOther(['1', '2', '3', '4', '5', '6', '7']) returns [ '2', '3', '5', '6' ]
Not sure what I'm doing wrong though, thanks for reading or even helping me out. Have a nice day!
You can use filter. And move the check up to the top:
function removeEveryOther(arr){
if (arr.length <= 2) {
return arr
}
return arr.filter((a,i) => i%2 == 0);
}
You should not mutate the original array and rather create a new one.
function removeEveryOther(arr){
if (arr.length > 2) {
return arr.filter((item, index) => index % 2 === 0);
} else {
return arr;
}
}
you can do this:
let removeEvery2 = (arr) => {
if(arr.length > 2) {
return arr.filter((el, i) => i % 2 === 0)
}
return arr
}
You could loop from the end, because with splicing from start all following indices are gone.
function removeEveryOther(array) {
if (array.length < 3) return array;
let i = Math.floor(array.length / 2) * 2 + 1;
while (i > 0) {
array.splice(i, 1);
i -= 2;
}
return array;
}
console.log(removeEveryOther([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); // [1, 3, 5, 7, 9]
console.log(removeEveryOther([1, 2]));
Use a simple for loop. Start at index 1 instead of 0 and increment i by 2 instead of 1.
function removeEveryOther(arr){
if(arr.length <= 2) return arr;
for(let i = 1; i < arr.length; i +=2){
arr.splice(i, 1);
}
return arr;
}
console.log(removeEveryOther([1, 2, 3, 4, 5, 6, 7, 8]));
console.log(removeEveryOther([1, 2]))
Try this function, I kept it very simple for your understanding and very near to what you wrote in the question
function removeEveryOther(arr)
{
if(arr.length <= 2)
return arr;
var arr_ret = [];
for (i=0; i < arr.length; i+=2)
{
arr_ret.push(arr[i])
}
return arr_ret
}

My swap function does not have any effect on my return array

const generateArray = (row, col) => {
let totalCells = row * col
const resultArray = [] // sorted
let subArray = []
let counter = 1
let trackRow = 1
let i = 0
while (i <= totalCells) {
if (counter === 1) subArray.push(trackRow)
else {
subArray.push(subArray[subArray.length - 1] + row)
}
if (subArray.length === col) {
resultArray.push(...subArray)
subArray = []
counter = 1
trackRow++
} else counter++
if (i === totalCells) { // perform swap if necessary
let lastIdx = resultArray.length - 1
let pointer1 = lastIdx
let count = 0
let pointer2 = col - 1
while(pointer1 >= 0) {
count++
if (count > col) {
pointer2 = lastIdx - pointer1 + col - 1
count = 1
}
if (pointer2 < 0 || pointer1 === pointer2 ) break // // pointers overlap and pointer on same row
if (count % 2 === 0) {
console.log('before swap', resultArray[pointer1], resultArray[pointer2]) // swap 16 13
swap(pointer2, pointer1, resultArray)
console.log('after swap', resultArray[pointer1], resultArray[pointer2]) // after swap 13 16
}
pointer2--
pointer1--
}
}
i++
}
return resultArray
}
function swap (a, b, array) {
[array[a], array[b]] = [array[b], array[a]]
}
console.log(
generateArray(4,5).map((x,i)=>`${x}`.padStart(2)+(i!=0&&i%5==4?'\n':',')).join('')
);
the swap function in the second while loop does not affect my return array for the generateArray method, even tho when printing to the console before and after the swap, the values have been perfectly swapped? see console.log 'before swap' and 'after swap'. Am I missing something?
console.log(generateArray1(4, 5))
expected result
[1, 8, 9, 16, 17
2, 7, 10, 15, 18,
3, 6, 11, 14, 19,
4, 5, 12, 13, 20]
actual result
[1, 5, 9, 13, 17,
2, 6, 10, 14, 18,
3, 7, 11, 15, 19,
4, 8, 12, 16, 20]
console.log
before swap 16 13,
after swap 13 16,
before swap 8 5,
after swap 5 8,
before swap 15 14,
after swap 14 15,
before swap 7 6,
after swap 6 7,
before swap 15 14
after swap 14 15,
before swap 7 6,
after swap 6 7,
before swap 16 13,
after swap 13 16,
before swap 8 5,
after swap 5 8
After pointers pass each other break out of loop. You've already swapped all elements of a column once each pointer has gone over half of the rows.
const generateArray = (row, col) => {
let totalCells = row * col
const resultArray = [] // sorted
let subArray = []
let counter = 1
let trackRow = 1
let i = 0
while (i <= totalCells) {
if (counter === 1) subArray.push(trackRow)
else {
subArray.push(subArray[subArray.length - 1] + row)
}
if (subArray.length === col) {
resultArray.push(...subArray)
subArray = []
counter = 1
trackRow++
} else counter++
if (i === totalCells) { // perform swap if necessary
let lastIdx = resultArray.length - 1
let pointer1 = lastIdx
let count = 0
let pointer2 = col - 1
while(pointer1 >= 0) {
count++
if (count > col) {
pointer2 = lastIdx - pointer1 + col - 1
count = 1
}
if (pointer2 < 0 || pointer1 <= pointer2 ) break // // pointers overlap and pointer on same row or pointers have passed each other
if (count % 2 === 0) {
console.log('before swap', resultArray[pointer1], resultArray[pointer2]) // swap 16 13
swap(pointer2, pointer1, resultArray)
console.log('after swap', resultArray[pointer1], resultArray[pointer2]) // after swap 13 16
}
pointer2--
pointer1--
}
}
i++
}
return resultArray
}
function swap (a, b, array) {
[array[a], array[b]] = [array[b], array[a]]
}
console.log(
generateArray(4,5).map((x,i)=>`${x}`.padStart(2)+(i!=0&&i%5==4?'\n':',')).join('')
);

Categories

Resources