I am new to JavaScript. Here is my task
I want to generate a Serial number starting with 'A' and with numbers in increment manner.
Example : A000001, A000002,...,A000010 and so on.
I want to generate this serial number according to the current year I am giving as an input.
Example :
If current year is 2020, then A000001, A000002,...,A000010 and so on
If current year is 2021, then B000001, B000002,...,B000010 and so on
If current year is 2046, then it should be like AA000001, AA000002,...,AA000010 and so on . Because 26 letters, it should start from AA. Same way for 2047 - AB, 2048 - AC and so on.
function colName(n) {
var ordA = 'A'.charCodeAt(0);
var ordZ = 'Z'.charCodeAt(0);
var len = ordZ - ordA + 1;
var year = 2020;
var s = "";
while(n >= 0) {
s = String.fromCharCode(n % len + ordA) + s;
n = Math.floor(n / len) - 1;
}
return s;
}
Here I have a code that will generate alphabets in the manner of A,B,C,....Z,AA. But when I call the function colName(n), the value of 'n' should be given from 0 to start from 'A'. I want to give the value as my current year. If I give n value 2020, then it should show 'A'.
I am stuck here and not getting idea about how to do this and how to add incrementing number with this. Here I am giving an image of my concept
Thank you.
You need to subtract n by 2020, to make it starting point (think of it as offset).
Also 2027 will be H not AA, since 2020=A, and 26 characters from there will be Z.
function colName(n) {
var ordA = 'A'.charCodeAt(0);
var ordZ = 'Z'.charCodeAt(0);
var len = ordZ - ordA + 1;
n -= 2020;
var s = "";
while(n >= 0) {
s = String.fromCharCode(n % len + ordA) + s;
n = Math.floor(n / len) - 1;
}
return s;
}
document.write(colName(2020));
Related
I'm trying to figure out the sample answer I've found.
Could anyone explain the code below step by step?
The 'str = "0" + str' part is most confusing.
const fillZero = function (n, w) {
let str = String(n);
for (let i = str.length; i < w; i++) {
str = "0" + str;
}
return str;
}
console.log(fillZero(5, 3)); // 005
console.log(fillZero(12, 3)); // 012
console.log(fillZero(123, 3)); // 123
With str = "0" + str he is using string concatenation. For example, if the string was Hello, after that line of code it will be 0Hello.
Usually when using i in the for loop, most people would set i = 0, you are setting it to the length of characters of "n". So as long as n < w (w = 3, according to above), you will be adding 0 + n until n = w.
in the first example: n = 1, w = 3.
str = 0 + 5 after first iteration THEN
str = 0 + 05 after second iteration
i is no longer lesser than 3, so final output is 005.
I am trying to run a program that, upon receiving a positive integer, splits it into its separate digits like so. Number is 652, output is 2, 5, 6. There is supposed to no arrays and I can't make the number a string. I've written most of the code but it's missing something that I can't figure out. The issue is really that I don't know how to store the numbers to be output during iterations. Would appreciate any help. I am using a while loop but for loop could be used as well.
function problem_09() {
var outputObj=document.getElementById("output");
var a = parseInt(prompt("Please enter a number: ", ""));
var i = 0;
var digits = ;
outputObj.innerHTML="number: "+a+"<br><br>its digits: ";
while (a>0) {
digits[i]= a%10;
a = Math.floor(a/10);
i++;
}
outputObj.innerHTML=digits;
outputObj.innerHTML=outputObj.innerHTML+"<br><br>"+"program ended";
document.getElementsByTagName("button")[0].setAttribute("disabled","true");
}
I know the issue lies with the digits and the i but I don't know how to fix it.
You could take a place value and multiply by 10 for each iteration.
function getDigits(value) {
var place = 1;
while (value >= place) {
console.log(Math.floor(value / place) % 10);
place *= 10;
}
}
getDigits(652);
getDigits(100);
A solution without using Math.floor(...)
function getDigits(n) {
var res = [];
while (n > 0) {
var r = n % 10,
d = n - r,
curr = d / 10;
n = curr;
res.push(r);
}
return res;
}
var n = prompt("Enter a number: "),
output = document.getElementById("output");
output.textContent = getDigits(+n);
<div id="output"></div>
then just to replace
var i = 0;
var digits = [];
while (a > 0) {
digits.push(a % 10);
a = Math.floor(a/10);
i++;
}
the question does not make really sense.. without arrays, but he is actually expecting the result to be an array...
How do I add 1 to this string in JavaScript?
var message = "12345612345678901234567890";
I want the output like this:
"12345612345678901234567891"
I tried this:
var message = "12345612345678901234567890";
message = parseInt(message);
var result = message + 1;
But parseInt returned a value in scientific notation like 1.234567896453e+25.
Try the big integer library BigInteger.js to add large numbers.
var message = "12345612345678901234567890";
var messageAsNumber = bigInt(message);
var messagePlusOne = messageAsNumber.add('1');
console.log(messagePlusOne.toString());
<script src="https://peterolson.github.io/BigInteger.js/BigInteger.min.js"></script>
There is no need to use libraries (2022), you can just use JS BigInt object
let message = "12345612345678901234567890";
let messageBigInt = BigInt(message);
console.log(messageBigInt + BigInt(1)); // 12345612345678901234567891n
You can create an array from the string in .lengths of 3 beginning from the end of the string.
Use a pattern which checks if adding 1 would result in the index of the array as a number would sum to 1000, if true, increment previous array index by 1 and fill the current array index with "000".
The pattern below only checks and adjusts last two elements of array; the same pattern can be extended to check each index of array, to properly adjust one or more of the indexes to "000" and increment the previous index by 1.
let message1 = "12345612345678901234567890";
let message2 = "12345612345678901234567999";
let message3 = "12345612345678901234999999";
function addNumberToString(str, numToAdd, digits = []) {
const [N, len, max] = [3, str.length, 1000];
for (let i = -N, l = len; digits.length < len / N; i -= N, l -= N) {
digits.unshift(str.slice(i, l));
}
function add(m) {
if (+digits[digits.length - m] + numToAdd < max) {
let n = +digits[digits.length - m];
digits[digits.length - m] = String(Number(n + numToAdd));
} else {
const M = m + 1;
if (+digits[digits.length - M] + numToAdd < max) {
let n = +digits[digits.length - M];
digits[digits.length - M] = String(Number(n + numToAdd));
digits[digits.length - (M - 1)] = "0".repeat(N);
} else {
if (digits[digits.length - (m + 1)]) {
digits[digits.length - (M - 1)] = "0".repeat(N);
add(m + 1);
}
}
}
return digits.join("")
}
return add(1);
}
console.log(
addNumberToString(message1, 1)
, addNumberToString(message2, 1)
, addNumberToString(message3, 1)
);
I have input field for ZIP, when user fill out field I want create two variables with first ground value.
example:
User type: 01250,
I need two variables with values 01000 and 02000
var zip = $('.js-zip-input').val();
var inputZip = zip % 1000;
var zipMax = zip - inputZip + 1000;
var zipMin = zip - inputZip;
This working for values when first char isn't 0
It's 'not working' because these are numbers, and it doesn't make sense to have a number 01000. This is really just 1000. If you really need to have the zero, you will have to turn your values into strings and add 0 to the beginning of them.
Is this what you wanted?
var zip = 1250;
var range = 1000;
var zipMin = Math.floor(zip/range) * range;
var zipMax = zipMin + range;
The code above gets the floor value of the zip input.
You can set up the range value as the difference of both outputs: in your case 1000 to 2000 would have a range of 1000. Give it a try.
As gavin pointed out, you cant have a leading 0 before the output unless you convert them to string. In this case, you can check for the length of the output (as strings) and add leading zeroes.
var outputLength = 5;
var zipMinOutput = "0".repeat(outputLength - zipMin.toString().length) + zipMin;
var zipMaxOutput = "0".repeat(outputLength - zipMax.toString().length) + zipMax;
The above code adds trailing zeroes for every missing character in the string.
(function(){
var zip = '00000140050';
var zeros = leading_zero(zip.toString().split('').map(Number)); //Number of zeros can be appended to min max values
alert(zeros);
var inputZip = zip % 1000;
var zipMax = zip - inputZip + 1000;
var zipMin = zip - inputZip;
alert(zipMax + ', ' + zipMin);
function leading_zero(x)
{
var n = 0;
for (var i = 0; i < x.length; i ++) {
if (x[i] == 0) n++;
else
break;
}
return n;
}
}());
The story behind
I am creating a voice controlled application using x-webkit-speech which is surprisingly good (the feature, not my app), but sometimes the user (me) mumbles a bit. It would be nice to accept the command if some reasonable part of the word matches some reasonable part of some reasonable command. So I search for the holy grail called Algorithm of the Greatest Intersect of Word in Set of Words. Could some fresh bright mind drive me out of the cave of despair?
Example
"rotation" in ["notable","tattoo","onclick","statistically"]
should match tattoo because it has the longest intersect with rotation (tat_o). statistically is the second best (tati intersect), because longer part of the word needs to be ignored (but this is bonus condition, it would be acceptable without it).
Notes
I use Czech language where the pronunciation is very close to its written form
javascript is the preffered language, but any pseudocode is acceptable
the minimal length of the intersect should be a parameter of the algorithm
What have I tried?
Well, it is pretty embarassing....
for(var i=10; i>=4; --i) // reasonable substring
for(var word in words) // for all words in the set
for(var j=0; j<word.length-i; ++j) // search for any i substring
// aaargh... three levels of abstraction is too much for me
This is an algorithm that seems to work. I have no idea how good it performs compared to other already established algorithms (I suspect it perform worse) but maybe it gives you an idea how you could do it:
FIDDLE
var minInt = 3;
var arr = ["notable","tattoo","onclick","statistically"];
var word = "rotation";
var res = [];
if (word.length >= minInt) {
for (var i = 0; i < arr.length; i++) {
var comp = arr[i];
var m = 0;
if (comp.length >= minInt) {
for (var l = 0; l < comp.length - minInt + word.length - minInt + 1; l++) {
var subcomp = l > word.length - minInt ? comp.substring(l - word.length + minInt) : comp;
var subword = l < word.length - minInt ? word.substring(word.length - minInt - l) : word;
var minL = Math.min(subcomp.length, subword.length);
var matches = 0;
for (var k = 0; k < minL; k++) {
if (subcomp[k] === subword[k]) {
matches++;
}
}
if (matches > m) {
m = matches;
}
}
}
res[i] = m >= minInt ? m : null;
}
}
console.log(res);
What happens is, that it compares the two strings by "moving" on against the other and calculates the matching letters in each position. Here you see the compared "sub"words for rotation vs. notable:
ion / notable --> one match on index 1
tion / notable --> no match
ation / notable --> no match
tation / notable --> one match on index 2
otation / notable --> no match
rotation / notable --> three matches on index 1,2,3
rotation / otable --> no match
rotation / table --> no match
rotation / able --> no match
rotation / ble --> no match
As you see, the maximum number of matches is 3 and that is what it would return.
Here's an implementation of a Levenshtein Distance Calculator in Javascript.
It returns an object containing the matching command and distance.
var commandArr = ["cat", "dog", "fish", "copy", "delete"]
var testCommand = "bopy";
function closestMatch(str, arr)
{
//console.log("match called");
var matchDist = [];
var min, pos;
for(var i=0; i<arr.length; i++)
{
matchDist[i]=calcLevDist(str, arr[i]);
console.log("Testing "+ str + " against " + arr[i]);
}
//http://stackoverflow.com/questions/5442109/how-to-get-the-min-elements-inside-an-array-in-javascript
min = Math.min.apply(null,matchDist);
pos = matchDist.indexOf(min);
var output = { match : arr[pos],
distance : matchDist[pos]
};
return output;
}
function calcLevDist (str1, str2)
{
//console.log("calc running");
var cost = 0 , len1, len2;
var x = 1;
while(x > 0)
{
len1 = str1.length;
console.log("Length of String 1 = " + len1);
len2 = str2.length;
console.log("Length of String 2 = " + len2);
if(len1 == 0)
{
cost+= len2;
return cost;
}
if(len2 == 0)
{
cost+= len1;
return cost;
}
x = Math.min(len1,len2);
if(str1.charAt(len1 -1) != str2.charAt(len2 -1))
{
cost++;
}
else
console.log(str1.charAt(len1-1) + " matches " + str2.charAt(len2-1));
str1 = str1.substring(0, len1 -1 );
str2 = str2.substring(0, len2 -1 );
console.log("Current Cost = " + cost);
}
}
var matchObj = closestMatch(testCommand, commandArr);
var match = matchObj["match"];
var dist = matchObj["distance"];
$("#result").html("Closest match to " + testCommand + " = " + match + " with a Lev Distance of " + dist + "." )
You can mess around with the fiddle here.
Thank you basilikum and JasonNichols and also Mike and Andrew for the comments, it really helped me to finish the algorithm. I come up with my own brute force O(n^3) solution in case someone runs into this question with the same problem.
Anyone is invited to play with the fiddle to improve it.
The algorithm
/**
* Fuzzy match for word in array of strings with given accurancy
* #param string needle word to search
* #param int accurancy minimum matching characters
* #param array haystack array of strings to examine
* #return string matching word or undefined if none is found
*/
function fuzzyMatch(needle,accurancy,haystack) {
function strcmpshift(a,b,shift) {
var match=0, len=Math.min(a.length,b.length);
for(var i in a) if(a[i]==b[+i+shift]) ++match;
return match;
}
function strcmp(a,b) {
for(var i=0,max=0,now; i<b.length; ++i) {
now = strcmpshift(a,b,i);
if(now>max) max = now;
}
return max;
}
var word,best=accurancy-1,step,item;
for(var i in haystack) {
item = haystack[i];
step = Math.max(strcmp(item,needle),strcmp(needle,item));
if(step<=best) continue;
best=step, word=item;
};
return word;
}
Example
var word = "rotation";
var commands = ["notable","tattoo","onclick","statistically"];
// find the closest command with at least 3 matching characters
var command = fuzzyMatch(word,3,commands);
alert(command); // tattoo