I want to find the largest number resulted from the permutations of a given number.
If the given number is 123, the largest number resulted from the permutations of it is 321.
EDIT
I have done some progress by changing
if (str.length === 0) return "";
if (str.length === 1) return str;
to
if (str.length === 0) {
return "";
} else {
return str;
}
A problem remains, however: the function returns a string. In fact, the array members are strings instead of numbers.
function findPerms(num) {
var str = num.toString();
if (str.length === 0) {
return "";
} else {
return str;
}
let result = [];
for (let i = 0; i < str.length; i++) {
const currentChar = str[i];
const remainingChars = str.slice(0, i) + str.slice(i + 1);
for (let j = 0; j < remainingChars.length; j++) {
result.push(Number(currentChar + findPerms(remainingChars)[j]));
}
}
result.sort(function(a, b) {
return a - b;
});
return result[result.length - 1];
}
console.log(findPerms(11121));
console.log(typeof findPerms(11121));
For this purpose I did:
function findPerms(num) {
var str = num.toString();
if (str.length === 0) return "";
if (str.length === 1) return str;
let result = [];
for (let i = 0; i < str.length; i++) {
const currentChar = str[i];
const remainingChars = str.slice(0, i) + str.slice(i + 1);
for (let j = 0; j < remainingChars.length; j++) {
result.push(Number(currentChar + findPerms(remainingChars)[j]));
}
}
result.sort(function(a, b) {
return a - b;
});
return result[result.length - 1];
}
console.log(findPerms(11121));
console.log(typeof findPerms(11121));
The problem
I must have made a mistake I was unable to spot because the function above returns NaN (even though typeof findPerms(11121) returns "number").
Where is my mistake?
There are a couple of issues with your code, but let's try to define the requirements correctly first.
If I understand what you want to do is to find all permutations of a number and select the highest possible permutation of the digits in the number.
What you are trying to do is something like this:
Create an empty list
Loop through the digits of the initial number.
For each digit loop trough the remaining digits and find all possible combinations left and add them to the initial empty list.
After you have all possible combinations of numbers in the list sort them and return the highest result.
There are 2 problems here, first there are some mistakes in the execution of the code and your algorithm is not very efficient.
Let's tackle the first one:
When you create the result list you define it inside the recursive function, this means that it will be overwritten with an empty array on each recursive call. Usually when you apply this technique you either define the result array outside of the recursive function or you pass it as a argument in order to be able to iterate over the result.
You seem to not have a good grasp of how function scope and how closures work in JS. I would advise reading some resources on MDN for this.
Another problem here is that you expect the function to receive a number as argument, but when you call it in
result.push(Number(currentChar + findPerms(remainingChars)
remainingChars is a string, hence the NaN result.
Now on to the second problem. Considering that you want the highest possible number from a series of digits you could just sort the digits from highest to smallest and just provide the result.
EG:
If the number is 18, you can sort it in array like [8, 1] and then concatenate it to 81.
The code would probably look smth like:
function findHighestPerm(no) {
const arr = no.toString().split('');
return parseInt(arr.sort((a, b) => b - a).join(''));
}
PS: I am aware that my code is not the most efficient or elegant, but I am just lazy and it works ;)
Edit
I think this is what you would like to do.
Make an array of all digit permutations of a number using recursion.
Sort the array.
Return the permutation with the largest number.
This can be done by breaking the problem it into two functions.
The first function returns an array of all permutations of a number.
The second function takes an array result from the first function then sorts it. Then it returns the last value.
Your recursion was not operating properly. That is why it didn't work.
<html><head><title>6770990</title>
<script>
function findPerms(num) {
var str = num.toString(); var result = [];
if (str.length == 0) return result;
if (str.length == 1) return [parseInt(str)];
for (var i = 0; i < str.length; i++) {
const currentChar = str[i];
const remainingChars = str.slice(0, i) + str.slice(i + 1)
var perms = findPerms(remainingChars) //----Permutation array of remaining chars.
for (var j = 0; j < perms.length; j++) {
result.push(parseInt("" + currentChar + perms[j]));
}
}
return result; //----All permutations for num.
}
function findLargestPerm(num)
{ var perms = findPerms(num); perms.sort(function(a,b) {return a-b;});
return perms[perms.length-1];
}
</script>
</head></body>
<script>
var r = findLargestPerm(11121); alert("r=" + r);
</script>
</body></html>
Previous answer
It would be more efficient to just sort the digits in reverse order and concatenate into a number. This would be the largest permutation.
The function findPerms() is trying to find the largest permutation of a set of digits. Sometimes it helps to rename a function to what it does, so that it is easier to follow the logic.
The line that calls the function using recursion again only needs to be called once for each current character.
The following code shows the steps that happen.
<html><head><title>6770990</title>
<script>
var msg="";
function findLargestPermutation(num)
{ var str = num.toString(); msg += "findLargestPermutation(" + str + ")<br>";
if (str.length === 0) return "";
if (str.length === 1) return str;
let result = [];
for (let i = 0; i < str.length; i++)
{ const currentChar = str[i];
const remainingChars = str.slice(0, i) + str.slice(i + 1);
msg += "currentChar=" + currentChar + " remainingChars=" + remainingChars + "<br>";
//----The j loop should be removed and just use this line.
var num = Number(currentChar + findLargestPermutation(remainingChars));
msg += "num=" + num + "<br>";
result.push(num);
}
result.sort(function(a, b) {return a - b;});
msg += "findLargestPermutation()=" + result[result.length - 1] + "<br>";
return result[result.length - 1];
}
</script>
</head><body>
<div id="div"></div>
<script>
var lp = findLargestPermutation(11121);
alert("lp=" + lp + " typeof lp=" + typeof lp);
document.getElementById("div").innerHTML = msg;
</script>
</body></html>
I have a < p > with 123456789 value
I need to convert my < p > value into 123.456.789 number. What's the easiest way to do this in js?
Try it using regex. The match() function creates an array and join('.') will join the array elements to the required output.
str = "123456789";
str = str.match(/.{1,3}/g).join('.')
console.log(str)
Try Using this function.
Useful for any number and for any delimeter you pass through.
function formatNumber(n, d) // n = number, d = delimeter
{
// round to 2 decimals if cents present
n = (Math.round(n * 100) / 100).toString().split('.');
var
myNum = n[0].toString(),
fmat = new Array(),
len = myNum.length,
i = 1, deci = (d == '.') ? '' : '.';
for (i; i < len + 1; i++)
fmat[i] = myNum.charAt(i - 1);
fmat = fmat.reverse();
for (i = 1; i < len; i++)
{
if (i % 3 == 0) {
fmat[i] += d;
}
}
var val = fmat.reverse().join('') +
(n[1] == null ? deci + '':
(deci + n[1])
);
return val;
}
var res = formatNumber(123456789,'.');
console.log(res);
You can use .match() with RegExp /\d{3}(?=\d{6}|\d{3}|$)/g to match three digits followed by six digits, three digits or end of string, chain .join() to array returned by .match() with parameter "."
var str = "123456789";
var res = str.match(/\d{3}(?=\d{6}|\d{3}|$)/g).join(".");
console.log(res);
Regex combined with html will be enough to get it to work beautifully:
$(".telephone").html(function () {;
return $(this).html().match(/[0-9]{3}/g).join('.');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="telephone">123456789</p>
I has use some jquery code, pls try this! hope this can help you! :)
$('.number').text(function () {
var txt = $(this).text();
return txt.replace(/\B(?=(?:\d{3})+(?!\d))/g, '.');
});
$(document).ready(function(){
$('.number').text(function () {
var txt = $(this).text();
return txt.replace(/\B(?=(?:\d{3})+(?!\d))/g, '.');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="number">123456789</p>
const convert= (str)=>{
let newStr=""
let pointer=0;
while(pointer < str.length){
newStr += str.charAt(pointer)
if(str.charAt(pointer) % 3 === 0 && pointer !== str.length-1){
newStr += "."
}
pointer++
}
console.log(newStr)
}
convert("123456789");
Hey guys working on a problem from CoderBytes. The directions of the following:
Using the JavaScript language, have the function DashInsert(num) insert dashes ('-') between each two odd numbers in num. For example: if num is 454793 the output should be 4547-9-3. Don't count zero as an odd number.
Use the Parameter Testing feature in the box below to test your code with different arguments.
So I didn't create a function but here is my road map.
num = 3333333333
arr = num.toString().split("")
for(var i = 0; i < arr.length; i++){
if(arr[i] % 2 === 1 && arr[i + 1] % 2 === 1){
num.toString().replace(arr[i].toString() + arr[i+1].toString(),
arr[i].toString() + "-" + arr[i+1].toString())
}
}
The thing is when I run this it only puts a dash between the first two threes. I really can't figure out why this is happening. Anyone know where I am going wrong?
Here, this simple solution should do well:
var num = 3434333333
var arr = num.toString().split("");
var finalStr = "";
for(var i = 0; i < arr.length; i++){
if(arr[i] % 2 === 1 && arr[i + 1] % 2 === 1){
finalStr += arr[i] + "-";
}
else {
finalStr += arr[i];
}
}
simply keep a string for the result, if two consecutive numbers are odd append an extra "-" after the number in the string, otherwise simply append the number and your final string will contain the desired result.
See the DEMO here
I have a function to add commas to numbers:
function commafy( num ) {
num.toString().replace( /\B(?=(?:\d{3})+)$/g, "," );
}
Unfortunately, it doesn't like decimals very well. Given the following usage examples, what is the best way to extend my function?
commafy( "123" ) // "123"
commafy( "1234" ) // "1234"
// Don't add commas until 5 integer digits
commafy( "12345" ) // "12,345"
commafy( "1234567" ) // "1,234,567"
commafy( "12345.2" ) // "12,345.2"
commafy( "12345.6789" ) // "12,345.6789"
// Again, nothing until 5
commafy( ".123456" ) // ".123 456"
// Group with spaces (no leading digit)
commafy( "12345.6789012345678" ) // "12,345.678 901 234 567 8"
Presumably the easiest way is to first split on the decimal point (if there is one). Where best to go from there?
Just split into two parts with '.' and format them individually.
function commafy( num ) {
var str = num.toString().split('.');
if (str[0].length >= 5) {
str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
}
if (str[1] && str[1].length >= 5) {
str[1] = str[1].replace(/(\d{3})/g, '$1 ');
}
return str.join('.');
}
Simple as that:
var theNumber = 3500;
theNumber.toLocaleString();
Here are two concise ways I think maybe useful:
Number.prototype.toLocaleString
This method can convert a number to a string with a language-sensitive representation. It allows two parameters, which is locales & options. Those parameters may be a bit confusing, for more detail see that doc from MDN above.
In a word, you could simply use is as below:
console.log(
Number(1234567890.12).toLocaleString()
)
// log -> "1,234,567,890.12"
If you see different with me that because we ignore both two parameters and it will return a string base on your operation system.
Use regex to match a string then replace to a new string.
Why we consider this? The toLocaleString() is a bit confusing and not all browser supported, also toLocaleString() will round the decimal, so we can do it in another way.
// The steps we follow are:
// 1. Converts a number(integer) to a string.
// 2. Reverses the string.
// 3. Replace the reversed string to a new string with the Regex
// 4. Reverses the new string to get what we want.
// This method is use to reverse a string.
function reverseString(str) {
return str.split("").reverse().join("");
}
/**
* #param {string | number}
*/
function groupDigital(num) {
const emptyStr = '';
const group_regex = /\d{3}/g;
// delete extra comma by regex replace.
const trimComma = str => str.replace(/^[,]+|[,]+$/g, emptyStr)
const str = num + emptyStr;
const [integer, decimal] = str.split('.')
const conversed = reverseString(integer);
const grouped = trimComma(reverseString(
conversed.replace(/\d{3}/g, match => `${match},`)
));
return !decimal ? grouped : `${grouped}.${decimal}`;
}
console.log(groupDigital(1234567890.1234)) // 1,234,567,890.1234
console.log(groupDigital(123456)) // 123,456
console.log(groupDigital("12.000000001")) // 12.000000001
Easiest way:
1
var num = 1234567890,
result = num.toLocaleString() ;// result will equal to "1 234 567 890"
2
var num = 1234567.890,
result = num.toLocaleString() + num.toString().slice(num.toString().indexOf('.')) // will equal to 1 234 567.890
3
var num = 1234567.890123,
result = Number(num.toFixed(0)).toLocaleString() + '.' + Number(num.toString().slice(num.toString().indexOf('.')+1)).toLocaleString()
//will equal to 1 234 567.890 123
4
If you want ',' instead of ' ':
var num = 1234567.890123,
result = Number(num.toFixed(0)).toLocaleString().split(/\s/).join(',') + '.' + Number(num.toString().slice(num.toString().indexOf('.')+1)).toLocaleString()
//will equal to 1,234,567.890 123
If not working, set the parameter like: "toLocaleString('ru-RU')"
parameter "en-EN", will split number by the ',' instead of ' '
All function used in my code are native JS functions. You'll find them in GOOGLE or in any JS Tutorial/Book
If you are happy with the integer part (I haven't looked at it closly), then:
function formatDecimal(n) {
n = n.split('.');
return commafy(n[0]) + '.' + n[1];
}
Of course you may want to do some testing of n first to make sure it's ok, but that's the logic of it.
Edit
Ooops! missed the bit about spaces! You can use the same regular exprssion as commafy except with spaces instead of commas, then reverse the result.
Here's a function based on vol7ron's and not using reverse:
function formatNum(n) {
var n = ('' + n).split('.');
var num = n[0];
var dec = n[1];
var r, s, t;
if (num.length > 3) {
s = num.length % 3;
if (s) {
t = num.substring(0,s);
num = t + num.substring(s).replace(/(\d{3})/g, ",$1");
} else {
num = num.substring(s).replace(/(\d{3})/g, ",$1").substring(1);
}
}
if (dec && dec.length > 3) {
dec = dec.replace(/(\d{3})/g, "$1 ");
}
return num + (dec? '.' + dec : '');
}
I have extended #RobG's answer a bit more and made a sample jsfiddle
function formatNum(n, prec, currSign) {
if(prec==null) prec=2;
var n = ('' + parseFloat(n).toFixed(prec).toString()).split('.');
var num = n[0];
var dec = n[1];
var r, s, t;
if (num.length > 3) {
s = num.length % 3;
if (s) {
t = num.substring(0,s);
num = t + num.substring(s).replace(/(\d{3})/g, ",$1");
} else {
num = num.substring(s).replace(/(\d{3})/g, ",$1").substring(1);
}
}
return (currSign == null ? "": currSign +" ") + num + (dec? '.' + dec : '');
}
alert(formatNum(123545.3434));
alert(formatNum(123545.3434,2));
alert(formatNum(123545.3434,2,'€'));
and extended same way the #Ghostoy's answer
function commafy( num, prec, currSign ) {
if(prec==null) prec=2;
var str = parseFloat(num).toFixed(prec).toString().split('.');
if (str[0].length >= 5) {
str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
}
if (str[1] && str[1].length >= 5) {
str[1] = str[1].replace(/(\d{3})/g, '$1 ');
}
return (currSign == null ? "": currSign +" ") + str.join('.');
}
alert(commafy(123545.3434));
Here you go edited after reading your comments.
function commafy( arg ) {
arg += ''; // stringify
var num = arg.split('.'); // incase decimals
if (typeof num[0] !== 'undefined'){
var int = num[0]; // integer part
if (int.length > 4){
int = int.split('').reverse().join(''); // reverse
int = int.replace(/(\d{3})/g, "$1,"); // add commas
int = int.split('').reverse().join(''); // unreverse
}
}
if (typeof num[1] !== 'undefined'){
var dec = num[1]; // float part
if (dec.length > 4){
dec = dec.replace(/(\d{3})/g, "$1 "); // add spaces
}
}
return (typeof num[0] !== 'undefined'?int:'')
+ (typeof num[1] !== 'undefined'?'.'+dec:'');
}
This worked for me:
function commafy(inVal){
var arrWhole = inVal.split(".");
var arrTheNumber = arrWhole[0].split("").reverse();
var newNum = Array();
for(var i=0; i<arrTheNumber.length; i++){
newNum[newNum.length] = ((i%3===2) && (i<arrTheNumber.length-1)) ? "," + arrTheNumber[i]: arrTheNumber[i];
}
var returnNum = newNum.reverse().join("");
if(arrWhole[1]){
returnNum += "." + arrWhole[1];
}
return returnNum;
}
Assuming your usage examples are not representative of already-working code but instead desired behavior, and you are looking for help with the algorithm, I think you are already on the right track with splitting on any decimals.
Once split, apply the existing regex to the left side, a similiar regex adding the spaces instead of commas to the right, and then rejoin the the two into a single string before returning.
Unless, of course, there are other considerations or I have misunderstood your question.
This is basically the same as the solution from Ghostoy, but it fixes an issue where numbers in the thousands are not handled properly. Changed '5' to '4':
export function commafy(num) {
const str = num.toString().split('.');
if (str[0].length >= 4) {
str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
}
if (str[1] && str[1].length >= 4) {
str[1] = str[1].replace(/(\d{3})/g, '$1 ');
}
return str.join('.');
}
//Code in Java
private static String formatNumber(String myNum) {
char[] str = myNum.toCharArray();
int numCommas = str.length / 3;
char[] formattedStr = new char[str.length + numCommas];
for(int i = str.length - 1, j = formattedStr.length - 1, cnt = 0; i >= 0 && j >=0 ;) {
if(cnt != 0 && cnt % 3 == 0 && j > 0) {
formattedStr[j] = ',';
j--;
}
formattedStr[j] = str[i];
i--;
j--;
cnt++;
}
return String.valueOf(formattedStr);
}
You can do it mathematically, depending on how many digits you want to separate, you can start from one digit with 10 to 100 for 2, and so on.
function splitDigits(num) {
num=Math.ceil(num);
let newNum = '';
while (num > 1000){
let remain = num % 1000;
num = Math.floor(num / 1000);
newNum = remain + ',' + newNum;
}
return num + ',' + newNum.slice(0,newNum.length-1);
}
At first you should select the input with querySelector like:
let field = document.querySelector("input");
and then
field.addEventListener("keyup", () => {
for (let i = 1 ; i <= field.value.length; i++) {
field.value = field.value.replace(",", "");
}
let counter=0;
for (let i = 1 ; i <= field.value.length; i++) {
if ( i % ((3 * (counter+1) ) + counter) ===0){
let tempVal =field.value
field.value = addStr(tempVal,field.value.length - i,",")
counter++;
console.log(field.value);
}
}
// field.value = parseInt(field.value.replace(/\D/g, ''), 10);
// var n = parseInt(e.target.value.replace(/\D/g,''),10);
// e.target.value = n.toLocaleString();
});