9
\$\begingroup\$

Write the shortest possible program or function that will join a list of columnar strings.

For this challenge, columnar strings are defined as one-character-wide strings spanning across multiple lines. Each character, except for the last one, is separated by a newline character. Some examples, separated by ---:

a
b
c
d
---
h
e
l
l
o
---
c
o
d
e
 
g
o
l
f
---
"
q
u
o
t
e
s
"

Given a list of columnar strings, join them into a single string with multiple columns. If the columnar string is longer than its surroundings, it should be left-padded by spaces.

Notes

  • This is , so shortest code wins!
  • You may assume inputs are ASCII only.
  • You may have trailing newlines.
  • You may have trailing spaces.
  • This is not a transpose challenge; each string in the input list of strings has newlines separating each character. The "multi-line strings vs list of strings as input" default does not apply here; each string in the test cases are separated by --- and include newlines.

Test Cases

Input:
---
a
b
c
d
---
h
e
l
l
o
---
c
o
d
e

g
o
l
f
---
"
q
u
o
t
e
s
"
---
Output: (note how `hello` and `code golf` are left-padded by spaces)
ahc"
beoq
cldu
dleo
 o t
  ge
  os
  l"
  f


Input:
---
h
w
---
e
o
---
l
r
---
l
l
---
o
d
---
Output:
hello
world

Input:
---
p

f
---
b
m
v
---
t

s
---
d
n
z
---
k

x
---
g
N
h
---
Output:
pbtdkg
 m n N
fvszxh

Input:
---
1
---

2
---


3
---



4
---
6



5
---
Output:
1   6
 2
  3
   4
    5

Input:
---
a

c
---
|
---
b
d
---
Output:
a|b
  d
c

Input:
---
Output:
(empty output, or single newline)
\$\endgroup\$
9
  • \$\begingroup\$ Sandbox \$\endgroup\$
    – bigyihsuan
    Dec 1, 2022 at 16:11
  • \$\begingroup\$ Can we output as a list? \$\endgroup\$
    – naffetS
    Dec 1, 2022 at 16:45
  • 1
    \$\begingroup\$ @hakr14 perhaps this part requires clarification from OP: "columnar strings are defined as one-character-wide strings spanning across multiple lines." Does the one-character-wide specification extend to "empty" lines (i.e. use a space) or not (i.e. no space)? \$\endgroup\$ Dec 2, 2022 at 7:35
  • 2
    \$\begingroup\$ @MamaFunRoll cc hakr14 the 1-character-wide extends to empty lines only if they contain a space before the newline, otherwise there can be an empty string before the newline \$\endgroup\$
    – bigyihsuan
    Dec 2, 2022 at 15:00
  • 1
    \$\begingroup\$ @jdt ideally output should be a string, but you can use a list of chars, list of bytes, list of strings, etc \$\endgroup\$
    – bigyihsuan
    Dec 2, 2022 at 19:58

15 Answers 15

10
\$\begingroup\$

Bash + GNU utilities, 39

Input is taken from files; 1 file per column; filenames passed as command-line parameters.

paste $@|expand|sed -r 's/(.) {7}/\1/g'

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Nice. I looked at pr and lam but could not coerce them to work as required. \$\endgroup\$
    – roblogic
    Jan 6 at 3:53
5
\$\begingroup\$

APL (Dyalog Unicode), 8 bytes

Anonymous tacit prefix function, taking list of strings with CR as newline.

⍉∘↑⎕FMT¨

Try it online!

¨ for each string:

⎕FMT ForMaT as character matrix, evaluating control characters for layout

 mix into 3D array (layers: number of strings; rows: hight of longest string; columns: 1)

 then:

 reverse order of axes (layers: 1; rows: hight of longest string; columns: number of strings)


Pre spec-change solution, 2 bytes

⍉↑

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ This is not a transpose challenge; each input string has newlines separating each character. \$\endgroup\$
    – bigyihsuan
    Dec 1, 2022 at 20:56
  • \$\begingroup\$ @bigyihsuan Per default input/output rules, submissions may use list of strings instead of multi-line strings. My function takes multi-line strings as matrices, which are equivalent to lists of strings. \$\endgroup\$
    – Adám
    Dec 1, 2022 at 21:58
  • 1
    \$\begingroup\$ However, that completely disregards the intentions of the challenge: to join multiple, many-lined strings. \$\endgroup\$
    – bigyihsuan
    Dec 1, 2022 at 22:50
  • 1
    \$\begingroup\$ A row can be empty. Check the test cases: there are no spaces \$\endgroup\$
    – hakr14
    Dec 2, 2022 at 6:37
  • \$\begingroup\$ @bigyihsuan OK, the new solution follows the new spec. \$\endgroup\$
    – Adám
    Dec 2, 2022 at 9:28
5
\$\begingroup\$

Vyxal j, 9 bytes

↵¤ðvVðÞṪṅ

Try it Online!

\$\endgroup\$
9
  • \$\begingroup\$ In the TIO link, the inputs look as if they're regular strings, rather than columnar strings (characters separated by newlines...)... \$\endgroup\$ Dec 1, 2022 at 20:05
  • \$\begingroup\$ This is not a transpose challenge; each input string has newlines separating each character. \$\endgroup\$
    – bigyihsuan
    Dec 1, 2022 at 20:55
  • \$\begingroup\$ @bigyihsuan So we can output as a list, but not input as a list? \$\endgroup\$
    – naffetS
    Dec 1, 2022 at 22:29
  • 1
    \$\begingroup\$ @Steffan You can input as a list of strings (that contain newlines). You can input as a list of lists of characters. If your language doesn't support lists, a delimited string is allowed. \$\endgroup\$
    – bigyihsuan
    Dec 1, 2022 at 22:57
  • 1
    \$\begingroup\$ Fails with concurrent or leading newlines \$\endgroup\$
    – hakr14
    Dec 2, 2022 at 6:25
4
\$\begingroup\$

05AB1E, 9 bytes

ε¶¡1ú€θ}ζ

Input as a list of multiline strings; output as a list of list of characters.

Try it online or verify all test cases. (The footer in the single-TIO is to join each inner list of characters; and then each string by newlines. Feel free to remove it to see the actual list output.)

Explanation:

ε       # Map over each multiline string of the (implicit) input-list:
 ¶¡     #  Split it on newlines
   1ú€θ #  Convert empty strings to spaces:
   1ú   #   Pad each inner character with a leading space
     €  #   Map over each inner 1 or 2-char string
      θ #    Only keep its last character
}ζ      # After the map: zip/transpose; swapping rows/columns, using " " as filler
        # character if the lists are of unequal lengths
        # (after which the resulting matrix of characters is output implicitly)
\$\endgroup\$
4
\$\begingroup\$

Japt -R, 1 2 bytes

Note that the spec states that "... columnar strings are defined as one-character-wide strings ...", so any empty lines in the test cases should contain a space character.

Õë

Try it (header allows for input to be formatted as per the test cases) or run all test cases

Õë     :Implicit input of array of multi-line strings
Õ      :Transpose
 ë     :Remove every second element
       :Implicit output joined with newlines
\$\endgroup\$
5
  • \$\begingroup\$ I don't know Japt or the input format, nor what -R or U.y() do, but the input has to be a list of columns, not plain strings. \$\endgroup\$
    – Adám
    Dec 1, 2022 at 19:52
  • \$\begingroup\$ This is not a transpose challenge; each input string has newlines separating each character. \$\endgroup\$
    – bigyihsuan
    Dec 1, 2022 at 20:54
  • 1
    \$\begingroup\$ Fails with concurrent or leading newlines \$\endgroup\$
    – hakr14
    Dec 2, 2022 at 6:24
  • \$\begingroup\$ @hakr14, from the spec "columnar strings are defined as one-character-wide strings". So the empty lines in your example should have a single space character. \$\endgroup\$
    – Shaggy
    Dec 2, 2022 at 9:35
  • \$\begingroup\$ In comments under the question: "the 1-character-wide extends to empty lines only if they contain a space before the newline, otherwise there can be an empty string before the newline" \$\endgroup\$
    – hakr14
    Dec 3, 2022 at 6:12
3
\$\begingroup\$

Charcoal, 6 bytes

FA«Pι→

Try it online! Link is to verbose version of code. Takes input in JSON-like format (but with Python string delimiters). Explanation:

FA«

Loop over all of the input strings.

Pι

Print the string to the canvas without moving the cursor.

Move the cursor one character to the right.

\$\endgroup\$
3
\$\begingroup\$

Octave, 13 61 bytes

+48 bytes in order to properly account for newlines in columnar strings (@hakr14)

@(b)reshape(strrep(b(:,1:2:end)',char(10),' '),[],size(b)(1))

Takes in columnar strings (with newline between characters), used as follows:

f = ans
a = ['a' newline 'b' newline 'c' newline 'd';
'h' newline 'e' newline 'l' newline 'l' newline 'o';
'c' newline 'o' newline 'd' newline 'e' newline newline newline 'g' newline 'o' newline 'l' newline 'f';
'"' newline 'q' newline 'u' newline 'o' newline 't' newline 'e' newline 's' newline '"']
f(a)
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Fairly sure the "space" in "code golf" is meant to be an "empty character", i.e. '', in which case this fails. \$\endgroup\$
    – hakr14
    Dec 2, 2022 at 7:31
3
\$\begingroup\$

Python 3, 123 121 137 128 bytes

def f(l):l=[''.join(c or' 'for c in q.split('\n'))for q in l];[print(*x,sep='')for x in zip(*[s+max(map(len,l))*' 'for s in l])]

Try it online!

+16 bytes because it was failing for concurrent newlines (@hakr14)

Saved 9 bytes by using a trick from 97.100.97.108's answer where it outputs a lot of newlines at the end.

\$\endgroup\$
5
  • \$\begingroup\$ Taking input as regular strings seems to be completely ignoring the description of the challenge: "columnar strings are defined as one-character-wide strings spanning across multiple lines"... \$\endgroup\$ Dec 1, 2022 at 20:09
  • \$\begingroup\$ Your first answer is not what this challenge is asking for. This is not a transpose challenge; each input string has newlines separating each character. \$\endgroup\$
    – bigyihsuan
    Dec 1, 2022 at 21:02
  • \$\begingroup\$ Fails with concurrent or leading newlines \$\endgroup\$
    – hakr14
    Dec 2, 2022 at 6:34
  • \$\begingroup\$ @hakr14 I've changed it but I'm not sure exactly what OP is looking for... Try it online! \$\endgroup\$
    – The Thonnu
    Dec 2, 2022 at 7:28
  • \$\begingroup\$ Looks good to me \$\endgroup\$
    – hakr14
    Dec 2, 2022 at 7:35
2
\$\begingroup\$

Pyth, 25 bytes

j%2.t:R"(?<=\n)\n|^\n"+;b

Try it online!

Could save 2 bytes if re supported alternations in lookbehinds.

Explanation:
j%2.t:R"(?<=\n)\n|^\n"+;b  | Full program
j%2.t:R"(?<=\n)\n|^\n"+;bQ | with implicit varibles
---------------------------+-------------------------------------------------------------------------
      R                  Q | For each string in the input,
     :                     |  Replace
       "(?<=\n)\n|^\n"     |   Each newline preceded by another newline or by the start of the string
                      +;b  |   with " \n"
   .t                      | Ragged transpose
 %2                        | Every other item (removes the newlines)
j                          | Join by newlines
\$\endgroup\$
2
\$\begingroup\$

Python 3.8 (pre-release), 77 95 bytes

+18 bytes in order to properly account for newlines inside of the columnar string (@hakr14)

lambda l:"\n".join(map("".join,zip(*[s[::2].replace("\n"," ")+" "*max(map(len,l))for s in l])))

Try it online!

Takes in lists of columnar strings (characters separated by newlines). Exploits the rule that you can have extra whitespace at the end.

\$\endgroup\$
4
  • \$\begingroup\$ Fail with concurrent or leading newlines \$\endgroup\$
    – hakr14
    Dec 2, 2022 at 6:27
  • \$\begingroup\$ @hakr14 I would assume that's not a valid columnar string? \$\endgroup\$ Dec 2, 2022 at 6:29
  • \$\begingroup\$ The provided test cases would disagree \$\endgroup\$
    – hakr14
    Dec 2, 2022 at 6:31
  • \$\begingroup\$ @hakr14Ql Ah, my bad, I thought there was a space. \$\endgroup\$ Dec 2, 2022 at 6:32
2
\$\begingroup\$

sclin, 51 bytes

"""."fold
over0:"."" "\ /#" ""."zip~
"^$"" "\ /# ++

Try it here! Takes input as a list of lists of single-character strings, and outputs as a list of row-based strings.

For testing purposes (c<> splits each string into a list of single-character strings):

["abcd" "hello" "code golf" "\"quotes\""] c<> ; n>< n>o
"""."fold
over0:"."" "\ /#" ""."zip~
"^$"" "\ /# ++

Explanation

Prettified code:

"""."fold
over0:"."" "\ /#" ""."zip~
"^$"" "\ /# ++
  • "" \; fold starting with the empty string, fold over each column...
    • over 0: "." " "\ /# get string of spaces with length of row built thus far as x
    • " " ; zip~ zip with the following (placeholding x for empty accumulator elements and a single space for empty subsequent elements)...
      • "^$"" "\ /# replace empty string with space
      • ++ concatenate
\$\endgroup\$
2
  • \$\begingroup\$ Fails if a "character" is empty, which would represent an empty row in an input string. e.g. [["1"] ["" "2"] ["" "" "3"] ["" "" "" "4"] ["6" "" "" "" "5"]] \$\endgroup\$
    – hakr14
    Dec 2, 2022 at 6:44
  • \$\begingroup\$ @hakr14 should be fixed, thanks for the heads-up! \$\endgroup\$ Dec 2, 2022 at 17:28
2
\$\begingroup\$

Excel 65 bytes

=LET(v,TEXTSPLIT(CONCAT(A:A),"-"),MID(v,SEQUENCE(MAX(LEN(v))),1))

enter image description here

\$\endgroup\$
1
\$\begingroup\$

Excel (ms365), 120 bytes

enter image description here

Formula in A1:

=TEXTJOIN(CHAR(10),,MAP(SEQUENCE(ROUND(MAX(LEN(A2:A5))/2,),,,2),LAMBDA(a,LET(b,MID(A2:A5,a,1),CONCAT(IF(b=""," ",b))))))

I do know that since you allow for trailing spaces I could remove ROUND() and /2 but it felt like cheating.

\$\endgroup\$
1
\$\begingroup\$

C (clang), 139 124 bytes

  • -15 bytes thanks to ceilingcat and jdt

Takes wide character strings as input.

f(*s,**t,m,i){for(t=s,m=0;i=*t;)m=fmax(wcslen(*t++),m);for(;i<m;i-=~puts(""))for(t=s;*t;t++)putchar(i<wcslen(*t)?i[*t]:32);}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Building on @ceilingcat, 124 bytes \$\endgroup\$
    – jdt
    Dec 3, 2022 at 12:37
0
\$\begingroup\$

JavaScript (Node.js), 45 bytes

x=>[...x+x].map((_,i)=>x.map(v=>v[i+i]||' '))

Try it online!

JavaScript (Node.js), 43 bytes

x=>[...x+x].map((_,i)=>x.map(v=>v[i]||' '))

Try it online!

43 take input as array, which looks unallowed so I added the 45

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.