Difficulty in constructing Luhn's algorithm - javascript

I want to construct Luhn's algorithm which is usually used to validate credit card numbers. Luhn's algorithm works like this:
Isolate every digit, starting from the right moving left, doubling every second one. If the doubled value is greater than 9, subtract 9 from it.
Sum all the transformed digits.
The original number valid according to Luhn's algorithm if and only if the sum ends in a 0.
function isValid(number) {
return LuhnDigitSum(number) % 10 === 0;
}
function LuhnDigitSum(number) {
let sum = 0;
let num_str = number.toString();
let reversed_num = num_str.split("").reverse().join("");
for (let i = 0; i < reversed_num.length; i++) {
let digit = parseInt(reversed_num[i]);
if (i % 2 !== 0 && (digit * 2) <= 9) {
digit = digit * 2;
sum += digit;
}
if (i % 2 !== 0 && (digit * 2) > 9) {
digit = (digit * 2) - 9;
sum += digit;
}
if (i % 2 === 0) {
sum += digit;
}
}
return sum;
}
When i run the code, the card numbers appeared to be invalid when they are supposed to be valid, and adding to that, the sum value were incorrect.
Your help is much appreciated. Thanks!!

Related

random number that always makes a total of 100 into array

Hi i am trying to create an array that always has a total of 100 based on random numbers. I get it to work when there is 2 or 3 rows but i can't get it to work if there are more as 4. Meaning i need to change the middle section. Here is simple code i made: (the length is the number of rows in the array)
var array = []
var length = 3; //4 , 5 , 6 ...
var number;
var calculate;
var totalProcessed;
for (i = 0; i < length; i++) {
// FIRST ONE
if(i == 0){
number = Math.floor(Math.random() * 100) + 1;
console.log(number);
totalProcessed = number;
array.push(number)
}
// MIDDLE SECTION
if(i > 0 && i == length-1){
if(length > 2){
calculate = 100 - number;
number = Math.floor(Math.random() * calculate) + 1
totalProcessed = totalProcessed + number;
console.log(number);
array.push(number)
}
}
// LAST ONE
if(i == length -1){
var lastOne = 100-totalProcessed;
console.log(lastOne);
array.push(lastOne)
}
}
console.log(array);
How should i change the middle section to be able to capture the numbers?
There are two errors in this code:
First:
You should change the == to < in order to be able to loop more then 3 times:
if(i > 0 && i == length-1)
Second:
I think your error occurs on the following line. You subtract number from 100 which is the previous generated number. You should instead generate a random number from everything that is left:
calculate = 100 - number;
So I think you should subtract the totalProcessed value instead.
calculate = 100 - totalProcessed;
Full working snippet:
var array = []
var length = 5; //4 , 5 , 6 ...
var number;
var calculate;
var totalProcessed;
for (i = 0; i < length; i++) {
// FIRST ONE
if(i == 0){
number = Math.floor(Math.random() * 100) + 1;
console.log(number);
totalProcessed = number;
array.push(number)
}
// MIDDLE SECTION
if(i > 0 && i < length-1){
if(length > 2){
calculate = 100 - totalProcessed;
number = Math.floor(Math.random() * calculate) + 1
totalProcessed = totalProcessed + number;
console.log(number);
array.push(number)
}
}
// LAST ONE
if(i == length -1){
var lastOne = 100-totalProcessed;
console.log(lastOne);
array.push(lastOne)
}
}
console.log(array);
let total = 0;
array.forEach(el => total += el)
console.log(total)
You should replace the "==" in the if statement of the middle section by "<".
I found your approach a bit hard to comprehend. Is the question setup same as what code is trying to do? Therefore I wrote an alternate example that solves the question (as currently explained):
let limit = 100;
const numbers = [...Array(limit)].map(() => {
const random = Math.floor(Math.random() * 100) + 1;
if (limit - random > 0) {
limit -= random;
return random;
}
return null;
}).concat(limit).filter((num) => num)
console.log(numbers);
It goes through 100 iterations (in case there would come only 1's :D) and then decreases the limit. And if next random number fits into limit, it's added to the result, otherwise it's a null.
And if it happens that after 100 iterations there are still limit left, it's concatenated to an existing array. Finally we filter out all the "nulls" (numbers that didn't fit in to limit) and voila.

how to make a script to print out all prime numbers in js

I want to know how I can improve my code by helping it find out what number is prime and what is not. I was thinking that I would divide a number by a number and then if it is a decimal number then it is prime,
I want it to have a loop to check every number 1 to 100 and see if it is a prime number
This is what I have so far:
for(let i = 1; i <= 100; i++) {
if(i == 1) {
}else if(i == 2) {
console.log(`${i} is a prime number`);
}else if(i >= 3){
x = i / 2;
tf = Number.isInteger(x);
if(tf == false && i >= 3) {
console.log(`${i} is a prime number`);
}
}
}
and so far it outputs 1 2 and all the odd numbers.
Create a function to test whether a number is prime or not (divisible only by 1 and itself). Then call this function inside the loop on each number.
function isPrimeNumber(no) {
if (no < 2) {
return false;
}
for (let i = 2; i < no; i++) {
if (no % i == 0) {
return false;
}
}
return true;
}
for (let i = 1; i <= 100; i++) {
if (isPrimeNumber(i)) {
console.log(i);
}
}
var numbers = new Array(101).fill(0).map((it, index) => index);
var halfWay = Math.floor(numbers.length / 2);
for (let i = 2; i <= halfWay; i++) {
if (!numbers[i]) continue;
for (let j = 2; j * i < numbers.length; j++) {
console.log(`${i} * ${j} = ${i * j}`);
numbers[j * i] = null;
}
}
console.log(numbers.filter(it => it));
Here is an attempt to mathematically find numbers between 1-100 that are primes.
Fill an array of numbers 0-100
For every number (starting at 2), multiply it by itself and all numbers after it, up to half of the array
For every computed number, remore it from the array, as it is not a prime
At the end, filter out all numbers that are null
As Taplar stated primes are numbers that only divide by the number itself and 1.
As far as improving your code. I would say you want to eliminate as many possible numbers with the fewest questions.
An example would be is the number even and not 2 if so it is not prime? The interesting part of this question you eliminate dividing by all even numbers as well. This instantly answers half of all possible numbers and halves the seek time with the ones you need to lookup.
So what would this look like?
function isPrime(num) {
// Check it the number is 1 or 2
if (num === 1 || num === 2) {
return true
}
// Check if the number is even
else if (num % 2 === 0) {
return false;
}
// Look it up
else {
// Skip 1 and 2 and start with 3 and skip all even numbers as they have already been checked
for (let i = 3; i <= num/2; i+=2) {
// If it divides correctly then it is not Prime
if (num % i === 0) {
return false
}
}
// Found no numbers that divide evenly it is Prime
return true
}
}
console.log('1:', isPrime(1))
console.log('2:', isPrime(2))
console.log('3:', isPrime(3))
console.log('4:', isPrime(4))
console.log('11:', isPrime(11))
console.log('12:', isPrime(12))
console.log('97:', isPrime(97))
console.log('99:', isPrime(99))
console.log('65727:', isPrime(65727))
console.log('65729:', isPrime(65729))

How to a count a specific digit in a number with javascript

I am trying to write a block of code which will separate digits (with modulus operator) in a number first and count how many digit "6" are there in the number.
I tried so many things but I think I have logic problem with the way I think.
output = [];
var count = 0;
while (a > 0){
output.push(a % 10);
a = Math.floor(a/10);
if(a == 6){
count++;
}
}
When I run this code on Safari, It shows the entered number as it is, but it shows "0" for the variable count.
Math.floor(a/10) doesn't give the current digit. a % 10 gives the current digit.
You have check if the current digit a % 10 is 6.
Live Example:
let output = [];
let count = 0;
let a = 1667;
while (a > 0) {
let digit = a % 10;
output.push(digit);
if (digit == 6) {
count++;
}
a = Math.floor(a / 10);
}
console.log(count);
You know the last digit, so you can subtract it and divide with 10, instead of using Math.floor.
let number = 1626364656; // has 5 sixes
let sixesCount = 0;
while (number > 0) {
const digit = number % 10;
if (digit === 6) {
sixesCount++;
}
number = (number - digit) / 10;
}
console.log('Found', sixesCount, 'sixes.'); // "Found 5 sixes."

Sum a negative number's digits

'Write a function named sumDigits which takes a number as input and
returns the sum of each of the number's decimal
digits.'
How can I sum the digits with the first digit being negative?
For example: sumDigits(-32); // -3 + 2 = -1;
I was able to solve it partially.
function sumDigits(number) {
return Math.abs(number).toString().split("").reduce(function(a, b) {
return parseInt(a) + parseInt(b);
}, 0);
}
console.log( sumDigits(-32) );
Simple math and recursion make short work of this problem.
Recall that when you divide a number by 10, the remainder is its rightmost decimal digit and the integer part of the quotient is the number formed by the remaining digits. In other words:
let n = 5678;
console.log(n % 10); // => 8
console.log(Math.floor(n / 10)); // => 567
With this in mind, summing a number's digits is a straightforward recursive procedure:
Procedure(n)
Divide n by 10.
Set digit to the remainder.
Set n to the integer part of the quotient.
If n = 0, return digit.
Otherwise, return digit + Procedure(n)
Keeping the sign for the leftmost digit adds a small amount of complexity, but not much. Here's how it looks in JavaScript:
function digitSum(n, sign=1) {
if (n < 0) {
sign = -1; // Save the sign
n = Math.abs(n);
}
const digit = n % 10; // Remainder of |n÷10|
n = Math.floor(n / 10); // Integer part of |n÷10|
if (n === 0) {
return sign * digit; // No digits left, return final digit with sign
}
return digit + digitSum(n, sign); // Add digit to sum of remaining digits
}
console.log(digitSum(32)); // => 5
console.log(digitSum(-32)); // => -1
Here is a way to do it with Array.prototype.reduce().
Stringify the input and split it on each character.
Iterate over the characters with reduce.
Initialize the accumulator with a sum of 0 and a multiplier of 1.
If the first character is a -, set the multiplier to -1
For the subsequent characters, multiply the digit with the multiplier and add it to the sum. Then set the multiplier back to 1 so the next digits will only be multiplied by 1.
const sumDigits = x => [...`${x}`].reduce(({ sum, mult }, x, i) => {
return i === 0 && x === '-' ? { sum: 0, mult: -1 } : { sum: sum + mult * x, mult: 1 };
}, { sum: 0, mult: 1 }).sum;
console.log(sumDigits(-32)); // -1
console.log(sumDigits(32)); // 5
console.log(sumDigits(5555)); // 20
Here's a way you can do it without String conversion -
const sumDigits = (n = 0) =>
n < 0
? n > -10
? n
: (-n % 10) + sumDigits (n / 10 >> 0)
: n < 10
? n
: (n % 10) + sumDigits (n / 10 >> 0)
console.log(sumDigits(-321))
// (-3 + 2 + 1)
// => 0
console.log(sumDigits(321))
// (3 + 2 + 1)
// => 6
The same answer using imperative style -
const sumDigits = (n = 0) =>
{ if (n < 0)
if (n > -10)
return n
else
return (-n % 10) + sumDigits (n / 10 >> 0)
else
if (n < 10)
return n
else
return (n % 10) + sumDigits (n / 10 >> 0)
}
console.log(sumDigits(-321))
// (-3 + 2 + 1)
// => 0
console.log(sumDigits(321))
// (3 + 2 + 1)
// => 6
An approach that does not require converting to a string adapted from another answer by #NinaScholz to a closely related question (for those that are bitwise shift operator challenged).
Converts the number to its absolute value, loops with modulus operator to sum the remainder after dividing by 10 until a ones value remains, and then subtracts the leftmost digit if the original number was negative.
const sumDigits = (n) => {
const negative = !!(n < 0);
let sum = 0;
let num = negative ? Math.abs(n) : n;
while (num) {
if (negative && num <= 10) {
sum -= num % 10;
} else {
sum += num % 10;
}
num = Math.floor(num / 10);
}
return sum;
};
console.log(sumDigits(-32));
// -1
You could take a different method for separating the digits and keep the first one with a possible sign.
'-32'.match(/-?\d/g)
returns
['-3', '2']
function sumDigits(number) {
return number.toString().match(/-?\d/g).reduce(function(a, b) {
return a + +b;
}, 0);
}
console.log(sumDigits(-32));
First, "decimal digits" means only the characters to the right of the decimal point. Converting the number to a string sets you up as JavaScript strings are arrays of characters. So, then it's just a matter of splitting out the decimal digits then summing them by iterating that array, then converting back to a number type.
//'Write a function named sumDigits which takes a number as input and returns the sum of each of the number's decimal digits.'
var a = 10.12345;
var b = -1012345;
function sumDigits(x){
var result = 0;
x = x.toString();
x = x.split('.')[1];
if (x == null){
//there's not decimal digits to sum!
return "there's not decimal digits to sum!"
}
for (var i = 0; i < x.length; i++) {
if (digit >= 0 && digit <= 9) { //just in case, probably unnecessary
var digit = Number(x[i]);
result = result + digit;
}
}
//if you care about negative uncomment this
//if(x[0] === "-"){
// result = result * -1;
//}
return result;
}
console.log(sumDigits(a));
console.log(sumDigits(b));
// try this to get the sum of negatives:
const sumOfNegative = (numbers) => {
let sum = 0;
numbers.forEach((number) => {
if (number < 0) {
sum += number;
}
});
return sum;
};

Extracting middle of string - JavaScript

I am trying to write an algorithm for this in JavaScript but I am getting a str.length is not a function...
function extractMiddle(str) {
var position;
var length;
if(str.length() % 2 == 1) {
position = str.length() / 2;
length = 1;
} else {
position = str.length() / 2 - 1;
length = 2;
}
result = str.substring(position, position + length)
}
extractMiddle("handbananna");
Because string length is not a function, it's a property.
function extractMiddle(str) {
var position;
var length;
if(str.length % 2 == 1) {
position = str.length / 2;
length = 1;
} else {
position = str.length / 2 - 1;
length = 2;
}
return str.substring(position, position + length)
}
console.log(extractMiddle("handbananna"));
Here is an another way to do this:
function extractMiddle(str) {
return str.substr(Math.ceil(str.length / 2 - 1), str.length % 2 === 0 ? 2 : 1);
}
// the most amazing
const getMiddle = s => s.substr(s.length - 1 >>> 1, (~s.length & 1) + 1);
// should return "dd"
console.log(getMiddle('middle'))
// >>> is an unsigned right shift bitwise operator. It's equivalent to division by 2, with truncation, as long as the length of the string does not exceed the size of an integer in Javascript.
// About the ~ operator, let's rather start with the expression n & 1. This will tell you whether an integer n is odd (it's similar to a logical and, but comparing all of the bits of two numbers). The expression returns 1 if an integer is odd. It returns 0 if an integer is even.
// If n & 1 is even, the expression returns 0.
// If n & 1 is odd, the expression returns 1.
// ~n & 1 inverts those two results, providing 0 if the length of the string is odd, and 1 if the length of the sting is even. The ~ operator inverts all of the bits in an integer, so 0 would become -1, 1 would become -2, and so on (the leading bit is always the sign).
// Then you add one, and you get 0+1 (1) characters if the length of the string is odd, or 1+1 (2) characters if the length of the string is even.
#author by jacobb
the link of the source is: https://codepen.io/jacobwarduk/pen/yJpAmK
That seemed to fix it!
function extractMiddle(str) {
var position;
var length;
if(str.length % 2 == 1) {
position = str.length / 2;
length = 1;
} else {
position = str.length / 2 - 1;
length = 2;
}
result = str.substring(position, position + length)
console.log(result);
}
https://jsfiddle.net/sd4z711y/
The first 'if' statement is to get the odd number while the 'else if' is to get the even number.
function getMiddle(s)
{
if (s.length % 2 == 1) {
return s.substring((s.length / 2)+1, (s.length / 2))
} else if (s.length % 2 == 0) {
return s.substring((s.length / 2)-1, (s.length / 2)+1)
}
}
console.log(getMiddle("handers"));
console.log(getMiddle("test"));
Here is my solution :-
function pri(word) {
if (!word) return 'word should have atleast one character';
let w = [...word].reduce((acc, val) => (val == ' ' ? acc : (acc += val)));
let res = '';
let length = word.length;
let avg = length / 2;
let temp = avg % 2;
if (temp == 0) {
res += word.charAt(avg - 1) + word.charAt(avg);
} else {
res += word.charAt(avg);
}
return res;
}
console.log(pri("Lime")); // even letter
console.log(pri("Apple")); // odd letter
console.log(pri("Apple is Fruit")); // String sequence with space
console.log(pri("")); // empty string
here is my solution
function getMiddle(s){
let middle = Math.floor(s.length/2);
return s.length % 2 === 0
? s.slice(middle-1, middle+1)
: s.slice(middle, middle+1);
}
function extractMiddle(s) {
return s.substr(Math.ceil(s.length / 2 - 1), s.length % 2 === 0 ? 2 : 1);
}
extractMiddle("handbananna");
str.length is a property. Just get rid of the parentheses. Example:
if (str.length == 44) {
length is a property of string, not a function. Do this instead:
str.length % 2 === 1
Also, use I suggest favoring === over ==
Since length is not a function, there is no need to use ().
function getMiddle(str) {
if(str.length % 2 === 0 ) {
return str.substr(str.length/2-1, 2);
} else {
return str.charAt(Math.floor(str.length/2));
}
}
console.log(getMiddle("middbkbcdle"));

Categories

Resources