Looping through a string of numbers in Javascript - javascript

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

Related

Remove consecutive characters from string until it doesn't have any consecutive characters

If you see two consecutive characters that are the same, you pop them from left to right, until you cannot pop any more characters. Return the resulting string.
let str = "abba"
"abba" - pop the two b's -> "aa"
"aa" - pop the two a's -> ""
return ""
Here's what i have tried so far:
function match(str){
for (let i = 0; i< str.length; i++){
if (str[i] === str[i+1]){
return str.replace(str[i], "");
}
}
};
match('abba');
But it replaces one character only.The problem is if any two consecutive characters matches it needs to remove both of those and console (Like 'abba' to 'aa'). Then it needs to go over the updated string to do the same thing again (Like 'aa' to '')and console until the return string can't be changed anymore.
Here's another solution i found:
function removeAdjacentDuplicates(str) {
let newStr = '';
for (let i = 0; i < str.length; i++) {
if (str[i] !== str[i + 1])
if (str[i - 1] !== str[i])
newStr += str[i];
}
return newStr;
};
removeAdjacentDuplicates('abba');
But this iterates one time only. I need this to go on until there's no more consecutive characters. Also It would be great if good time complexity is maintained.
You can use a while loop to continuously loop until the result is equal to the previous result.
function removeAdjacentDuplicates(str) {
let newStr = '';
for (let i = 0; i < str.length; i++) {
if (str[i] !== str[i + 1])
if (str[i - 1] !== str[i])
newStr += str[i];
}
return newStr;
};
let before = 'abba';
let result = removeAdjacentDuplicates(before);
while(result != before){
before = result;
result = removeAdjacentDuplicates(before);
}
console.log(result);
If you want to add a limit to the number of pops, you can store the maximum pops in a variable and the number of pops in another (incremented in the loop), then add an expression to the while loop that instructs it not to execute when the number of pops is no longer smaller than the maximum number of pops permitted.
E.g:
function removeAdjacentDuplicates(str) {
let newStr = '';
for (let i = 0; i < str.length; i++) {
if (str[i] !== str[i + 1])
if (str[i - 1] !== str[i])
newStr += str[i];
}
return newStr;
};
let before = 'cabbac';
let result = removeAdjacentDuplicates(before);
const maxPop = 2;
var pops = 1; //It's 1 because we already removed the duplicates once on line 11
while (result != before && pops < maxPop) {
before = result;
result = removeAdjacentDuplicates(before);
pops++;
}
console.log(result);
You can use a regular expression to match consecutive characters and keep replacing until the string is unchanged.
function f(s) {
while (s != (s = s.replace(/(.)\1+/g, '')));
return s;
}
console.log(f("abba"))

JavaScript bug: function returns NaN even though typeof function returns "number"

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>

Javascript - How to sum up all the first and last digit of a number until only two digits are left?

I am fairly new to programming, just knowing the basics in Javascript and Swift. I am trying to write a simple program which creates, from any entered number, a two digit number by summing up the first and last digit until only two digits are finally left.
Here is an example:
num = 1234567:
1+7 = 8
2+6 = 8
3+5 = 8
4 remains
So the first result is: 8884. Now everything is added again:
8+8 = 16
8+4 = 12
The result is 1612. Again everything is summed up:
1+2 = 3
6+1 = 7
The result is 37 - which is also the final result.
I am struggling with two things. First the while loop. I was thinking about casting num.toString() and then do a while loop like this in which I change the string to an int again:
num.toString()
while (num.length > 2) {
num = num.parseInt(num, 10);
...
}
But this doesn't work properly, plus it gets crazy complicated I guess because I would have to switch between string and int each new round, right?
I know how to add all digits together until I get a two digit number (it took me a while to figure this one out) and I am not even sure if this is a good way to do it:
var sum = num
.toString()
.split('')
.map(Number)
.reduce(function (a, b) {
return a + b;
}, 0);
But obviously I cannot use this here and I have no idea how to change the code so that the first and last digit are added together.
Slightly different approach:
function sum(num) {
var numString = num.toString();
var newString = "";
while (numString.length > 1) { // (1)
newString += (parseInt(numString[0]) + parseInt(numString[numString.length - 1])).toString(); // (2)
numString = numString.substring(1, numString.length - 1); // (3)
}
newString += numString; // (4)
if (newString.length > 2) { // (5)
console.log(newString)
return sum(newString);
} else {
return newString;
}
}
console.log(sum(1234567));
Outputs:
8884
1216
73
Brief explanation of what's going on:
(1) Your while loop will process the string until there's either 1 or
0 characters left
(2) Add the sum of your first and last character to
your newString
(3) Remove the first and last characters from your
numString now that they've been saved to the newString. Because
you're overwriting the value in numString and shrinking it, this
will eventually satisfy the while condition of a numString with
less than 2 characters
(4) Add the remaining characters to
newString, which will either be 1 or 0 characters depending on the
length of the original number
(5) if your newString is more than 2
characters, run this method again. Otherwise return your result
Try this buddy. Its just using simple for loop. Its loops upto half of number and add corresponding. The final result according to ur logic should be 73 not 37
function sum(num){
//if num is greater than or equal to 2 end the function and return final value
if(num.length <= 2) return num;
//converting the num to string beacuse first time input will be number
num = String(num);
let result = '';
//creating a loop upto half of length of the num
for(let i = 0;i<num.length/2;i++){
//if the number is not middle one
if(i !== num.length - 1 - i)
{
//adding the sum of corresponding numbers to result
result += parseInt(num[i]) + parseInt(num[num.length - 1 - i]);
}
//if the number is middle number just add it to result
else result += num[i]
}
return sum(result);
}
console.log(sum(1234567))
You could take a nested while loop and check the string length for the outer loop and the left and right indices for the inner loop
function add(n) {
var s = n.toString(),
l, r,
sum;
while (s.length > 2) {
l = 0;
r = s.length - 1;
sum = [];
while (l < r) {
sum.push(+s[l++] + +s[r--]);
}
if (l === r) sum.push(s[l]);
s = sum.join('');
}
return +s;
}
console.log(add(1234567));
The same but with a recursive function.
function add(n) {
var s = n.toString(),
l = 0, r = s.length - 1,
sum = [];
if (s.length <= 2) return n;
while (l < r) sum.push(+s[l++] + +s[r--]);
if (l === r) sum.push(s[l]);
return add(+sum.join(''));
}
console.log(add(1234567));

number to be printed in a format using javascript

I am using java script to print a 10 digit number. example 1234567891. But i want that number to be printed in a particular format link 123.456.789-1. Can somebody please help me to sort this.
Very simple way to do it:
var num = "1234567891";
var formattedNum = formatNum(num);
console.log(formattedNum); //returns 123.456.789-1
function formatNum(num) {
var arr = num.split('');
var output = '';
for (var i = 0; i < arr.length; i++) {
output += arr[i];
if (i === 2 || i === 5) output += '.';
if (i === 8) output += '-';
}
return output;
}
First, convert to a string with leading zeroes,
then insert the punctuation as you desire.
function formatnum(n) {
n = ("0000000000" + n).substr(-10); // take the last 10 digits of the padded string
return ( n.substr(0,3) + "." + n.substr(3,3) + "." + n.substr(6,3) + "-" + n.substr(9,1) );
}

Insert dashes into a number

Any ideas on the following? I want to input a number into a function and insert dashes "-" between the odd digits. So 4567897 would become "456789-7". What I have so far is to convert the number into a string and then an array, then look for two odd numbers in a row and use the .splice() method to add the dashes where appropriate. It does not work and I figure I may not be on the right track anyway, and that there has to be a simpler solution.
function DashInsert(num) {
var numArr = num.toString().split('');
for (var i = 0; i < numArr.length; i++){
if (numArr[i]%2 != 0){
if (numArr[i+1]%2 != 0) {
numArr.splice(i, 0, "-");
}
}
}
return numArr;
}
The problem is you're changing the thing you're iterating over. If instead you maintain a separate output and input...
function insertDashes(num) {
var inStr = String(num);
var outStr = inStr[0], ii;
for (ii = 1; ii < inStr.length; ii++) {
if (inStr[ii-1] % 2 !== 0 && inStr[ii] % 2 !== 0) {
outStr += '-';
}
outStr += inStr[ii];
}
return outStr;
}
You can try using regular expressions
'4567897'.replace(/([13579])(?=[13579])/g, '$1-')
Regex Explained
So, we find an odd number (([13579]) is a capturing group meaning we can use it as a reference in the replacement $1) ensure that it is followed by another odd number in the non-capturing positive lookahead ((?=[13579])) and replace the matched odd number adding the - prefix
Here is the function to do it:
function dashes(number){
var numString = '';
var numArr = number.toString().split('');
console.log(numArr);
for(i = 0; i < numArr.length; i++){
if(numArr[i] % 2 === 1 && numArr[i+1] % 2 === 1){
numString += numArr[i] + '-';
}else{
numString += numArr[i];
}
}
console.log(numString);
}
dashes(456379);
Tested and everything.
Edit: OrangeDog's answer was posted earlier (by nearly a full half hour), I just wanted to make an answer which uses your code since you're almost there.
Using another array instead of splicing into one you were looping through (this happens to return a string using join):
var num = 4567897;
function DashInsert(num) {
var numArr = num.toString().split('');
var len = numArr.length;
var final = [];
for (var i = 0; i < len; i++){
final.push(numArr[i]);
if (numArr[i]%2 != 0){
if (i+1 < len && numArr[i+1]%2 != 0) {
final.push("-")
}
}
}
return final.join("");
}
alert(DashInsert(num));
function dashInsert(str) {
var arrayNumbers = str.split("");
var newString = "";
for (var i = 0; i < arrayNumbers.length; i++){
if(arrayNumbers[i] % 2 === 1 && arrayNumbers[i + 1] % 2 === 1){
newString = newString + arrayNumbers[i] + "-";
} else {
newString = newString + arrayNumbers[i];
}
}
return newString;
}
var result = dashInsert("3453246");
console.log(result);

Categories

Resources