Print Words Vertically
Problem
You are given a sentence s of uppercase words separated by single spaces (length up to 200). Rewrite it vertically: the i-th output string is built from the i-th character of every word, taken in order. A word that is too short contributes a space at that position so the columns stay aligned.
Interior padding spaces must be kept, but every output string must have its trailing spaces removed.
s = "TO BE OR NOT TO BE"["TBONTB", "OEROOE", " T"]def print_vertically(s):
words = s.split()
max_len = max(len(w) for w in words)
res = []
for c in range(max_len):
col = []
for w in words:
col.append(w[c] if c < len(w) else " ")
res.append("".join(col).rstrip())
return res
function printVertically(s) {
const words = s.split(" ");
const maxLen = Math.max(...words.map(w => w.length));
const res = [];
for (let c = 0; c < maxLen; c++) {
let col = "";
for (const w of words) col += c < w.length ? w[c] : " ";
res.push(col.replace(/ +$/, ""));
}
return res;
}
List<String> printVertically(String s) {
String[] words = s.split(" ");
int maxLen = 0;
for (String w : words) maxLen = Math.max(maxLen, w.length());
List<String> res = new ArrayList<>();
for (int c = 0; c < maxLen; c++) {
StringBuilder col = new StringBuilder();
for (String w : words)
col.append(c < w.length() ? w.charAt(c) : ' ');
int end = col.length();
while (end > 0 && col.charAt(end - 1) == ' ') end--;
res.add(col.substring(0, end));
}
return res;
}
vector<string> printVertically(string s) {
vector<string> words;
stringstream ss(s);
string w;
while (ss >> w) words.push_back(w);
size_t maxLen = 0;
for (auto& x : words) maxLen = max(maxLen, x.size());
vector<string> res;
for (size_t c = 0; c < maxLen; c++) {
string col;
for (auto& x : words)
col += c < x.size() ? x[c] : ' ';
while (!col.empty() && col.back() == ' ') col.pop_back();
res.push_back(col);
}
return res;
}
Explanation
Reading words vertically is just a transpose: if you stack the words as rows of a grid, the i-th output string is the i-th column of that grid. So instead of inventing anything clever, we simulate exactly that — walk column by column and collect one character from each word.
The number of columns is max_len, the length of the longest word, because past that point no word has any character left. For column c we visit every word in order: if the word is long enough we take w[c], otherwise that word has a hole at this position and we emit a space so the characters of later words stay in their correct row.
The only subtlety is which spaces survive. Padding between two real characters is meaningful — removing it would shift a letter into the wrong row — but padding after the last real character of a column carries no information. That is why each column string is right-trimmed (rstrip / strip trailing spaces) before it is appended to the answer.
Walking the default example "TO BE OR NOT TO BE": the six words have max_len = 3. Column 0 reads the first letters T,B,O,N,T,B → "TBONTB"; column 1 reads O,E,R,O,O,E → "OEROOE"; column 2 finds a third letter only in NOT, producing " T ", and trimming the two trailing spaces leaves " T".
Every (word, column) pair is touched exactly once, so the running time is O(words · max_len) — proportional to the area of the padded grid, which is at most a small constant times the length of s. The result strings occupy the same order of space, and apart from them we only keep one column buffer at a time.