Reputation: 11
I am trying to solve the GeeksForGeeks problem Concatenation of Zig-Zag String in n Rows:
Given a string and number of rows ‘n’. Print the string formed by concatenating n rows when the input string is written in row-wise Zig-Zag fashion.
Example 1:
Input:
str = "ABCDEFGH" n = 2
Output:
"ACEGBDFH"
Explanation:
Let us write input string in Zig-Zag fashion in 2 rows.
A C E G B D F H
Now concatenate the two rows and ignore spaces in every row. We get
"ACEGBDFH"
My code outputs the correct answer, except that it is not output all on one line, and it prints undefined
after every test case I have tried.
I can't figure out what I did to get this answer or how to get the results to print one line.
function StringChallenge(strArr) {
let str = strArr[0];
let n = strArr[1];
if (n == 1) {
console.log(str);
return;
}
let str1 = str.split("");
let len = str.length;
let arr = new Array(n);
for (let i = 0; i < n; i++) {
arr[i] = "";
}
let row = 0;
let down = true;
for (let i = 0; i < len; i++) {
arr[row] += (str1[i]);
if (row == n - 1) {
down = false;
} else if (row == 0){
down = true;
}
if (down) {
row++
} else {
row--;
}
}
for (let i = 0; i < n; ++i) {
console.log(arr[i]);
}
}
let strArr = ["geeksforgeeks", 3]; // test 1. should print gsgsekfrekeoe
//let strArr = ["cat", 5];// test 2. should print cat
console.log(StringChallenge(strArr));
Upvotes: 1
Views: 195
Reputation: 350760
The problem is that:
your function outputs to console and does not return anything (so undefined
). By returning undefined, the main code prints undefined
. Instead the function should return the result, and leave the printing for the main program to take care of.
your function outputs multiple strings in a final for
loop. Instead it should concatenate those strings into one string.
So replace this:
for (let i = 0; i < n; ++i) {
console.log(arr[i]);
}
with this:
return arr.join("");
And replace this:
if (n == 1) {
console.log(str);
return;
}
with:
if (n == 1) {
return str;
}
NB: GeeksForGeeks gives a JavaScript solution that does print in the function and it looks like your code is derived from this solution -- this printing in a function is not good practice. Even worse is that the GeeksForGeeks version uses document.write
.
This statement is not necessary:
let str1 = str.split("");
You can just omit it, as the rest of the code only assumes that str1
has indexes, not that it is an array.
The loop for initialising the array with ""
can be replaced with a call to fill
:
const arr = Array(n).fill("");
The calculation of row
with the help of down
and some if
conditions, can be replaced by using modular arithmetic:
const row = Math.min(i % cycle, (cycle - i % cycle) % cycle);
It is a bit odd that the function only takes one argument for essentially two pieces of information. If this really is how it is supposed to work, then you can use destructuring in the function heading:
function stringChallenge([str, n]) {
Taking all this together, you get this solution:
function stringChallenge([str, n]) {
if (n == 1) return str;
const arr = Array(n).fill("");
const cycle = 2 * (n - 1);
for (let i = 0; i < str.length; i++) {
const row = Math.min(i % cycle, (cycle - i % cycle) % cycle);
arr[row] += str[i];
}
return arr.join("");
}
const tests = [
["geeksforgeeks", 3], // gsgsekfrekeoe
["cat", 5] // cat
];
for (const test of tests) {
console.log(stringChallenge(test));
}
Upvotes: 2