I am doing an exercise, the problem is that my if/else structure does not work properly and I do not know why.
Here is the exercise statement and my code
Your task is to write a function, fizzBuzz, that accepts a number and returns a string:
'fizz' if the number is divisible by 3;
'buzz' if the number is divisible by 5;
'fizzbuzz' if the number is divisible by both 3 and 5.
'{number}' if the number doesn't fulfil any of the above conditions.
function fizzBuzz(number) {
if (number % 3 === 0) {
return "fizz"
};
if (number % 5 === 0) {
return "buzz"
};
if (number % 3 === 0 && number % 5 === 0) {
return "fizzbuz"
};
else return number
}
Try a little mental debugging. Look at your code and run different values through it in your mind:
What happens if you run the value 6 through it?
What happens if you run the value 10 through it?
What happens if you run the value 15 through it?
Ask yourself, "How could I fix this?" (hint: order of operations is important).
Something like this would do what you expect:
function fizzBuzz(n) {
const fizz = n % 3 ? '' : 'fizz' ;
const buzz = n % 5 ? '' : 'buzz' ;
return !fizz && !buzz ? '{number}' : `${fizz}${buzz}` ;
}
or this:
function fizzBuzz( n ) {
let s;
if ( n % 3 === 0 ) {
s = 'fizz' ;
if ( n % 5 === 0 ) {
s = 'fizzbuzz' ;
}
} else if ( n % 5 == 0 ) {
s = 'buzz' ;
} else {
s = '{number}' ;
}
return s;
}
This does [at most] 2 divisions and 2 comparisions.
The former does 2 divisions and 3-4 comparisons, so it is nominally less efficient.
But I know which version I'd rather look at.
The problem is, if a number is divisible by 5 and 3 (ex 15) "fizz" would only be returned (as a factor of 3) because every block {...} terminates the function with a return (this technique is called a "short-circuit", which isn't a bad practice). So you need to put the 5 and 3 condition first. Also that condition had an undefined variable called solution so that would've been the first error. One minor thing is that each block {...} was suffixed with a semi-colon: ; which is just bad formatting but it doesn't affect functionality.
function fB(number) {
if (number % 3 === 0 && number % 5 === 0) {
return "fizzbizz";
}
if (number % 3 === 0) {
return "fizz";
}
if (number % 5 === 0) {
return "bizz";
}
return number;
}
console.log(fB(15));
console.log(fB(575));
console.log(fB(49));
console.log(fB(51));
console.log(fB(80));
console.log(fB(375));
console.log(fB(99));
console.log(fB(Infinity));
Related
I am a beginner in Javascript now I have started, the only background I have is HTML and CSS. I'm trying to make a program that prints whether a number is even or odd. But to the odd numbers to add 2 and 4. My code :
function isEvenExceptTwoOrFour(number) {
if (number%2 == 0 ) {
console.log("The number is even");}
else {
console.log("The number is odd ")
}
}
You could write an if..else statement like this, using Logical Or (||) to check each of your conditions.
Below I used the statement
if (number === 2 || number === 4 || number % 2 === 1)
This checks if number === 2 or number === 4 or number % 2 === 1 (if the number is odd)
Code:
function isEvenExceptTwoOrFour(number) {
if (number === 2 || number === 4 || number % 2 === 1) {
console.log("Number is considered odd");
} else {
console.log("Number is considered even")
}
}
isEvenExceptTwoOrFour(1);
isEvenExceptTwoOrFour(2);
isEvenExceptTwoOrFour(6);
Write a function that accepts an array of exceptions, and returns a new function that accepts a number. The closure (the function that's returned) will then 1) check to see if the number is in the array, and return false otherwise 2) check to see if the number is even, and return true, otherwise 3) return false.
// Pass in the exceptions array and return a function
// that will accept a number
function checkIsEvenExcept(exceptions) {
return function (n) {
if (exceptions.includes(n)) return false;
return n % 2 === 0 && true;
return false;
}
}
const exceptions = [2, 4, 18];
// Assign the result of calling `checkIsEvenExcept` with the
// exceptions array to a variable. This will be the function that
// we can call
const isEven = checkIsEvenExcept(exceptions);
// We can now call that function with a number
// that we need to check
console.log(isEven(6));
console.log(isEven(2));
console.log(isEven(1));
console.log(isEven(4));
console.log(isEven(8));
console.log(isEven(18));
You can just add conditions whether the number is 2 or 4.
function isEvenExceptTwoOrFour(number) {
if ( number === 2 || number === 4 ||| number % 2 !== 0){
console.log("The number is odd ")
return
}
console.log("The number is even")
}
In the book Eloquent JS in the section of recursion, a program was given:
Consider this puzzle: by starting from the number 1 and repeatedly
either adding 5 or multiplying by 3, an infinite amount of new numbers
can be produced. How would you write a function that, given a number,
tries to find a sequence of such additions and multiplications that
produce that number? For example, the number 13 could be reached by
first multiplying by 3 and then adding 5 twice, whereas the number 15
cannot be reached at all.
I have following program which look like checks it, but I don't know how to make it print he sequence.
function tester (value, key) {
if (value == key) {
return 1;
}
else if (value > key) {
return 0;
}
else {
if ( tester(value+5, key) || tester(value*3, key) ) {
return 1;
}
return 0;
}
}
Your version is a little odd to me, returning 1 or 0 rather than true or false. Are you mostly used to a language that conflates booleans with such integers? But it looks like it should work.
I would write it a bit differently. I generally prefer my recursion to count down to smaller inputs. You can write a simple function to test the values like this:
const m3a5 = (n) => n < 1
? false
: n == 1
? true
: m3a5(n - 5) || (n % 3 === 0 && m3a5(n / 3))
console.log(m3a5(13)) //=> true
console.log(m3a5(15)) //=> false
console.log(m3a5(18)) //=> true
This should be entirely equivalent to yours, modulo the boolean/int differences.
With this one, you can can then expand it in a fairly straightforward manner to allow you to capture the steps:
const m3a5 = (n, steps = []) => n < 1
? false
: n == 1
? steps
: m3a5(n - 5, ['+5'].concat(steps))
|| (n % 3 === 0 && m3a5(n / 3, ['*3'].concat(steps)))
console.log(m3a5(13)) //=> ['*3', '+5', '+5']
console.log(m3a5(15)) //=> false
console.log(m3a5(18)) //=> ['*3', '+5, '+5', '+5']
Note that this will show one possible path, not all of them. For instance ['+5', '*3'] is another possible result for m3a5(18), one which you would get by switching the main branch to
: (n % 3 === 0 && m3a5(n / 3, ['*3'].concat(steps)))
|| m3a5(n - 5, ['+5'].concat(steps))
But if you want all the paths, that would be significantly different code.
You could store the sequence and if found the calculation return the sequence.
function tester(key, value = 1, sequence = value) {
if (value > key) {
return false;
}
if (value === key) {
return sequence;
}
return tester(key, value + 5, '(' + sequence + ' + 5)')
|| tester(key, value * 3, sequence + ' * 3');
}
console.log(tester(15));
console.log(tester(11));
console.log(tester(24));
console.log(tester(37));
Why would this not work if I took the first "if" statement and put it as the third "else if" statement? Just want to understand. Thanks!
function fizzBuzz(num) {
if ((num % 3 === 0) && (num % 5 === 0)) {
return 'fizzbuzz';
} else if (num % 3 === 0) {
return 'fizz';
} else if (num % 5 === 0) {
return 'buzz';
} else {
return num;
}
// if num is divisible by 3 return 'fizz'
// if num is divisible by 5 return 'buzz'
// if num is divisible by 3 & 5 return 'fizzbuzz'
// otherwise return num
}
If-else-if statement only work until one of the if statements becomes true.
This scenario prevents to check other "else if" conditions.
In your second scenario if modulus of "num" is 0 for 3 OR 5, it will stop checking other else if statements,
It is necessary to prioritize the sequence of if-else-if conditions.
So a if/else if statement works so that as soon as one of the ifs is true, it executes the code inside that if statement and then skips the rest of the ifs and else statements. In this case, however, the return ends the function and therefore it skips the rest of the code in the method.
If else if checks each condition on by one. If any of the conditional blocks executes, the rest of the conditions won't work.
function fizzBuzz(num) {
if ((num % 3 === 0) && (num % 5 === 0)) {
return 'fizzbuzz';
} else if (num % 3 === 0) {
return 'fizz';
} else if (num % 5 === 0) {
return 'buzz';
} else {
return num;
}
// if num is divisible by 3 return 'fizz'
// if num is divisible by 5 return 'buzz'
// if num is divisible by 3 & 5 return 'fizzbuzz'
// otherwise return num
}
In your example, if you put the first condition in the third block, i.e, else if, if the number is divisible by either 3 or, 5, the corresponding conditional block work and resulting in skipping the third block. The order of execution is important in if-else-if ladder.
Yes Remember that if/else-if/else executes in order and will stop when it finds an acceptable case. In your example, if (num % 3 === 0) you'll return return 'fizz' and that condition is true. So This is (num % 5 === 0) and (num % 3 === 0) && (num % 5 === 0)) are not mutually exclusive - they can both be true, so the order matters.
I've made a sequence of numbers from 0 to 20 and I want to change the sequence so once it comes up with a multiple of 3 and 5 it logs 'FizzBuzz' to the terminal then carries on with the rest of the numbers up to 20. My problem is once I have changed the number to the string the rest of the terms in the sequence come up with NaN. I know the problem with my code is that I'm changing the number to a string and you cannot perform addition to a string which is why NaN comes up. I'm pretty new to this so any thoughts on how to do complete this would be greatly appreciated. I've tried using .append() but I'm pretty sure I'm using it incorrectly.
My code thus far;
var increment = function(number)
{
for (var i = 1; i <= 20; i++)
{
console.log(number++)
if ((number % 3 === 0) && (number % 5 === 0))
{
number = "FizzBuzz"
console.log("FizzBuzz");
}
else if (number % 3 === 0)
{
console.log("Fizz");
}
else if (number % 5 === 0)
{
console.log("Buzz");
}
else
{}
}
}
increment(1)
When you find a multiple of 3 and 5, you are setting number to "FizzBuzz", which does not have a ++ operator. On the next iteration, you call ++ on number, which is now "FizzBuzz", so it logs NaN.
If you don't set number to "FizzBuzz" it should work fine.
This would do it
var increment = function()
{
for (var i = 1; i <= 20; i++)
{
if ((i % 3 === 0) && (i % 5 === 0))
{
console.log("FizzBuzz");
}
else if (i % 3 === 0)
{
console.log("Fizz");
}
else if (i % 5 === 0)
{
console.log("Buzz");
}
else{
console.log(i)
}
}
}
increment()
There's no need to pass the number parameter, since your for loop is already set to increment by 1 (i++).
Write a javascript program that displays the numbers from 10 to 100. But for multiples of 4 print "Penny" instead of the number and for multiples of 6 print "Leonard". For numbers which are multiples of both 4 and 6 print "Bazzinga"
I know how to do two parts struggling to print 6 and 4;
function baZzinga (number) {
for (var number = 10; number <= 101; number++)
if(number % 4 == 0) {
console.log("penny");
}
else if (number % 6 == 0) {
console.log("Leonard");
} else if ( not sure what goes here) {
help help help
} else {
console.log(number");
}
You want the and condition first. Try this
var result = document.getElementById("result");
function baZzinga (number) {
for (var number = 10; number <= 101; number++) {
if (number % 4 == 0 && number % 6 == 0) {
result.innerHTML += "Bazinga";
}
else if(number % 4 == 0) {
result.innerHTML += "penny";
}
else if (number % 6 == 0) {
result.innerHTML += "Leonard";
}
else {
result.innerHTML += number;
}
}
}
baZzinga()
<p id="result"></p>
I changed console.log to result.innerHTML because I wanted to demonstrate it in a snippet.
I have a few comments on your code -- constructive criticism, I hope! First, you don't need the number parameter in your bazzinga function. Next, the indentation of the code you posted makes it hard to read. Finally, you should almost always use === instead of ==. The === tests for strict equality, whereas == tries to do some type conversions first (and can therefore produce unexpected results). See the official docs.
To answer you question: check for divisibility by 6 AND 8 first. That way, it will override the individual cases. I believe you want something like this:
function bazzinga() {
for (var number = 10; number <= 100; number++) {
if (number % 4 === 0 && number % 6 === 0) {
console.log("Bazzinga");
} else if (number % 4 === 0) {
console.log("Penny");
} else if (number % 6 === 0) {
console.log("Leonard");
}
}
}
Here is a solution using the format you posted:
for (var number = 10; number <= 100; number++) {
if(number % 4 === 0 && number % 6 === 0){
console.log("bazzinga");
} else if(number % 4 === 0) {
console.log("penny");
} else if (number % 6 === 0) {
console.log("Leonard");
} else {
console.log(number);
}
}
Or use the ternary operator to be even more succinct!
for (var i = 10; i <= 100; i++){
var penny = i % 4 === 0;
var leonard = i % 6 === 0;
console.log(penny ? (leonard ? "bazzinga" : "penny"): leonard ? "leonard" : i);
}
function process_num(num) {
return num % 4 == 0 ? num % 6 == 0 ? "Bazzinga" : "Penny" : num % 6 == 0 ? "Leonard" : num;
}
for (x = 10; x <= 100; x++) { console.log( x + ': is ', process_num(x)) }
Nested Ternary operator for conciseness
If it passes outer ternary test it is divisible by 4:
Enter into nested termary one to test if num is also divisible by 6 for the BaZzinga prize!!
If it fails the BaZzinga challenge, we know it previously passed the divisible by 4 test so print "penny"
Failing the outer ternary condition, we know it's not divisible by 4:
Enter nested ternary two to consider if divisible by 6. If so print "Leonard".
If not it's failed both the outer (div by 4) and inner (div by 6) so return the number unchanged.
Now that the logic is contained in the function, we can just create a for loop to iterate over the required numbers printing out the correct values.