js card validation without converting to string or array - javascript

I'm trying to create a cs50 card validator with JavaScript. I'm having problems with the checksum counting. It should be sum % 10 === 0 //true.
let cards = [378282246310005, 371449635398431,
5555555555554444, 5105105105105100, 4012888888881881,
4012888888881880, 1234567890, 361049635398431], result = '';
cards.forEach( card => {
if (isCardValid(card)) {
result += card + ' = ';
checkBank(card);
}
});
document.getElementById('task6').innerHTML = result;
function checkBank(card) {
if ((card >= 340000000000000 && card < 350000000000000) || (card >= 370000000000000 && card < 380000000000000))
result += ("AMEX\n");
else if (card >= 5100000000000000 && card < 5600000000000000)
result += ("MASTERCARD\n");
else if ((card >= 4000000000000 && card < 5000000000000) || (card >= 4000000000000000 && card < 5000000000000000))
result += ("VISA\n");
else
result += ("INVALID\n");
}
function isCardValid(digits) {
let sum = 0;
for (let i = 0; i < digits.length; i++) {
let cardNum = parseInt(digits[i]);
if ((digits.length - i) % 2 === 0) {
cardNum = cardNum * 2;
if (cardNum > 9) {
cardNum = cardNum - 9;
}
}
sum += cardNum;
}
return sum % 10 === 0;
}
Here is some data to check validator work:
378282246310005 //AMEX
371449635398431 //AMEX
5555555555554444 //MASTERCARD
5105105105105100 //MASTERCARD
4012888888881881 //VISA
4012888888881880 //INVALID
1234567890 //INVALID
361049635398431 //INVALID
The main thing is, i can't use strings, arrays and any ready to use functions. Waiting for your help, thanks.
UPD
I solved the issue with an algorithm except for this card:
4012888888881880 //INVALID
My code thinks that this is a VISA card. Bank validation looks fine, so i don't know where to find the problem. Any suggestions where is problem?
UPD2
Final version
let cards = [378282246310005, 371449635398431,
5555555555554444, 5105105105105100, 4012888888881881,
4012888888881880, 1234567890, 361049635398431], result = '';
cards.forEach( card => {
if (isCardValid(card)) {
result += card + ' = ';
checkBank(card);
} else {
result += card + ' = INVALID Card\n'
}
});
document.getElementById('task6').innerHTML = result;
function checkBank(card) {
if ((card >= 340000000000000 && card < 350000000000000) || (card >= 370000000000000 && card < 380000000000000))
result += ("AMEX\n");
else if (card >= 5100000000000000 && card < 5600000000000000)
result += ("MASTERCARD\n");
else if ((card >= 4000000000000 && card < 5000000000000) || (card >= 4000000000000000 && card < 5000000000000000))
result += ("VISA\n");
else
result += ("INVALID Bank\n");
}
function isCardValid(card) {
let sum = 0, len, first = 0, second = 0;
for (len=0; card; Math.floor(card /= 10), ++len) {
let digit = Math.floor(card % 10);
second = first;
first = digit;
if (len & 1) {
digit += digit;
if (digit > 9) {
digit -= 9;
}
}
sum += digit;
}
return sum % 10 === 0;
}
<pre id="task6"></pre>

Related

how to get an output of next `ten` odd and even numbers after entering any random number in javascript

I want to have a logic where if I enter an even number I want next 10 even numbers to be printed and If I enter an odd number, I want next 10 odd numbers to be printed. How should I rectify this logic inside a function. If someone can please help me rectifying the logic which was answered.
JS
function oddEven() {
var input = prompt("");
for (let x = 1; x <= 10; x++) {
console.log(input + x * 2);
}
}
oddEven()
This should work for any number
const input = 2
for (let x = 1; x <= 10; x += 1) {
console.log(input + x * 2)
}
i hope this help
function printTen(input){
let list = []
let number = input
while(list.length <= 10){
number++
if(input % 2 === 0 && number % 2 === 0){
console.log(number + " is even");
list.push(number)
}else if(input % 2 !== 0 && number % 2 !== 0) {
console.log(number + " is odd");
list.push(number)
}
}
}
printTen(9)
let inputval = 2;
for (let x = 1; x <= 10; x++) {
console.log(inputval + x * 2)
}

Why Is Empty Argument Not Getting Identified as Undefined?

I have an (almost) working solution for a coding challenge:
function addLetters(...letters) {
let sum = 0;
const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
if (typeof letters === 'undefined' || letters === [] || letters === undefined) {
return 'z';
}
for (let i = 0; i < letters.length; i++) {
sum += (alphabet.indexOf(letters[i]) + 1);
}
if (sum <= 26) {
return alphabet[sum - 1];
} else {
while (sum > 26) {
sum = (sum - 26);
if (sum <= 26) {
return alphabet[sum - 1];
}
}
}
}
console.log(addLetters())
But as you can see, in this particular case of console.log(addLetters()), it's returning undefined instead of 'z' - why is that?
I think it must have something to do with the way that ...letters is a rest / default / destructured / spread argument.
The challenge does, in fact, want the argument to appear as a spread, but I don't know how to accommodate for it.
EDIT Test specs for challenge:
letters === []
Will always be false, as these are two different references which will never evaluate to true, you need to check the length of array to check if it's empty or not
Also you can safely remove the other two conditions from if statement as letters will always be an array
function addLetters(...letters) {
let sum = 0;
const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
if (letters.length === 0) {
return 'z';
}
for (let i = 0; i < letters.length; i++) {
sum += (alphabet.indexOf(letters[i]) + 1);
}
if (sum <= 26) {
return alphabet[sum - 1];
} else {
while (sum > 26) {
sum = (sum - 26);
if (sum <= 26) {
return alphabet[sum - 1];
}
}
}
}
console.log(addLetters())
Try this. :)
function addLetters(...letters) {
let sum = 0;
const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
if (!letters.length) {
return 'z';
}
for (let i = 0; i < letters.length; i++) {
sum += (alphabet.indexOf(letters[i]) + 1);
}
if (sum <= 26) {
return alphabet[sum - 1];
} else {
while (sum > 26) {
sum = (sum - 26);
if (sum <= 26) {
return alphabet[sum - 1];
}
}
}
}

Want user to input number for for loop to run Javascript

Trying to have a user input a number and if they type in a string I would like to prompt them to enter a number. Seems like I got that part right but how can I get the second prompt to keep popping up until the user enters a an actual number. As of now, once the user enters a string again nothing runs after that. Would appreciate any kind of suggestions.
Here is the code:
function enterNumber(n) {
n = parseInt(prompt("Please enter a number: "));
if (isNaN(n)) {
n = parseInt(prompt("You did not enter a number. Please enter a number: "));
for(var i = 1; i <= n; i++) {
if (i % 15 === 0) {
document.write("Fizz Buzz" + "<br>");
continue;
}
else if (i % 3 === 0){
document.write("Fizz" + "<br>");
continue;
} else if (i % 5 === 0) {
document.write("Buzz" + "<br>");
continue;
}
document.write(i + "<br>");
}
}
};
enterNumber();
Use while loop until the entered is number.
function enterNumber(n) {
while (isNaN(parseInt(n))) {
n = parseInt(prompt("Please enter a number: "));
}
for (var i = 1; i <= n; i++) {
if (i % 15 === 0) {
document.write("Fizz Buzz" + "<br>");
continue;
} else if (i % 3 === 0) {
document.write("Fizz" + "<br>");
continue;
} else if (i % 5 === 0) {
document.write("Buzz" + "<br>");
continue;
}
document.write(i + "<br>");
}
};
enterNumber();
You can also shorten you code using nested Ternary operators as follow.
function enterNumber(n) {
while (isNaN(parseInt(n))) {
n = parseInt(prompt("Please enter a number: "));
}
for (var i = 1; i <= n; i++) {
var title = i % 15 === 0 ? 'Fizz Buzz' : i % 3 === 0 ? 'Fizz' : i % 5 === 0 ? 'Buzz' : i;
document.write(title + "<br>");
}
};
enterNumber();
Try like this
function enterNumber(n) {
while (isNaN(n))
n = parseInt(prompt("You did not enter a number. Please enter a number: "));
for (var i = 1; i <= n; i++) {
if (i % 15 === 0) {
document.write("Fizz Buzz" + "<br>");
continue;
} else if (i % 3 === 0) {
document.write("Fizz" + "<br>");
continue;
} else if (i % 5 === 0) {
document.write("Buzz" + "<br>");
continue;
}
document.write(i + "<br>");
}
};
enterNumber();

Euler #2 Fibonacci Javascript function will only return zero after crunching the numbers

I wrote a function to solve Euler #2 in Javascript for adding all the even Fibonacci numbers up to 4,000,000. However, when I run my function, the chrome dev tool keeps giving me zero as the answer. I am not sure why.
function DoEverything() {
oldnum = 0;
num = 1;
total = 0;
result = addFibNumbers(num, oldnum);
console.log(result);
}
function addFibNumbers(num, oldnum) {
while(num < 4000000) {
if (num % 2 == 0) {
newnum = num + oldnum;
total += newnum;
oldnum = num;
num = newnum;
}
return total;
}
}
DoEverything();
The reason its returning 0:
result = addFibNumbers(num, oldnum);//num=1,oldNum=0
//function
while(num < 4000000) { //num is 1, so it enters while
if (num % 2 == 0) {// 1 % 2 == 1, so skip this if
return total;// this ends the function, returning total=0 as nothing was changed
I guess you are looking to do this:
while(num < 4000000) {
newnum = num + oldnum;
if (newnum % 2 == 0 && newnum < 4000000) {
total += newnum;
}
oldnum = num;
num = newnum;
}
return total;
I would guess it is your while loop
Change this:
while(num < 4000000) {
if (num % 2 == 0) {
newnum = num + oldnum;
total += newnum;
oldnum = num;
num = newnum;
}
return total;
}
to this:
while(num < 4000000) {
if (num % 2 == 0) {
newnum = num + oldnum;
total += newnum;
oldnum = num;
num = newnum;
}
}
return total;
Your while loop is useless with a return in it and no if statement to control it's use.
In addition to modifying your while statement inside of addFibNumbers() like so:
function addFibNumbers(num, oldnum) {
while(num < 4000000) {
newnum = oldnum + num;
if (oldnum % 2 == 0) {
total += oldnum;
}
oldnum = num;
num = newnum;
}
return total;
}
you will also need to initialize the first two Fibonacci terms to 1 and 2:
oldnum = 1; and num = 2;

parseFloat.toPreceision just adds zeros

I'm sending the number/string 0.001 to a the function below:
SignificantFigures = 4;
function LimitNumberOfDigits(num) {
var tempStr = "";
if (isNaN(num))
return "\xD8";
else{
if (parseFloat(num) === 0 || (num.toString().indexOf('.') === -1 && parseInt(num) < 9999) || num.toString().length <= 4) {
return num;
}
tempStr = parseFloat(num).toPrecision(SignificantFigures);
if (tempStr.indexOf("e") > -1) {
var startE = tempStr.indexOf("e");
var endE = 0;
for (var i = startE +2 ; i < tempStr.length; i++ ) { // + to ignore e and sign (+ or - )
if(parseInt(tempStr[i], 10) > 0) {
endE = i;
}else {
break;
}
}
if (startE + 2 === endE) {
var pow = tempStr[endE];
} else {
var pow = tempStr.substring(startE +2 ,endE);
}
return tempStr.substring(0,startE) + "*10<sup>"+ pow +"</sup>";
}else {
return parseFloat(num).toPrecision(SignificantFigures);
}
}
}
When im sending 0.2 or even 0.11 im getting like 0.2000 and 0.1100.
The issue here is the toPrecision acts like ToFixed.
Ideas?
EDIT
What i want? simple as that, if a numbers needs to be changed e.g 0.012312312041 it should be 0.0123 , numbers like 0.12 or 28 should stay the same.

Categories