54321 4321 321 1 in JavaScript using recursion - javascript

I have a problem about recursive in JavaScript.
This is my code when I use loop, but I want to use recursive.
function triangleNumber(num) {
for(var i = num; i >= 1 ; i--){
var str = ''
for(var j = i; j >= 1; j--){
str += j
}
console.log(str)
}
//DRIVER CODE
console.log(triangleNumber(5));
// 54321
// 4321
// 321
// 21
// 1

Try this solution, where you build the string using the for loop appending numbers till you reach 1. Then you call the function recursively for the next smaller numbern - 1:
function triangleNumber(num) {
if(num <= 0){ //Base case return if number reaches '0'
return;
}
var str = ''
for(var i = num; i >= 1; i--){
str += i; //Create number string by appending successive decreasing value
}
console.log(str);
triangleNumber(num - 1) //Recursively call the function for the next lower number
}
triangleNumber(5);

Pretty straightforward :)
function triangleNumber(num) {
if(num<1) return;
var str = '';
for(var i = num; i >= 1 ; i--) str += i;
console.log(str);
triangleNumber(num-1)
}
triangleNumber(5);

Related

How to print a half pyramid in javascript

The code works but I don't want the inner for loop to take me to the new line.
for (i = 0; i < 5; i++) {
for (j = 1; j <= i; j++) {
console.log('*');
}
console.log();
}
console.log('-----------------');
console.log will automatically break the line. Concatenate to a string instead of a log. Log at the end.
let str = '';
for(i = 0; i <= 5 ; i++) {
for(j = 1; j <= i; j++) {
str += '*';
}
str += '\n';
}
console.log(str);
You can do this way, with the help of a string variable:
for (i = 0; i < 5; i++) {
var str = '';
for (j = 1; j <= i; j++) {
str+='*';
}
console.log(str);
}
console.log('-----------------');
If you want to print at the page, use like below
for (i = 0; i < 5; i++) {
let j=0;
do{document.write("*");j++;}while(j < i)
document.write("<br/>")
}
You need to break the line with the console.log you can also controle the space between * with output+='*' + " ";
function pyramid() {
var total = 5;
var output="";
for (var i = 1; i <= total; i++) {
for (var j = 1; j <= i; j++) {
output+='*' + " ";
}
console.log(output);
output="";
}
}
pyramid()
You can get rid of second for loop as follows:
var str = '';
for (i = 1; i <= 5; i++) {
str +=Array(i).join("*");
str +='\n';
}
console.log(str);
let string = "";
for (let i = 0; i < 5; i++){
string += '*';
console.log(string);
}
Output:
*
**
***
****
*****
A simple way to solve this "exercise" in JavaScript:
let width = ""
while(width.length < 6) console.log(width += `#` );
Basically, we create a string (width) and increment its value using the while loop till we hit a restriction.
I found the more typical method "bulky"(?)...plus there's the issue of not getting the exact picture of a half pyramid.
let i,j
for (i= 0; i < 6; i++){
for (j = 0; j<=i; j++){
console.log("#")
}
console.log("\n")
}
function pyramid(n){
let result = "";
for(let i=0; i<=n; i++){
result += "*".repeat(i);
result += "\n"
}
return result;
}
console.log(pyramid(5));
//OutPut
*
**
***
****
*****
As we need n number of pyramid structure with '' / '#' / any symbol. by using above code we can achieve. Here you can see we just created a function called pyramid with one parameter 'n'. and inside function we declare a variable 'result'. So inside for loop the length of 'i' is "<=n" and also you can use "repeat() method to print '' 'i' times. So if you call that function like console.log(pyramid(5)); You can able to see your Answer as expected..
shortest code:
console.log('*\n**\n***\n****\n*****');

How do you iterate over an array every x spots and replace with letter?

/Write a function called weave that accepts an input string and number. The function should return the string with every xth character replaced with an 'x'./
function weave(word,numSkip) {
let myString = word.split("");
numSkip -= 1;
for(let i = 0; i < myString.length; i++)
{
numSkip += numSkip;
myString[numSkip] = "x";
}
let newString = myString.join();
console.log(newString);
}
weave("weave",2);
I keep getting an infinite loop. I believe the answer I am looking for is "wxaxe".
Here's another solution, incrementing the for loop by the numToSkip parameter.
function weave(word, numToSkip) {
let letters = word.split("");
for (let i=numToSkip - 1; i < letters.length; i = i + numToSkip) {
letters[i] = "x"
}
return letters.join("");
}
Well you need to test each loop to check if it's a skip or not. Something as simple as the following will do:
function weave(word,numSkip) {
var arr = word.split("");
for(var i = 0; i < arr.length; i++)
{
if((i+1) % numSkip == 0) {
arr[i] = "x";
}
}
return arr.join("");
}
Here is a working example
Alternatively, you could use the map function:
function weave(word, numSkip) {
var arr = word.split("");
arr = arr.map(function(letter, index) {
return (index + 1) % numSkip ? letter : 'x';
});
return arr.join("");
}
Here is a working example
Here is a more re-usable function that allows specifying the character used for substitution:
function weave(input, skip, substitute) {
return input.split("").map(function(letter, index) {
return (index + 1) % skip ? letter : substitute;
}).join("");
}
Called like:
var result = weave('weave', 2, 'x');
Here is a working example
You dont need an array, string concatenation will do it, as well as the modulo operator:
function weave(str,x){
var result = "";
for(var i = 0; i < str.length; i++){
result += (i && (i+1)%x === 0)?"x":str[i];
}
return result;
}
With arrays:
const weave = (str,x) => str.split("").map((c,i)=>(i&&!((i+1)%x))?"x":c).join("");
You're getting your word greater in your loop every time, so your loop is infinite.
Try something like this :
for(let k = 1; k <= myString.length; k++)
{
if(k % numSkip == 0){
myString[k-1]='x';
}
}
Looking at what you have, I believe the reason you are getting an error is because the way you update numSkip, it eventually becomes larger than
myString.length. In my code snippet, I make i increment by numSkip which prevents the loop from ever executing when i is greater than myString.length. Please feel free to ask questions, and I will do my best to clarify!
JSFiddle of my solution (view the developer console to see the output.
function weave(word,numSkip) {
let myString = word.split("");
for(let i = numSkip - 1; i < myString.length; i += numSkip)
{
myString[i] = "x";
}
let newString = myString.join();
console.log(newString);
}
weave("weave",2);
Strings are immutable, you need a new string for the result and concat the actual character or the replacement.
function weave(word, numSkip) {
var i, result = '';
for (i = 0; i < word.length; i++) {
result += (i + 1) % numSkip ? word[i] : 'x';
}
return result;
}
console.log(weave("weave", 2));
console.log(weave("abcd efgh ijkl m", 5));
You can do this with fewer lines of code:
function weave(word, numSkip) {
word = word.split("");
for (i = 0; i < word.length; i++) {
word[i] = ((i + 1) % numSkip == 0) ? "x" : word[i];
}
return word.join("");
}
var result = weave("weave", 2);
console.log(result);

transform every 3rd letter to uppercase

how to transform every 3rd character to uppercase. for example this string pifedvcbtauzkwgnxyjrhmq converted into piFedVcbTauKkwGnxYjrHmq.
here is what i've done so far
function up3rdletter(str){
var i, result = '';
for(i = 0; i < str.length; i++){
if(i > 0 && i % 3 == 0){
result += str[i].toUpperCase();
}else{
result += str[i];
}
}
return result;
}
the script above return pifEdvCbtAuzKwgNxyJrhMq, it start converting from 4th letter. if I change the modulo number to 2 it become piFeDvCbTaUzKwGnXyJrHmQ
It's rather trivial: indexing in JS starts from 0, but you want to change letters based on 1-based index, natural for human beings. ) Solution? Either shift the remainder check:
result += i % 3 === 2 ? str[i].toUpperCase() : str[i];
... or go on checking against 0, but advance i instead:
result += (i + 1) % 3 ? str[i] : str[i].toUpperCase();
But actually, I'd probably write it as follows:
result = str.replace(/(..)(.)/g, function(_, m1, m2) {
return m1 + m2.toUpperCase();
});
function up3rdletter(str){
var i, result = '';
var counter = 1;
for(i = 0; i < str.length; i++){
if(i > 0 || counter % 3 == 0){
result += str[i].toUpperCase();
}else{
result += str[i];
}
counter++;
}
return result;
}

Counting occurances of character in strings

I made a function that counts the occurances of x's and o's in a given string and returns true if they are equal.
function ExOh(str) {
var x_count = 0;
var o_count = 0;
for (var i = 0;i < str.length-1;i++){
if (str[i] === 'x'){
x_count = x_count + 1;
}
else if (str[i] === 'o'){
o_count = o_count + 1;
}
}
console.log(o_count);
console.log(x_count);
if (x_count === o_count){
return true;}
else{
return false;
}
}
// keep this function call here
// to see how to enter arguments in JavaScript scroll down
ExOh(readline());
I added the lines of code
console.log(o_count);
console.log(x_count);
To see if it was counting correctly and I discovered that was the issue. After testing it I realized that this function is not testing the last element in the string. I tried changing the length of the for loop, but I can't think of what else could be wrong.
Any advice?
Thanks mates
JavaScript arrays are 0 index based objects. So, your loop should be like this
for (var i = 0; i < str.length; i++) {
otherwise the last element will be skipped.
Consider that the length of the string is 5. So, i starts from 0 and if you had your original condition
for (var i = 0; i < str.length - 1; i++) {
following are the comparisons happening in the loop
0 < 4
1 < 4
2 < 4
3 < 4
4 < 4 -- Fails
So it breaks out of the loop. But the last element will be at index 4. But when you have the condition like this
for (var i = 0; i < str.length; i++) {
the comparisons go like this
0 < 5
1 < 5
2 < 5
3 < 5
4 < 5
5 < 5 -- Fails
It breaks out of the loop only after comparing all the elements.
So, your actual program can be written like this
function ExOh(str) {
var x_count = 0, o_count = 0;
for (var i = 0; i < str.length; i++) {
if (str[i] === 'x') {
x_count = x_count + 1;
} else if (str[i] === 'o') {
o_count = o_count + 1;
}
}
return x_count === o_count;
}
alternate method to count characters:
var s = 'example';
s.split('').filter(function (i) { return i === 'e'; }).length; // 2
Your for loop is running one too short. Try this instead.
for (var i = 0;i < str.length;i++){
if (str[i] === 'x'){
x_count = x_count + 1;
}
else if (str[i] === 'o'){
o_count = o_count + 1;
}
}
Your problem is in for loop. Try changing to this.
for (var i = 0; i < str.length; i++) {
If you want to avoid using for loops, you can use this much shorter version of ExOh function.
function ExOh(str) {
return str.match(/o/g).length == str.match(/x/g).length
}
Rather than looping over the whole String with for, I'd see if using indexOf achieves a faster result
function countOccurance(haystack, needle) {
var total = 0, pos = -1;
while (-1 !== (pos = haystack.indexOf(needle, pos + 1)))
total += 1;
return total;
}
Then
var x_count = countOccurance(str, 'x'),
o_count = countOccurance(str, 'o');
return x_count === o_count;
EDIT looks like I might have been wrong about it being faster! jsperf
function indexOfMethod(haystack, needle) {
var total = 0, pos = -1;
while (-1 !== (pos = haystack.indexOf(needle, pos + 1)))
total += 1;
return total;
}
function splitMethod(haystack, needle) {
return haystack.split(needle).length - 1;
}
function forMethod(haystack, needle) {
var total = 0, i;
for (i = 0; i < haystack.length; ++i)
if (haystack.charAt(i) === needle)
total += 1;
return total;
}
The forMethod will only work with char needle, whereas the other two should work with any String as needle, if that matters.

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