I'm fairly new to Javascript and have been able to get by so far by just following tutorials and reading forums but this one really stumped me for a while.
Basically I wanted to have a counter for numbers that contain seven digits, I found a few things but none that really made sense to me so I wrote this:
imgNumber++;
if (imgNumber < 10){function add(number){return '00000' + number}};
if (imgNumber > 10 && imgNumber < 100){function add(number){return '0000' + number}};
if (imgNumber > 100 && imgNumber < 1000){function add(number){return '000' + number}};
if (imgNumber > 1000 && imgNumber < 10000){function add(number){return '00' + number}};
if (imgNumber > 10000 && imgNumber < 100000){function add(number){return '0' + number}};
if (imgNumber > 100000 && imgNumber < 1000000){function add(number){return '' + number}};
It works as far as I can tell. My question is this: Do you foresee any issues with this and if not is there a cleaner way to write all this?
I'll appreciate any and all replys.
Cheers,
Colin
As with all programming functions are your friend. I searched google for padding zeros javascript and got directed to this site.
function pad(number, length) {
var negative = number < 0;
var str = '' + Math.abs(number);
while (str.length < length) {
str = '0' + str;
}
if(negative) str = '-' + str;
return str;
}
Using this you would just generate your number standard and prior to storing/outputting it you'd run it through this function:
pad(1,7);
A one liner:
var output = sprintf("%07d", 30);
Believe me, it will save you a lot of time in javascript (and in other languages). You can download the implementation in http://sprintf.googlecode.com/files/sprintf-0.7-beta1.js
By today, this code works right now, perhaps you need to change the src of the library for a more updated:
<script type="text/javascript" src="http://sprintf.googlecode.com/files/sprintf-0.7-beta1.js"> </script>
<script type="text/javascript" >
alert(sprintf("%04d",4));
</script>
More information, here, plus there are other implementations of this useful method.
Why don't you just take the log (base 10) of the number as an indicator of how many digits to add.
If log(N) is between 0 and less than 1, N is a one digit number.
If log(N) is greater than or equal to 1 but less than 2, N has two digits, and so forth.
I don't actually code in JavaScript, so I don't know if you have access to a log function, but if you do, this is a very terse way to get the result.
John Doner
Related
So I tried doing this leetcode question: https://leetcode.com/problems/arranging-coins/
After doing some math, I came up with this solution:
var arrangeCoins = function(n) {
return parseInt((Math.sqrt(8*n+1)-1)/2);
};
This does return the right answer. However, I noticed that it is literally the bottom of the barrel when it comes to execution speed. Comparatively, the alternative solution, where binary search is used to search for the right value in the range of 1 to n is around 2 to 3 times faster than mine. So something like this:
var arrangeCoins = function(n) {
let left = 1;
let right = n;
while(left + 1 < right){
let mid = Math.floor(left + (right - left) / 2);
let sum = (mid + 1) * mid / 2
if(sum === n){
return mid;
}else if(sum < n){
left = mid;
}else{
right = mid;
}
}
return (right + 1) * right / 2 === n? right : left;
}
Compared to my solution, this has the time complexity of O(log n), which would mean it should have been slower, at least in theory.
Why is this the case? What can I do to improve the execution speed of my solution?
This is not an authoritative answer but:
sqrt is relatively slow
it looks like your parseInt is useless and wastes time
Hello everyone;
I have been grappling with 3 cases that are not passing. The difference is so subtle with a digit change. I tried JavaScript notations for very large numbers or scientific notations but of of no avail.
The challenge is linked here.
The different test cases are here.
console.log(separateNumbers("90071992547409929007199254740993")) //Gives NO although it should give "yes"
console.log(separateNumbers("90071992547401929007199254740193")) //Gives YES when 9 replaced with 1//
My code goes like:
function separateNumbers(s) {
var beautiful = true;
for (let len = 1; len < s.length; len++) {
var first = s.substr(0, len);
var num = s.substr(0, len);
if (s.length <= len) {
continue;
}
var sNew = ''.concat(first.toString());
while (sNew.length < s.length) {
num++;
sNew = sNew.concat(num.toString());
}
if (sNew === s) {
console.log('YES ' + first);
beautiful = false;
continue;
}
}
if (beautiful) {
console.log('NO')
}
}
Your helps are very much appreciated. Thanks many
There is no issue with your algorithm, it is working exactly as expected (and is right, btw).
The issue is with JS-Number data-type. The MAX_SAFE_INTEGER constant has a value of 9007199254740991. The reasoning behind that number is that JavaScript uses double-precision floating-point format numbers as specified in IEEE 754 and can only safely represent integers between -(2^53 - 1) and 2^53 - 1
Instead of using std Number type, use BIGINT. That should give you correct answer for the test case.
I'm pretty awful at Javascript as I've just started learning.
I'm doing a Luhn check for a 16-digit credit card.
It's driving me nuts and I'd just appreciate if someone looked over it and could give me some help.
<script>
var creditNum;
var valid = new Boolean(true);
creditNum = prompt("Enter your credit card number: ");
if((creditNum==null)||(creditNum=="")){
valid = false;
alert("Invalid Number!\nThere was no input.");
}else if(creditNum.length!=16){
valid = false;
alert("Invalid Number!\nThe number is the wrong length.");
}
//Luhn check
var c;
var digitOne;
var digitTwo;
var numSum;
for(i=0;i<16;i+2){
c = creditNum.slice(i,i+1);
if(c.length==2){
digitOne = c.slice(0,1);
digitTwo = c.slice(1,2);
numSum = numSum + (digitOne + digitTwo);
}else{
numSum = numSum + c;
}
}
if((numSum%10)!=0){
alert("Invalid Number!");
}else{
alert("Credit Card Accepted!");
}
</script>
The immediate problem in your code is your for loop. i+2 is not a proper third term. From the context, you're looking for i = i + 2, which you can write in shorthand as i += 2.
It seems your algorithm is "take the 16 digits, turn them into 8 pairs, add them together, and see if the sum is divisible by 10". If that's the case, you can massively simplify your loop - you never need to look at the tens' place, just the units' place.
Your loop could look like this and do the same thing:
for (i = 1; i < 16; i +=2) {
numSum += +creditNum[i];
}
Also, note that as long as you're dealing with a string, you don't need to slice anything at all - just use array notation to get each character.
I added a + in front of creditNum. One of the issues with javascript is that it will treat a string as a string, so if you have string "1" and string "3" and add them, you'll concatenate and get "13" instead of 4. The plus sign forces the string to be a number, so you'll get the right result.
The third term of the loop is the only blatant bug I see. I don't actually know the Luhn algorithm, so inferred the rest from the context of your code.
EDIT
Well, it would have helped if you had posted what the Luhn algorithm is. Chances are, if you can at least articulate it, you can help us help you code it.
Here's what you want.
// Luhn check
function luhnCheck(sixteenDigitString) {
var numSum = 0;
var value;
for (var i = 0; i < 16; ++i) {
if (i % 2 == 0) {
value = 2 * sixteenDigitString[i];
if (value >= 10) {
value = (Math.floor(value / 10) + value % 10);
}
} else {
value = +sixteenDigitString[i];
}
numSum += value;
}
return (numSum % 10 == 0);
}
alert(luhnCheck("4111111111111111"));
What this does is go through all the numbers, keeping the even indices as they are, but doubling the odd ones. If the doubling is more than nine, the values of the two digits are added together, as per the algorithm stated in wikipedia.
FIDDLE
Note: the number I tested with isn't my credit card number, but it's a well known number you can use that's known to pass a properly coded Luhn verification.
My below solution will work on AmEx also. I submitted it for a code test a while ago. Hope it helps :)
function validateCard(num){
var oddSum = 0;
var evenSum = 0;
var numToString = num.toString().split("");
for(var i = 0; i < numToString.length; i++){
if(i % 2 === 0){
if(numToString[i] * 2 >= 10){
evenSum += ((numToString[i] * 2) - 9 );
} else {
evenSum += numToString[i] * 2;
}
} else {
oddSum += parseInt(numToString[i]);
}
}
return (oddSum + evenSum) % 10 === 0;
}
console.log(validateCard(41111111111111111));
Enjoy - Mitch from https://spangle.com.au
#Spangle, when you're using even and odd here, you're already considering that index 0 is even? So you're doubling the digits at index 0, 2 and so on and not the second position, fourth and so on.. Is that intentional? It's returning inconsistent validations for some cards here compared with another algorithm I'm using. Try for example AmEx's 378282246310005.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I create a Zerofilled value using JavaScript?
I have to output a day number that must always have 3 digits. Instead of 3 it must write 003, instead of 12 it must write 012. If it is greater than 100 output it without formatting.
I wonder if there's a regex that I could use or some quick in-line script, or I must create a function that should do that and return the result. Thanks!
How about:
zeroFilled = ('000' + x).substr(-3)
For arbitrary width:
zeroFilled = (new Array(width).join('0') + x).substr(-width)
As per comments, this seems more accurate:
lpad = function(s, width, char) {
return (s.length >= width) ? s : (new Array(width).join(char) + s).slice(-width);
}
I found an elegant solution by Samuel Mullen on his blog. I simply optimized the zeroes creation.
function lpad(value, padding) {
var zeroes = new Array(padding+1).join("0");
return (zeroes + value).slice(-padding);
}
Usage: lpad(12, 3) results in "012"
You can do this...
("00" + day).slice(-3)
It'll prepend the zeros, and then .slice() will always give you the last 3 values of the string.
Here is a simple function that pads a number with zeroes to a certain width:
function zeroFill(number, width) {
width -= number.toString().length;
if(width > 0) {
return new Array(width + (/\./.test(number) ? 2 : 1)).join('0') + number;
}
return number + ""; // always return a string
}
(from How can I pad a value with leading zeros?)
Since the original answer did not explain how the function works I'll do it here.
width initially contains the total length you want, so width - number_of_digits is the number of padding chars necessary.
new Array(len + 1).join(str) repeats str len times.
The regex is used to add an additional padding zero in case of a number containing a decimal point since the point was also included in the number_of_digits determined using number.toString().length
One possible solution:
while ((val+"").length < 3) {
val = "0" + val;
}
DEMO: http://jsfiddle.net/WfXVn/
I would write the following function:
var pad = function(n, length) {
var str = "" + n;
if(str.length < length) str = new Array(length - str.length).join("0") + str;
return str;
};
Here's something I haven't been able to figure out for the last 30 minutes.
var file = Components.classes["#mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
file.initWithPath( sPath );
...
if ( file.fileSize < (offsetContent+bytesToRead) )
{
wt.BO.log(file.fileSize + "<" + offsetContent + "+" + bytesToRead);
bytesToRead = file.fileSize - offsetContent;
}
What the above code displays is: "577 < 50 + 50"... o.O How the hell is 577 < 100? The if statement is true...can't seem to figure why.
The plus operator (+) is used to concatenate strings, or to add up numbers in JavaScript.
Since offsetContent or bytesToRead are strings, both variables are concatenated:
"50" + "50" = "5050"
When comparing these values, the string is converted to a number, and
"5050" == 5050 -> 577 < 5050 is true, of course.
Some methods to fix the code:
// Substract bytesToRead from both sides
if ( file.fileSize - bytesToRead < offsetContent )
// Or, Turn the comparison operator, and make the right side negative
if ( file.fileSize >= -bytesToRead - offsetContent )