I am trying to generate a function that generates sequence of numbers and add 0 accordingly to its front. However, it's not outputting the right numbers:
const generatingNumber = (start, end) => {
let result = [];
let output = '';
for(let num = start; num <= end; num++){
if(num.toString().length === 1){
output = '000' + num.toString();
result.push(parseInt(output));
} else if (num.toString().length === 2){
output = '00' + num.toString();
result.push(parseInt(output));
} else if (num.toString() === 3){
output = '0' + num.toString();
result.push(parseInt(output));
}
result.push(num);
}
return result.join('\n');
};
console.log(generatingNumber(1, 3000));
Any idea what am I missing here why its not adding zeros?
Also is there a more succint way to do this?
You can use padStart method.
The padStart() method pads the current string with another string (multiple times, if needed) until the resulting string reaches the given length. The padding is applied from the start of the current string.
const generatingNumber = (start, end) => {
let result = [];
let output = '';
for (let num = start; num <= end; num++) {
result.push(num.toString().padStart(4, 0));
}
return result.join('\n');
};
console.log(generatingNumber(1, 10));
Is this something you want
const generatingNumber = (start, end) => {
let result = [];
let output = '';
for (let num = start; num <= end; num++) {
if (num.toString().length === 1) {
output = '000' + num.toString();
result.push(output);
} else if (num.toString().length === 2) {
output = '00' + num.toString();
result.push(output);
} else if (num.toString().length === 3) {
output = '0' + num.toString();
result.push(output);
} else {
result.push(num);
}
}
return result.join('\n');
};
console.log(generatingNumber(1, 3000));
parseInt('0001') will result in 1. parseInt will remove all the 0's before of actual number because 0001 & 1 is same in integer.
So you have to push only string in result.
parseInt() Removes all the leading zeros from the string before parsing it. You can change
output = '0' + num.toString();
result.push(parseInt(output));
to
output = '0' + num.toString();
result.push(output);
and all other similar states where you push to result array.
It will be storing strings but you cant store numbers with leading zeros.
What you want is not to modify the value, but the presentation of the value instead.
There's no numerical difference between "00000000" and "0"; both are still the value 0. So if your value is converted to a number type, you'll not be able to show those leading zeroes.
This is the line where you're converting the digits to a numeric value
result.push(parseInt(output));
If you want to preserve the leading zeroes in your output, do not convert it to number; keep it as a string.
Also, instead of having those manual ifs depending on the length, take a look at the padStart method. It can "fill" those zeroes at the front for however many digits you want, not just 4.
A generic way of doing that without bounds to specific length or range, using Array.from, map, and padStart:
const generatingNumber = (start, end) => {
const range = end - start + 1;
const maxLen = ('' + end).length;
return Array.from({length: range}).map((_, i) =>
(i + start).toString().padStart(maxLen, '0'));
};
console.log(generatingNumber(5, 3000).join('\n'));
Related
For the given problem below, what would be the time complexity of my solution (below the problem). I think it is not O(n^2), but I am not sure if it is O(n).
Problem: You are given two strings s and t. You can select any substring of string s and rearrange the characters of the selected substring. Determine the minimum length of the substring of s such that string t is a substring of the selected substring.
Signature int minLengthSubstring(String s, String t)
Input s and t are non-empty strings that contain less than 1,000,000 characters each
Output Return the minimum length of the substring of s. If it is not possible, return -1
Example s = "dcbefebce" t = "fd" output = 5
Explanation: Substring "dcbef" can be rearranged to "cfdeb", "cefdb", and so on. String t is a substring of "cfdeb". Thus, the minimum length required is 5.
My code:
function minLengthSubstring(s, t) {
// Write your code here
if(t.length > s.length) return -1;
let letters = new Map();
for(const tc of t) {
letters.set(tc, (letters.get(t) || 0) +1);
}
let min = Infinity;
let start = 0;
let i = 0;
let count = 0;
let map = new Map(letters);
while(i < s.length) {
if(map.has(s[i])) {
if(start === 0 && count === 0) start = i;
count++;
if(map.get(s[i]) === 1) map.delete(s[i])
else map.set(s[i], map.get(s[i]) -1);
if(count === t.length) {
min = Math.min(min, i-start+1);
map = new Map(letters);
count = 0;
start++;
i = start;
}
} else {
i++;
}
}
return min === Infinity ? -1 : min;
}
Thank you.
I have a string where I need to strip out the letters and the numbers. There will only be one number in the string.
So for example this string:
"AM12" I would like to split into this:
['A','M',12]
What is the most efficient way to do this? I was able to do it before with dashes in the string separating them (A-M-12) but was asked to remove the dashes.
Here is code I used for with dashes:
let arrUrl = myString.split('-');
Thanks.
You could use /\d+|./. It will match consecutive numbers or individual characters.
const split = str => str.match(/\d+|./g)
console.log(split("AM12"))
console.log(split("Catch22"))
If you need the number portion to be numeric in your resulting array, you could try something like this
let test = 'AM12'
let res = []
let num = ''
test.split('').forEach(e=>isNaN(e)?res.push(e):num+=e)
res.push(parseInt(num))
console.log(res)
You can scan the input string linearly, char by char, and keep track of any running number, also you should pay attention to the negative numbers.
The following snippet handles negative numbers and also multiple numbers in the same input.
function isDigit(char) {
return char >= "0" && char <= "9";
}
function split(input) {
const result = [];
// keep track of the running number if any
let runningNum = 0;
let isNum = false;
let isNegative = false;
for (let i = 0; i < input.length; i++) {
const ch = input[i];
if (isDigit(ch)) {
// check for negative value
if (i > 0 && input[i - 1] === "-") {
isNegative = true;
}
runningNum *= 10;
runningNum += (isNegative ? -1 : 1) * (ch - "0");
isNum = true;
} else {
// push previous running number if any
if (isNum) {
result.push(runningNum);
runningNum = 0; // reset
isNum = false;
isNegative = false;
}
// if current char is a "-" sign and the following char is a digit continue,
// if not then it's a hyphen
const isLastChar = i === input.length - 1;
if (!isLastChar && input[i] === "-" && isDigit(input[i + 1])) {
continue;
}
result.push(ch);
}
}
// in case the number at the end of the input string
if (isNum) {
result.push(runningNum);
}
return result;
}
const inputs = ["AM-12", "AM-12-30", "AM-12B30", "30", "a3b", "ab", "-", "-abc", "a-12-"];
for (let input of inputs) {
console.log(`"${input}": `, split(input));
}
I'm trying to solve a question to be able to add strings that include floating point numbers. For example "110.75" + "9" = "119.75".
I have the code below that I have been wrestling with for about an hour now and could appreciate if anybody could point me in the right direction as to where I might be wrong. I am only returning an empty string "" for every test case I write for myself.
var addStrings = function(num1, num2) {
const zero = 0;
let s1 = num1.split(".");
let s2 = num2.split(".");
result = "";
let sd1 = s1.length > 1 ? s1[1] : zero;
let sd2 = s2.length > 1 ? s2[1] : zero;
while(sd1.length !== sd2.length) {
if(sd1.length < sd2.length) {
sd1 += zero
} else {
sd2 += zero;
}
}
let carry = addStringHelper(sd1, sd2, result, 0);
result.concat(".");
addStringHelper(s1[0], s2[0], result, carry);
return result.split("").reverse().join("");
};
function addStringHelper(str1, str2, result, carry) {
let i = str1.length - 1;
let j = str2.length - 1;
while(i >= 0 || j >= 0) {
let sum = carry
if(j >= 0) {
sum += str1.charAt(j--) - '0';
}
if(i >= 0 ) {
sum += str2.charAt(i--) - '0';
}
carry = sum / 10;
result.concat(sum % 10);
}
return carry
}
Convert the strings into Number, add them and then convert them back to String.
const addStrings = (num1, num2) => String(Number(num1) + Number(num2))
console.log(addStrings("110.67", "9"))
Also, try to handle floating point rounding in some way. You can try using toFixed (this will fix the result to two decimal places).
const addStrings = (num1, num2) => String((Number(num1) + Number(num2)).toFixed(2))
console.log(addStrings("0.2", "0.1"))
function sumDigits(num) {
newStr = num.toString();
var sum = 0;
for(var i=0; i < newStr.length; i++) {
sum = sum + parseInt(newStr[i]);
}
return sum;
}
var output = sumDigits(1148);
console.log(output); // --> 14
Hey guys, my output is 14. However, my for loop falls apart if num is a negative number. Anyone got any ideas how to get past this? Presently, a negative number returns 'NaN'
I would suggest using a modulus approach here, which avoids the unnecessary cast from integer to string and vice-versa:
function sumDigits(num) {
var sum = 0;
while (num != 0) {
sum += num % 10;
num = num > 0 ? Math.floor(num / 10) : Math.ceil(num / 10);
}
return sum;
}
var output = sumDigits(1148);
console.log("1148 => " + output);
var output = sumDigits(-1148);
console.log("-1148 => " + output);
output = sumDigits(0);
console.log("0 => " + output);
Multiply the result?
function sumDigits(input) {
return Math.abs(input)
.toString()
.split("")
.reduce((sum, num) => sum + Number(num), 0)
* (input < 0 ? -1 : 1);
}
One of the examples.
function sumDigits(num) {
newStr = Math.abs(num).toString();
var sum = 0;
for(var i=0; i < newStr.length; i++) {
sum = sum + parseInt(newStr[i]);
}
return num >= 0 ? sum : -sum ;
}
var output = sumDigits(1148);
console.log(output); // --> 14
var output = sumDigits(-1148);
console.log(output); // --> -14
var output = sumDigits(0);
console.log(output); // --> 0
When you pass a negative number into your sumDigits() function and convert it to a string, the first character becomes the sign (-). So, you should get the absolute value to get rid of the sign. However, if you're expecting a negative value, then you should define a flag that indicates whether the parameter was a negative integer before it got converted, or simply multiply it again by the initial sign. So, you should modify your function like this:
function sumDigits(num) {
const seq = Math.abs(num).toString();
let sum = 0;
for (let i = 0; i < seq.length; i++) {
sum += parseInt(seq[i]);
}
return sum * Math.sign(num);
}
How would I calculate the number of decimal places (not digits) of a real number with Javascript?
function countDecimals(number) {
}
For example, given 245.395, it should return 3.
Like this:
var val = 37.435345;
var countDecimals = function(value) {
let text = value.toString()
// verify if number 0.000005 is represented as "5e-6"
if (text.indexOf('e-') > -1) {
let [base, trail] = text.split('e-');
let deg = parseInt(trail, 10);
return deg;
}
// count decimals for number in representation like "0.123456"
if (Math.floor(value) !== value) {
return value.toString().split(".")[1].length || 0;
}
return 0;
}
countDecimals(val);
The main idea is to convert a number to string and get the index of "."
var x = 13.251256;
var text = x.toString();
var index = text.indexOf(".");
alert(text.length - index - 1);
Here is a method that does not rely on converting anything to string:
function getDecimalPlaces(x,watchdog)
{
x = Math.abs(x);
watchdog = watchdog || 20;
var i = 0;
while (x % 1 > 0 && i < watchdog)
{
i++;
x = x*10;
}
return i;
}
Note that the count will not go beyond watchdog value (defaults to 20).
I tried some of the solutions in this thread but I have decided to build on them as I encountered some limitations. The version below can handle: string, double and whole integer input, it also ignores any insignificant zeros as was required for my application. Therefore 0.010000 would be counted as 2 decimal places. This is limited to 15 decimal places.
function countDecimals(decimal)
{
var num = parseFloat(decimal); // First convert to number to check if whole
if(Number.isInteger(num) === true)
{
return 0;
}
var text = num.toString(); // Convert back to string and check for "1e-8" numbers
if(text.indexOf('e-') > -1)
{
var [base, trail] = text.split('e-');
var deg = parseInt(trail, 10);
return deg;
}
else
{
var index = text.indexOf(".");
return text.length - index - 1; // Otherwise use simple string function to count
}
}
You can use a simple function that splits on the decimal place (if there is one) and counts the digits after that. Since the decimal place can be represented by '.' or ',' (or maybe some other character), you can test for that and use the appropriate one:
function countPlaces(num) {
var sep = String(23.32).match(/\D/)[0];
var b = String(num).split(sep);
return b[1]? b[1].length : 0;
}
console.log(countPlaces(2.343)); // 3
console.log(countPlaces(2.3)); // 1
console.log(countPlaces(343.0)); // 0
console.log(countPlaces(343)); // 0
Based on Gosha_Fighten's solution, for compatibility with integers:
function countPlaces(num) {
var text = num.toString();
var index = text.indexOf(".");
return index == -1 ? 0 : (text.length - index - 1);
}
based on LePatay's solution, also take care of the Scientific notation (ex: 3.7e-7) and with es6 syntax:
function countDecimals(num) {
let text = num.toString()
if (text.indexOf('e-') > -1) {
let [base, trail] = text.split('e-')
let elen = parseInt(trail, 10)
let idx = base.indexOf(".")
return idx == -1 ? 0 + elen : (base.length - idx - 1) + elen
}
let index = text.indexOf(".")
return index == -1 ? 0 : (text.length - index - 1)
}
var value = 888;
var valueLength = value.toString().length;