how to fix the while loop? - javascript

function div(num) {
while (num <= 9) {
var a = (num - (num % 10));
var b = (a / 10)
var c = 0
var digits = num.toString().split("")
for (i = digits.length - 1; i > 2; i--) {
c = digits[i]
}
num = b - (c * 2);
}
return num;
}
document.write(div(1234))
My code is supposed to take the number and get the last digit and subtract it from the rest of the number, and repeat the process until the answer is lesser or equal to 9. I made a while loop but I keep on getting the number I started with. What is wrong and how do I fix it?
Edit :
It is supposed to multiply the last digit by 2 and then subtract it from the rest of the number and then repeat the process until the answer is less than or equal to 9

while (num<=9)
This should be
while (num>=9)

As of now, the while loop will be executed only for a number that is less than 9.
Use while(num >= 9) instead of while(num <= 9).
function div(num) {
while (num >= 9) {
var a = (num - (num % 10));
var b = (a / 10)
var c = 0
var digits = num.toString().split("")
for (i = digits.length - 1; i > 2; i--) {
c = digits[i]
}
num = b - (c * 2);
}
return num;
}
document.write(div(1234));

Related

I need to validate an input string using checksum for alphanumerics

I have the following function that validates a digits input consisted of only numbers based on Luhn Algorithm:
function isCheckdigitCorrect(value) {
// accept only digits, dashes or spaces
if (/[^0-9-\s]+/.test(value)) return false;
var nCheck = 0, nDigit = 0, bEven = false;
value = value.replace(/\D/g, "");
for (var n = value.length - 1; n >= 0; n--) {
var cDigit = value.charAt(n),
nDigit = parseInt(cDigit, 10);
if (bEven) {
if ((nDigit *= 2) > 9) nDigit -= 9;
}
nCheck += nDigit;
bEven = !bEven;
}
return (nCheck % 10) == 0;
}
Is there anyway that I can validate also alphanumerics, so let's suppose I have a valid ID: AC813(6) , () is the checksum. So is there a way that I can prevent users having to type mistakenly AF813(6) so this would tell user incorrect ID.
I appreciate your help
Substituting digits for alphabetic characters to calculate a checksum severely reduces the robustness of the check, and the simplest suggestion I can come up with is to use the Luhn mod N algorithm described on Wikipedia.
Translating the algorithm into JavaScipt was relatively straight forward: the following is not my code but a translation from the wiki article - so I won't pretend it is optimal. It is intended to work with strings of case insensitive ASCII alphabetic characters and decimal digits. For documentation see the wiki.
// based on https://en.wikipedia.org/wiki/Luhn_mod_N_algorithm
var charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
function NumberOfValidInputCharacters () { return charset.length; }
function CodePointFromCharacter(character) { return charset.indexOf(character)};
function CharacterFromCodePoint( codePoint) { return charset[codePoint]};
function GenerateCheckCharacter (input) {
var factor = 2;
var sum = 0;
var n = NumberOfValidInputCharacters();
input = input.toUpperCase();
// Starting from the right and working leftwards is easier since
// the initial "factor" will always be "2"
for (var i = input.length - 1; i >= 0; i--) {
var codePoint = CodePointFromCharacter(input[i]);
if( codePoint < 0) {
return "";
}
var addend = factor * codePoint;
// Alternate the "factor" that each "codePoint" is multiplied by
factor = (factor == 2) ? 1 : 2;
// Sum the digits of the "addend" as expressed in base "n"
addend = Math.floor(addend / n) + (addend % n);
sum += addend;
}
// Calculate the number that must be added to the "sum"
// to make it divisible by "n"
var remainder = sum % n;
var checkCodePoint = (n - remainder) % n;
return CharacterFromCodePoint(checkCodePoint);
}
function ValidateCheckCharacter(input) {
var factor = 1;
var sum = 0;
var n = NumberOfValidInputCharacters();
input = input.toUpperCase();
// Starting from the right, work leftwards
// Now, the initial "factor" will always be "1"
// since the last character is the check character
for (var i = input.length - 1; i >= 0; i--) {
var codePoint = CodePointFromCharacter(input[i]);
if( codePoint < 0) {
return false;
}
var addend = factor * codePoint;
// Alternate the "factor" that each "codePoint" is multiplied by
factor = (factor == 2) ? 1 : 2;
// Sum the digits of the "addend" as expressed in base "n"
addend = Math.floor(addend / n) + (addend % n);
sum += addend;
}
var remainder = sum % n;
return (remainder == 0);
}
// quick test:
console.log ("check character for 'abcde234': %s",
GenerateCheckCharacter("abcde234"));
console.log( "validate 'abcde2349' : %s " ,
ValidateCheckCharacter( "abcde2349"));
console.log( "validate 'abcde234X' : %s" ,
ValidateCheckCharacter( "abcde234X"));
If you just want to do the Luhn algorithm with letters replacing some of the numbers, then include an additional step to convert letters to numbers within your function.
So if you wanted to allow say A, B, C, D that convert to 0, 1, 2, 3 then you could do:
function isCheckdigitCorrect(value) {
// Letter to number mapping
var letters = {a:'0', b:'1', c:'2', d:'3'};
// Convert letters to their number equivalents, if they have one
value = value.split('').reduce(function(s, c){
return s += letters[c.toLowerCase()] || c;
},'');
// Continue as currently
// accept only digits, dashes or spaces
if (/[^0-9-\s]+/.test(value)) return false;
var nCheck = 0, nDigit = 0, bEven = false;
value = value.replace(/\D/g, "");
for (var n = value.length - 1; n >= 0; n--) {
var cDigit = value.charAt(n),
nDigit = parseInt(cDigit, 10);
if (bEven) {
if ((nDigit *= 2) > 9) nDigit -= 9;
}
nCheck += nDigit;
bEven = !bEven;
}
return (nCheck % 10) == 0;
}
// In the following, A = 0 and D = 3
console.log(isCheckdigitCorrect('375767AA4D6AA21'));
You can implement other algorithms in a similar way.

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"));

How to rewrite a excel-vba to acrobat javascript?

this is a code from a excel macro (VB), how can i rewrite it, so it works on adobe acrobat?
for e.g. nummer is "161628686041430"
Function upsp(nummer)
' Übergeben wird KdNr+Serviceart+Paketnummer (ohne 1Z)
'
qsm = 0
For i = 1 To 15
p = Mid(nummer, i, 1)
If Asc(p) > 57 Then p = (Asc(p) - 63) Mod 10
qsm = qsm + (p * (2 - i Mod 2))
Next
upsp = 10 - (qsm Mod 10)
If upsp = 10 Then upsp = 0
End Function
the result of this function should be "2".
Thanks for help.
I think this is what you're looking for, I tried to keep as close as possible to the Excel code, hoping it would be easier to follow. Let me know if you have any questions...
alert(upsp('161628686041430'));
function upsp(nummer) {
var qsm;
var p;
var returnValue;
qsm = 0;
for (var i = 0; i < nummer.length; i++) {
p = nummer.substr(i, 1);
if (p.charCodeAt(0) > 57) {
p = (p.charCodeAt(0) - 63) % 10;
}
qsm = qsm + (p * (2 - ((i + 1) % 2)));
}
returnValue = 10 - (qsm % 10);
if (returnValue === 10) {
returnValue = 0;
}
return returnValue;
}

How to avoid this bad for loop?

I'm trying to loop through a big number (6 billion to be exact), but I can't because my computer freezes. How can I work my way around this. I'm supposed to find the largest prime factor of 600851475143.
function prime(n) {
if (n === 1 || n === 2) return false;
if (n % 2 === 0 || n % 3 === 0) return false;
return true;
}
var n = 600851475143;
for (var i = 1, c = []; i < n; i++) {
if ((n % i === 0) && prime(i)) {
c.push(i);
}
}
I'm done with it yet. I'm storing the primes in an array.
Your prime() function doesn't do what the name says it should. There are many efficient ways of factoring primes, try this one for example:
var x = 600851475143;
var i = 2;
var sk;
while(i <= x)
{
while (x % i == 0)
{
sk = i;
x = x / i;
}
i++;
}
console.log(sk);
Output: 6857
This page has another (view source) function for factoring.
That prime function doesn't returns prime numbers only, but all those positive integers that aren't 1 or divisible by 2 and 3.
Let's see the whole algorhythm again. First of all, notice that you don't need to iterate through n, you can stop at its square root (think about it).
var divs = [];
if (!(n & 1)) { // Checking if n is even, using faster bit operators
divs.push(2);
while (!(n & 1)) n >>= 1;
}
var d = 3, l = Math.sqrt(n);
while (d < l) {
if (!(n % d)) {
divs.push(d);
while (!(n % d)) n /= d;
l = Math.sqrt(n);
}
d += 2; // No even numbers except 2 are prime, so we skip them
}
if (n !== 1) divs.push(n);
Now divs[divs.length - 1] contains your largest prime divisor of n, and divs all the prime factors.

Math.ceil to nearest five at position 1

Okay....
I have a lot of uncontrolled numbers i want to round:
51255 -> 55000
25 -> 25
9214 -> 9500
13135 -> 15000
25123 -> 30000
I have tried modifying the numbers as string and counting length....
But is there a simple way using some Math function maybe?
Here's my late answer. Uses no Math methods.
function toN5( x ) {
var i = 5;
while( x >= 100 ) {x/=10; i*=10;}
return ((~~(x/5))+(x%5?1:0)) * i;
}
DEMO: http://jsbin.com/ujamoj/edit#javascript,live
[51255, 24, 25, 26, 9214, 13135, 25123, 1, 9, 0].map( toN5 );
// [55000, 25, 25, 30, 9500, 15000, 30000, 5, 10, 0]
Or this is perhaps a bit cleaner:
function toN5( x ) {
var i = 1;
while( x >= 100 ) {x/=10; i*=10;}
return (x + (5-((x%5)||5))) * i;
}
DEMO: http://jsbin.com/idowan/edit#javascript,live
To break it down:
function toN5( x ) {
// v---we're going to reduce x to the tens place, and for each place
// v reduction, we'll multiply i * 10 to restore x later.
var i = 1;
// as long as x >= 100, divide x by 10, and multiply i by 10.
while( x >= 100 ) {x/=10; i*=10;}
// Now round up to the next 5 by adding to x the difference between 5 and
// the remainder of x/5 (or if the remainder was 0, we substitute 5
// for the remainder, so it is (x + (5 - 5)), which of course equals x).
// So then since we are now in either the tens or ones place, and we've
// rounded to the next 5 (or stayed the same), we multiply by i to restore
// x to its original place.
return (x + (5-((x%5)||5))) * i;
}
Or to avoid logical operators, and just use arithmetic operators, we could do:
return (x + ((5-(x%5))%5)) * i;
And to spread it out a bit:
function toN5( x ) {
var i = 1;
while( x >= 100 ) {
x/=10;
i*=10;
}
var remainder = x % 5;
var distance_to_5 = (5 - remainder) % 5;
return (x + distance_to_5) * i;
}
var numbers = [51255, 25, 9214, 13135, 25123, 3, 6];
function weird_round(a) {
var len = a.toString().length;
var div = len == 1 ? 1 : Math.pow(10, len - 2);
return Math.ceil(a / 5 / div) * div * 5;
}
alert(numbers.map(weird_round));
Also updated for numbers below 10. Won't work properly for negative numbers either, just mention if you need this.
DEMO
I'm not sure why, but I thought it would be fun with regular expressions:
var result = +(number.toString().replace(/([1-9])([0-9])(.+)/, function() {
return Math.ceil(+(arguments[1] + '.' + arguments[2])) * 10 - (+arguments[2] < 5?5:0) + arguments[3].replace(/./g, '0');
}));
Working Demo
with(Math) {
var exp = floor(log(number)/log(10)) - 1;
exp = max(exp,0);
var n = number/pow(10,exp);
var n2 = ceil(n/5) * 5;
var result = n2 * pow(10,exp);
}
http://jsfiddle.net/NvvGf/4/
Caveat: only works for the natural numbers.
function round(number) {
var numberStr = number + "",
max,
i;
if (numberStr[1] > '4') {
numberStr[0] = parseInt(numberStr[0]) + 1;
numberStr[1] = '0';
} else {
numberStr[1] = '5';
}
for (i = 2; max = numberStr.length; i < max; i += 1) {
numberStr += '0';
}
return parseInt(numberStr);
}
Strange coincidence, I wrote something really similar not so long ago!
function iSuckAtNames(n) {
var n = n.toString(), len = n.length, res;
//Check the second number. if it's less than a 5, round down,
//If it's more/equal, round up
//Either way, we'll need to use this:
var res = parseFloat(n[0]) * Math.pow(10, len - 1); //e.g. 5 * 10^4 = 50000
if (n[1] <= 5) {
//we need to add a 5 right before the end!
res += 5 * Math.pow(10, len - 2);
}
else {
//We need another number of that size
res += Math.pow(10, len - 1);
}
return res;
}

Categories

Resources