why can't get expected result after truthy switch statements? - javascript

Trying to find all divisible numbers of an integer but getting an incorrect answer after switch loop.
function divisors(integer) {
let divNumbers = []
switch(true) {
case (integer % 2 === 0):
divNumbers.push(2);
case (integer % 3 === 0):
divNumbers.push(3);
case (integer % 4 === 0):
divNumbers.push(4);
case (integer % 5 === 0):
divNumbers.push(5);
break;
default: divNumbers.push(integer)
}
return divNumbers;
};
divisors(15)
Getting 3, 4, 5 as divNumbers where 4 shouldn't be here. Why?

Here's the correct solution that will not be hardcoded:
var divisors = function (num) {
const initial = num, result=[];
while(num--) {
if (initial % num ===0) {
result.push(num);
}
}
return result;
}
If you want to get the number itself in divisors, do this:
var divisors = function (num) {
const initial = num, result=[];
num++;
while(num--) {
if (initial % num ===0) {
result.push(num);
}
}
return result;
}

Switch stamenets fall through by default. To prevent this, you should break after each one. Having said that, you'll only end up with 3 in that case, as 15 is divisible by 3. Once the division was successful, you'd break out of the switch:
function divisors(integer) {
let divNumbers = []
switch (true) {
case (integer % 2 === 0):
divNumbers.push(2);
break;
case (integer % 3 === 0):
divNumbers.push(3);
break;
case (integer % 4 === 0):
divNumbers.push(4);
break;
case (integer % 5 === 0):
divNumbers.push(5);
break;
default:
divNumbers.push(integer)
}
return divNumbers;
};
console.log(divisors(15));
To ensure that you end up with both 3 and 5 in the array, I'd recommend swapping to if conditionals instead, because you want multiple conditions to trigger:
function divisors(integer) {
let divNumbers = []
if (integer % 2 === 0) {
divNumbers.push(2);
}
if (integer % 3 === 0) {
divNumbers.push(3);
}
if (integer % 4 === 0) {
divNumbers.push(4);
}
if (integer % 5 === 0) {
divNumbers.push(5);
}
return divNumbers;
}
console.log(divisors(15));
Hope this helps! :)

Related

Cant' find out the cause of infinite loop in Javascript (After translating a function from Python)

I'm translating a function I've wrote in Python to Javascript but In JS I have an infinite loop while in Python everything works fine.
Here's my code in Python:
def isPrime(n: int) -> bool:
# Since neither 1 nor 0 is a prime number, return false
if n == 1 or n == 0:
return False
# Loops from 2 to n
for i in range(2, n):
# If the number is divisible by i, then n is not a prime number
if n % i == 0:
return False
# Otherwise, n is a prime number
return True
def getPrimes(n: int) -> list[int]:
"""
Take a positive int number n as a parameter and prints to the console the first n prime numbers
"""
primes = []
count = 0
while len(primes) < n:
if isPrime(count):
primes.append(count)
count += 1
return primes
Here's my code in Javascript:
function isPrime(num) {
// Since neither 1 nor 0 is a prime number, return false
if (num == 1 || num == 0) {
return false
}
// Loops from 2 to n
for (let i = 2; i <= num; i++) {
// If the number is divisible by i, then n is not a prime number
if (num % i == 0) {
return false
}
}
// Otherwise, n is a prime number
return true
}
function getPrimes(num) {
let primes = [];
count = 0;
while (primes.length < num) {
if (isPrime(count) === true) {
primes.push(count);
}
count++;
}
return primes;
}
In Python, when I call the function getPrimes(n) it correctly returns an array containing the first n prime numbers.
But in Javascript, the same function causes an infinite loop.
Why is that happening? Thank you in advance.
It's not causing infinite loop, your isPrime(num) function just returns false for every number, because you are having i <= num, which causes num % num == 0 evaluating to true and returning false. Just fix it to i < num
function isPrime(num) {
// Since neither 1 nor 0 is a prime number, return false
if (num === 1 || num === 0) {
return false
}
// Loops from 2 to n
for (let i = 2; i < num; i++) {
// If the number is divisible by i, then n is not a prime number
if (num % i === 0) {
return false
}
}
// Otherwise, n is a prime number
return true
}
function getPrimes(num) {
let primes = [];
count = 0;
while (primes.length < num) {
if (isPrime(count) === true) {
primes.push(count);
}
count++;
}
return primes;
}
console.log(getPrimes(10)) // [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

(Javascript) Recursive function that works on first call but not on second When Oscillating numbers

I'm trying to do iteration for oscillating number, by using Recursion on Javascript, but unfortunately it didn't get the expected output. The first call works but the second fail. Here is the code:
let result = [];
function oscillator(A) {
if (result[result.length - 1] == A) {
// base case
return result;
}
let number = A;
if (number > 0) {
number -= 5;
result.push(number);
} else {
number += 5;
result.push(number);
}
return oscillator(number);
}
console.log(oscillator(16));
The Result shown is just [ 11 ]
When The expected output should be: 16 11 6 1 -4 1 6 11 16
What should be changed
From that code, the base case of the recursion should be changed to:
if (base == 0) {
base = A;
} else if (A == base) {
return result;
}
Full code
let result = [];
var base = 0;
var dirDown = true;
function oscillator(A) {
// need to set the condition to check if the base case is number is reached.
if (base == 0) {
base = A;
} else if (A == base) {
return result;
}
// Push the number into result
result.push(A);
let number = A;
if ((number > 0) && dirDown) {
number -= 5;
} else {
// set dirDown to false to prevent the number keep looping in -4 and 1
dirDown = false;
number += 5;
}
return oscillator(number);
}
console.log(oscillator(16));
The result
If you run the snippet above, you will see this result:
[16, 11, 6, 1, -4, 1, 6, 11]
Thank you for tidying the code
Added some comment in the code for explanation
JS Fiddle

Basic JavaScript: Counting Cards - Card Counting Function with Strings

The card function has been explained multiple times, and I understand it. For those who do not know it: my function receives a card parameter, which can be a number or a string. I then increment or decrement the global count variable according to the card's value 2,3,4,5,6 increments, 7,8,9 keeps it at 0, while 10, J, Q, K, A decrements it. My function then returns a string with the current count and the string "Bet" if the count is positive, or "Hold" if it is negative.
So I understand how the function is done, and FreeCodeCamp accepted my solution as technically it meets their conditions. But have a question regarding this function:
var count = 0;
function cc(card) {
if (card >= 2 && card <= 6) {
count++;
} else if (card >= 7 && card <= 9) {
count += 0;
} else {
count--;
}
if (count <= 0) {
return count + " Hold";
} else {
return count + " Bet";
}
}
console.log(cc(2));
console.log(cc(3));
console.log(cc(7));
console.log(cc('K'));
console.log(cc('A'));
As I can see, the first condition is fairly simple and easy to define, so is the else if. In the third case, there are both numbers and strings involved. Does this not mean that when I put ANY string into cc, it will decrement? As anything that is not between 2 and 6, or 7 and 9, will automatically decrement? Even if the user inputs something that is not a card or is not a value from the list?
I understand that there is a list of predefined card values and names, but nevertheless, is there any better way to condition my statement to make sure that my condition will ONLY run IF the card is either 10, J, Q, K or A, and not any other value?
You can change your current else, to return and error message or just return immediately in case of the input being a non-valid card, and add another else-if to check for 10 through Ace:
if (card >= 2 && card <= 6) {
count++;
} else if (card>=7 && card <=9) {
count+= 0;
} else if (card === 10 || card === 'J' || card === 'Q' || card === 'K' || card === 'A'){
count--;
}else {
//Either just return or alert an error message and return
}
There are a number of ways you could deal with this situation. You could initially parse the input, and say assign 'J' to 11, 'Q' to 12, 'K' to 13 and 'A' to 1 (if you need to distinguish), or just a common number to that category. Everything else is an invalid input and you return immediately/post an error message. Something like:
var count = 0;
function cc(card) {
if (card == 'J' || card == 'Q' || card == 'K' || card == 'A')
card = 11;
if (card >= 2 && card <= 6) {
count++;
} else if (card>=7 && card <=9) {
count+= 0;
} else if (card >= 10 && card <= 11) {
count--; // to keep structure cleaner we use dummy 11 value
} else
//error message
if (count <= 0) {
return count + " Hold";
} else {
return count + " Bet";
}
}
cc(2); cc(3); cc(7); cc('K'); cc('A');
Also, you need to make sure to handle lower case and upper case values for the picture cards.
Define a set of allowed values and check if the value you are given is within that set using .includes(). For example:
var count = 0;
function cc(card) {
// Only change code below this line
const up = [2,3,4,5,6];
const no = [7,8,9];
const down = [10, "J", "Q", "K", "A"];
if(up.includes(card))count++;
if(down.includes(card))count--;
const str = count > 0 ? "Bet" : "Hold";
return `${count} ${str}`;
// Only change code above this line
}
// Add/remove calls to test your function.
// Note: Only the last will display
cc(2); cc(3); cc(7); cc('K'); cc('A');
Bear in mind this is type sensitive.
Another possibility is something like the following, which explicitly lists the changes for each card:
const counter = () => {
let count = 0
let values = {2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 0, 8: 0,
9: 0, 10: -1, J: -1, Q: -1, K: -1, A: -1}
return (card) => {
const change = values[card] || 0 // no change if card is, say, 'XYZ' or 'Joker'
count += change
return count <= 0 ? 'Hold' : 'Bet'
}
}
const cc = counter();
console.log(cc(2));
console.log(cc(3));
console.log(cc(7));
console.log(cc('K'));
console.log(cc('A'));
For a list as short as thirteen values, I think this sort of explicit list is cleaner.
This also encapsulates the count variable in a closure. I find that cleaner than a global variable.
Where the comment talks about jokers, you might want some more robust error-handling:
if (!(card in values)) {throw 'Bad card'}
const change = values[card]
You could use a regular expression at the very top of your function to skip all the conditionals and return a handy message if the argument passed in doesn't match a valid card:
// Check if card is valid
var cardRegex = /^(10|[2-9AJQK])$/i;
if (!cardRegex.test(card)) {
return "Invalid Card";
}
So, in the context of your code, it would look like:
var count = 0;
function cc(card) {
// Check if card is valid
var cardRegex = /^(10|[2-9AJQK])$/i;
if (!cardRegex.test(card)) {
return "Invalid Card";
}
if (card >= 2 && card <= 6) {
count++;
} else if (card >= 7 && card <= 9) {
count += 0;
} else {
count--;
}
if (count <= 0) {
return count + " Hold";
} else {
return count + " Bet";
}
}
// Valid inputs
console.log(cc(2));
console.log(cc(3));
console.log(cc(7));
console.log(cc('K'));
console.log(cc('a'));
// Invalid inputs
console.log(cc('e'));
console.log(cc('L'));
console.log(cc(0));
My solution for Basic JavaScript: Counting Cards
function cc(card) {
// Only change code below this line
if(card >= 2 && card <= 6) {
count++;
} else if (card === 10 ||card === 'J' || card === 'Q' || card === 'K' || card === 'A') {
count = count - 1;
}
if (count > 0) {
return count + ' Bet';
}
return count + ' Hold';
// Only change code above this line
}
My solution, based on what we learned so far.
Maybe it isnĀ“t the best, but it also works.
var count = 0;
function cc(card) {
// Only change code below this line
switch(card){
case 2:
case 3:
case 4:
case 5:
case 6:
count++;
break
case 7:
case 8:
case 9:
count = count;
break
case 10:
case 'J':
case 'Q':
case 'K':
case 'A':
count--;
break;
}
if (count <=0) {
return count + ' Hold';
}
else {
return count + ' Bet'
}
// Only change code above this line
}
console.log(cc(2));
console.log(cc(3));
console.log(cc(7));
console.log(cc('K'));
console.log(cc('A'));
let count = 0;
function cc(card) {
switch (card) {
case 2:
case 3:
case 4:
case 5:
case 6:
count++;
break;
case 10:
case 'J':
case 'Q':
case 'K':
case 'A':
count--;
}
if (count > 0) {
return count + " Bet";
} else {
return count + " Hold";
}
}

Javascript Logical Operator AND inside 'if' condition

Inside the if condition, I have num1 and num2 which are checked to see if they can be divided by 2 to determine whether they are odd or not. As you can see, I am checking to see if when divided by 2, whether the answer is 0 or not for both num1 and num2. I'm not sure why it evaluates to true when I enter num2 argument as an even number.
function areBothOdd(num1, num2) {
if(num1 % 2 === 0 && num2 % 2 === 0){
return false;
}
else {
return true;
}
}
var output = areBothOdd(7, 4);
console.log(output); // --> true
Why am I getting true?
And why does this code evaluate as false?
function areBothOdd(num1, num2) {
if(num1 % 2 !== 0 && num2 % 2 !== 0){
return true;
}
else {
return false;
}
}
var output = areBothOdd(7, 4);
console.log(output); // --> false
You need a logical OR ||, instead of an logical AND.
Your test with
num1 % 2 === 0
returns true for even numbers, because even numbers have a remainder of 0 by division with 2.
function areBothOdd(num1, num2) {
if (num1 % 2 === 0 || num2 % 2 === 0) {
return false;
} else {
return true;
}
}
console.log(areBothOdd(7, 4)); // --> false
console.log(areBothOdd(7, 5)); // --> true
console.log(areBothOdd(4, 4)); // --> false
For a check with logical AND, you need to negate the parts and change the logical operator from OR to AND, as the De_Morgan's laws describes the transformation.
num1 % 2 === 0 || num2 % 2 === 0 both parts
num1 % 2 !== 0 && num2 % 2 !== 0 are equal
^^^^ ^^ ^^^
function areBothOdd(num1, num2) {
if (num1 % 2 !== 0 && num2 % 2 !== 0) {
return false;
} else {
return true;
}
}
console.log(areBothOdd(7, 4)); // --> false
console.log(areBothOdd(7, 5)); // --> true
console.log(areBothOdd(4, 4)); // --> false
It always evaluate to true because, what && operator does is to check both condition, if both condition is true than the block will get executed, otherwise else block will get executed.
% will return remainder which will never be zero. in your case while calculate modules i.e 7%2 will result 1.
either you need to use logical !! operator or you can change your condition.
function areBothOdd(num1, num2) {
if(num1 % 2 === 0 && num2 % 2 === 0){
return false;
}
else {
return true;
}
}
var output = areBothOdd(7, 4);
console.log(output);
var x = 7%2;
document.getElementById("demo").innerHTML = x;
<span id="demo"></span>
Because of Short-Circuit evaluation. Simply put, your num2 % 2 === 0 part of condition will not be evaluated. 7 % 2 does not equal to zero hence your function returns true. That's it.
To quote from MDN:
false && (anything) is short-circuit evaluated to false.
true || (anything) is short-circuit evaluated to true.
Note that the anything part of the above expressions is not evaluated,
so any side effects of doing so do not take effect
1st Case :
function areBothOdd(num1, num2) {
if(num1 % 2 === 0 && num2 % 2 === 0){
return false;
}
else {
return true;
}
}
var output = areBothOdd(7, 4);
console.log(output); // --> true
Here, if condition fails as (num1 % 2 === 0 && num2 % 2 === 0) will become (false && true) as 7 is an odd number and 4 is an even number.Hence, it will execute the else block and return true.
2nd Case :
function areBothOdd(num1, num2) {
if(num1 % 2 !== 0 && num2 % 2 !== 0){
return true;
}
else {
return false;
}
}
var output = areBothOdd(7, 4);
console.log(output); // --> false
Here again if condition fails as (num1 % 2 !== 0 && num2 % 2 !== 0) will become (true && false).Hence, it will execute the else block and return false.
Conclusion : As Nina Scholz suggested, use logical OR(||) instead of an logical AND(&&).
DEMO
function areBothOdd(num1, num2) {
if(num1 % 2 === 0 || num2 % 2 === 0){
return false;
}
else {
return true;
}
}
var output = areBothOdd(7, 4);
console.log(output); // --> false
You can change the if condition.In this case,if num1 is odd it doesnot satisfy the if condition and therefore returns true which is else condition.
You can try something like this.
function areBothOdd(int num1,int num2){
if(num1%2 !==0){
if(num2%2!==0){
return true;
}
return false;
}
return false;
}
I'm not sure why it evaluates to true when I enter num2 argument as an even number. Why am I getting true?
There are three possible conditions to consider:
both are odd,
both are even, or
one is odd and one is even
Your first example checks condition 2 (both even) and returns false only for this. Condition 1 and 3 are captured by the else statement and both return true (which is not what you want, you want condition 3 to return false). When providing the numbers 7 and 4, this corresponds to condition 3, which illustrates how the function fails.
And why does this code evaluate as false?
Your second example gets it right, it checks for condition 1 (both odd), and returns true. Otherwise, for condition 2 and 3 it returns false, which is what you want.
Your first code example commented:
function areBothOdd(num1, num2) {
if(num1 % 2 === 0 && num2 % 2 === 0){ // if both are even
return false;
}
else { // otherwise, if one is even or both are odd
return true;
}
}
var output = areBothOdd(7, 4); // one number is even
console.log(output); // --> true
(Note that num % 2 === 0 is a way to test for an even number, and num % 2 !== 0, num % 2, or num & 1 are ways to test for an odd number.)
With a few small changes, the function will work as intended (corresponds to your code example 2):
function areBothOdd(num1, num2) {
if(num1 % 2 && num2 % 2){ // if both are odd
return true;
}
else { // otherwise, if one is even or both are even
return false;
}
}
var output = areBothOdd(7, 4); // one number is even
console.log(output); // --> false
Or just simply:
function areBothOdd(num1, num2) {
return num1 & 1 && num2 & 1
}
Demo code and tests:
function areBothOdd(num1, num2) {
if(num1 % 2 && num2 % 2){ // if both are odd
return true;
}
else { // otherwise, if one is even or both are even
return false;
}
}
// tests
test(1, 1, true); // both are odd
test(2, 2, false); // none are odd
test(1, 2, false); // only one is odd
test(2, 1, false); // only one is odd
// test function
function test(num1, num2, expected) {
console.log(
areBothOdd(num1, num2) == expected ?
'Passes' : 'Fails'
)
}

javascript fizzbuzz switch statement

I'm currently taking the code academy course on Javascript and I'm stuck on the FizzBuzz task. I need to count from 1-20 and if the number is divisible by 3 print fizz, by 5 print buzz, by both print fizzbuzz, else just print the number. I was able to do it with if/ else if statements, but I wanted to try it with switch statements, and cannot get it. My console just logs the default and prints 1-20. Any suggestions?
for (var x = 0; x<=20; x++){
switch(x){
case x%3==0:
console.log("Fizz");
break;
case x%5===0:
console.log("Buzz");
break;
case x%5===0 && x%3==0:
console.log("FizzBuzz");
break;
default:
console.log(x);
break;
};
};
Switch matches the x in switch(x){ to the result of evaluating the case expressions. since all your cases will result in true /false there is no match and hence default is executed always.
now using switch for your problem is not recommended because in case of too many expressions there may be multiple true outputs thus giving us unexpected results. But if you are hell bent on it :
for (var x = 0; x <= 20; x++) {
switch (true) {
case (x % 5 === 0 && x % 3 === 0):
console.log("FizzBuzz");
break;
case x % 3 === 0:
console.log("Fizz");
break;
case x % 5 === 0:
console.log("Buzz");
break;
default:
console.log(x);
break;
}
}
I thought switch too,but no need.
for (var n = 1; n <= 100; n++) {
var output = "";
if (n % 3 == 0)
output = "Fizz";
if (n % 5 == 0)
output += "Buzz";
console.log(output || n);
}
Switch statement checks if the situation given in the cases matches the switch expression. What your code does is to compare whether x divided by 3 or 5 is equal to x which is always false and therefore the default is always executed. If you really want to use a switch statement here is one way you can do.
for (var i=1; i<=30; i++){
switch(0){
case (i % 15):
console.log("fizzbuzz");
break;
case (i % 3):
console.log("fizz");
break;
case (i % 5):
console.log("buzz");
break;
default:
console.log(i);
}
}
Not to too my own horn but this is much cleaner:
var numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
for (var i = 1; i <= numbers.length; i++) {
if (i % 15 === 0) {
console.log("FizzBuzz");
} else if (i % 5 === 0) {
console.log("Buzz");
} else if (i % 3 === 0) {
console.log("Fizz");
} else {
console.log(i);
}
};
The switch(true) part of this statement helped me. I was trying to do a switch statement for fizzbuzz. My solution incorporates the coding style of Rosettacodes - general solution. Most significantly the use of force typing to shorten the primary conditionals. I thought, it was valuable enough to post:
var fizzBuzzSwitch = function() {
for (var i =0; i < 101; i++){
switch(true) {
case ( !(i % 3) && !(i % 5) ):
console.log('FizzBuzz');
break;
case ( !(i % 3) ):
console.log('Fizz');
break;
case ( !(i % 5) ):
console.log('Buzz');
break;
default:
console.log(i);
}
}
}
Here's what made it clear for me, might help :
It's a misinterpretation of what switch (x){} means.
It doesn't mean : "whenever whatever I put inbetween those brackets is true, when the value of x changes."
It means : "whenever x EQUALS what I put between those brackets"
So, in our case, x NEVER equals x%3===0 or any of the other cases, that doesn't even mean anything. x just equals x all the time. That's why the machine just ignores the instruction. You are not redefining x with the switch function. And what you put inbetween the brackets describes x and x only, not anything related to x.
In short :
With if/else you can describe any condition.
With switch you can only describe the different values taken by the variable x.
Here's a solution incorporating #CarLuvr88's answer and a switch on 0:
let fizzBuzz = function(min, max){
for(let i = min; i <= max; i++){
switch(0){
case i % 15 : console.log('FizzBuzz'); break;
case i % 3 : console.log('Fizz'); break;
case i % 5 : console.log('Buzz'); break;
default : console.log(i); break;
}
}
}
fizzBuzz(1,20)
We can use a function to find a multiple of any number and declare two variables to identify these multiples so that if you want to change the multiples you only need to change at max 2 lines of code
function isMultiple(num, mod) {
return num % mod === 0;
}
let a = 3;
let b = 5;
for(i=0;i<=100;i++){
switch(true){
case isMultiple(i,a) && isMultiple(i,b):
console.log("FizzBuzz")
case isMultiple(i,a):
console.log("Fizz");
case isMultiple(i,b):
console.log("Buzz");
default:
console.log(i);
}
}

Categories

Resources