20
\$\begingroup\$

Your task is to accept as input two "ASCII Art"s, and align each piece of art next to each other horizontally.

For example, say you have two strings, "abc\ndef" and "123\n456". You need to align them horizontally to produce the string "abc123\ndef456". I'm calling this "aligning horizontally" because while the inputs, when printed, look like this:

abc
def

and:

123
456

The output, when printed, will look like this:

abc123
def456

Note how one input is placed next to the other.


Input

  • Input will be strings, and can be as two separate arguments, or as a sequence of strings.

  • The characters in the arts will have decimal codes in the range 32-126 (inclusive).

  • It's fine to support an arbitrary number of arts to align instead of just two (but obviously you must support at least two).

  • You can assume that each art will have the same dimensions, and that they will contain at least one line.

  • You must be able to support at least 100x100 character arts.

  • To align with conventions on the site, the argument order does not matter. It does not matter which art is on the left or right.


Output

  • Output will be the aligned arts as mentioned above, either returned or output to the stdout.

  • Any trailing whitespace in optional.

  • There must be no visual separator between the aligned arts.


Input and output arts must be \n or \r delimited strings. It would be overly trivial to allow 2D-arrays.

Submissions may be functions or full programs.

Test Cases:

"abc\ndef", "123\n456" -> "abc123\ndef456".
"qwertyuiop\n asdfghjkl", "Some other\nTextFiller" -> "qwertyuiopSome other\n asdfghjklTextFiller"
" * \n *** \n*****\n *** \n * \n", " + \n + \n+++++\n + \n + \n" -> " * + \n *** + \n*****+++++\n *** + \n * + \n"
asked Mar 16, 2018 at 15:21
\$\endgroup\$
18
  • 1
    \$\begingroup\$ Can we use a custom delimiter instead of newlines? i.e. "|" or " "? \$\endgroup\$ Commented Mar 16, 2018 at 15:30
  • 10
    \$\begingroup\$ I'm gonna say no given that would kind of ruin any art. \$\endgroup\$ Commented Mar 16, 2018 at 15:31
  • \$\begingroup\$ May we use \r instead of \n? \$\endgroup\$ Commented Mar 16, 2018 at 15:50
  • \$\begingroup\$ @Adám Sure. I'll update the wording. \$\endgroup\$ Commented Mar 16, 2018 at 15:52
  • \$\begingroup\$ Is leading whitespace ok? \$\endgroup\$ Commented Mar 16, 2018 at 15:53

31 Answers 31

1
2
20
\$\begingroup\$

Canvas, 1 byte

×ばつ

Try it here!

answered Mar 16, 2018 at 15:44
\$\endgroup\$
7
  • 6
    \$\begingroup\$ Cause who doesn't just have a builtin for this? :P \$\endgroup\$ Commented Mar 16, 2018 at 15:49
  • 5
    \$\begingroup\$ That's not even fair. ;-; \$\endgroup\$ Commented Mar 16, 2018 at 15:52
  • 3
    \$\begingroup\$ @KevinCruijssen On PPCG it's usually allowed to take inputs in whatever order you want, and for a stack-based language the current order makes more sense than reverse. \$\endgroup\$ Commented Mar 16, 2018 at 16:43
  • 5
    \$\begingroup\$ @KevinCruijssen although I just remembered that I have a built-in for reverse add, so I'm updating the post :p \$\endgroup\$ Commented Mar 16, 2018 at 16:45
  • 3
    \$\begingroup\$ So Canvas has two builtins for this? Ok, why not? \$\endgroup\$ Commented Mar 16, 2018 at 20:11
7
\$\begingroup\$

Haskell, 37 bytes

(unlines.).(.lines).zipWith(++).lines

Try it online!

IO as lists of lines would just be zipWith(++). :P

answered Mar 16, 2018 at 15:26
\$\endgroup\$
6
\$\begingroup\$

Python 2, 59 bytes

lambda y:'\n'.join(map(str.__add__,*map(str.splitlines,y)))

Try it online!

answered Mar 16, 2018 at 15:25
\$\endgroup\$
3
  • \$\begingroup\$ It can also be shortened by removing the space. :P \$\endgroup\$ Commented Mar 16, 2018 at 15:27
  • \$\begingroup\$ If you want to input and output lists of lines, as you had before, you can get it down to 30: Try it online! \$\endgroup\$ Commented Mar 16, 2018 at 15:43
  • \$\begingroup\$ I sat there for like 5 minutes trying to decide if I should allow that. As the Haskell answer shows, it would reduce the challenge down to something much more trivial. I suppose though that the overly trivial solutions just wouldn't be as popular. \$\endgroup\$ Commented Mar 16, 2018 at 16:40
4
\$\begingroup\$

05AB1E, 6 bytes

|¶¡øJ»

Try it online!

Explanation

| # push all input into a list
 ¶¡ # split on newlines
 ø # zip
 J # join the rows to single strings
 » # merge on newlines
answered Mar 16, 2018 at 15:30
\$\endgroup\$
1
  • \$\begingroup\$ Too bad a space between the two inputs wasn't allowed :(. \$\endgroup\$ Commented Mar 16, 2018 at 16:44
3
\$\begingroup\$

Jelly, 4 bytes

Ỵ€ZY

Try it online!

answered Mar 16, 2018 at 15:43
\$\endgroup\$
3
\$\begingroup\$

Perl 5 -0F, 28 bytes

Includes +2 for the \n argument to -F (it's "code" so it should count)

Give inputs directly after each other on STDIN.

#!/usr/bin/perl -0F\n
say@F[$%++,$_]for@F/2..$#F

Try it online!

answered Mar 16, 2018 at 15:57
\$\endgroup\$
3
\$\begingroup\$

Bash + coreutils, 14

  • 4 bytes saved thanks to @DavidFoerster.
paste -d "" $@

Input is given as two filenames as command-line parameters.

Try it online.

answered Mar 16, 2018 at 18:56
\$\endgroup\$
2
  • \$\begingroup\$ You can save 4 bytes: paste -d "" $@ \$\endgroup\$ Commented Mar 16, 2018 at 20:50
  • \$\begingroup\$ @DavidFoerster Thanks! Weird - I tried that earlier and it didn't work. Edit - I see now - instead of -d "", I tried -d"", which of course is no different to -d \$\endgroup\$ Commented Mar 16, 2018 at 21:38
3
\$\begingroup\$

Perl 6, 27 bytes

{join "\n",[Z~] $_>>.lines}

Try it online!

Works with arbitrary number of arts. IO as list of lists would be just &[Z~].

answered Mar 16, 2018 at 18:48
\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog Unicode), 9 bytes SBCS

Full program. Prompts (STDIN) for any length list of \r-delimited strings. The strings may be ragged and of different widths as long as they have the same number of lines. Prints (STDOUT) resulting ASCII art.

⊃,/⎕FMT ̈⎕

Try it online!

prompt for evaluated input

⎕FMT ̈ format (evaluate all control characters and return character matrix) each

,/ combine them horizontally (catenation reduction)

disclose (because the reduction reduced the rank from 1 to 0)

answered Mar 16, 2018 at 17:00
\$\endgroup\$
2
\$\begingroup\$

Java 8, (削除) 100 (削除ここまで) (削除) 84 (削除ここまで) 78 bytes

a->b->{for(int i=0;;)System.out.println(a.split("\n")[i]+b.split("\n")[i++]);}

Exits with an ArrayIndexOutOfBoundsException to STDERR after it has printed the result to STDOUT, which is allowed.

-6 bytes thanks to @OlivierGrégoire.

Explanation:

Try it online.

a->b->{ // Method with two String parameters and no return-type
 for(int i=0;;) // Loop over the substrings of the first input
 System.out.println( // Print:
 a.split("\n")[i] // The substring of the first input
 +b.split("\n")[i++]);} // plus the same-indexed substring of the second input
answered Mar 16, 2018 at 16:37
\$\endgroup\$
2
  • 1
    \$\begingroup\$ a->b->{for(int i=0;;)System.out.println(a.split("\n")[i]+b.split("\n")[i++]);} 78 bytes. Nothing is said about not having any extra side-effect. So we could simply count until an exception occurs. \$\endgroup\$ Commented Mar 16, 2018 at 17:07
  • \$\begingroup\$ @OlivierGrégoire Thanks! And exiting with an error to STDERR is indeed allowed after it has printed everything to STDOUT. \$\endgroup\$ Commented Mar 16, 2018 at 17:53
2
\$\begingroup\$

Ruby, 48 bytes

->a,b{$;=$/;a.split.zip(b.split).map(&:join)*$/}

Try it online!

A lambda taking two strings and returning a string. Setting the default split delimiter to newline with $;=$/; doesn't save any bytes, but it makes the rest look a little nicer.

Ruby, 49 bytes (arbitrarily many strings)

->s{s.map{|a|a.split$/}.transpose.map(&:join)*$/}

Try it online!

Just for fun. It turns out we can accept an array of strings at an additional cost of only 1 byte.

answered Mar 16, 2018 at 19:22
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 51 bytes

f=
(a,b)=>a.replace(/.+/g,a=>a+b.shift(),b=b.split`
`)
;document.write("<pre>"+f("abc\ndef", "123\n456")+"</pre>")

answered Mar 16, 2018 at 23:51
\$\endgroup\$
2
\$\begingroup\$

Wonder, 21 bytes

->#oN.zip#++.-> <>"
"

Usage example:

(->#oN.zip#++.-> <>"
")["abc#ndef" "abc#ndef"]

#n is used instead of \n to denote newlines.

Explanation

Verbose version:

(map #oN) . (zip #con) . (map split "#n")

Split each string in the input array along newlines, zip with string concatenate, and output each item.

answered Mar 17, 2018 at 4:00
\$\endgroup\$
2
\$\begingroup\$

Kotlin, 73 bytes

a,b->a.split("\n").mapIndexed{i,s->s+b.split("\n")[i]}.joinToString("\n")

Try it online!

answered Mar 17, 2018 at 16:37
\$\endgroup\$
2
\$\begingroup\$

Vyxal j, 4 bytes

↵∩vṅ

Try it Online!

answered May 3, 2022 at 2:30
\$\endgroup\$
2
\$\begingroup\$

K (ngn/k), (削除) 15 (削除ここまで) 14 bytes

"\n"/,'/"\n"\'

Try it online!

-1 byte thanks to ngn

answered May 3, 2022 at 15:29
\$\endgroup\$
1
  • 1
    \$\begingroup\$ ,/'+ -> ,'/ \$\endgroup\$ Commented May 19, 2022 at 16:52
1
\$\begingroup\$

Add++, 24 bytes

L,c10CdVAptA$pG$tBcB@£+n

Try it online!

answered Mar 16, 2018 at 15:56
\$\endgroup\$
1
\$\begingroup\$

C, 96 bytes

#define L(s)for(;*s++>10;)putchar(s[-1]);
i;f(s,t)char*s,*t;{for(;i=!!s[-i];puts("")){L(s)L(t)}}

Try it online!

answered Mar 16, 2018 at 16:01
\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 52 bytes

Takes input in currying syntax (a)(b).

a=>b=>a.split`
`.map((s,i)=>s+b.split`
`[i]).join`
`

Try it online!

answered Mar 16, 2018 at 16:05
\$\endgroup\$
1
\$\begingroup\$

PowerShell, (削除) 51 (削除ここまで) 49 bytes

param($a,$b)$a-split"
"|%{$_+($b-split"
")[$i++]}

Try it online!

Takes input as literal strings with newlines. You could also use `n (the newline delimiter in PowerShell, not \n) instead.

We first -split the left input string on newlines, which creates an array, and loop through that |%{...}. Each iteration, we string concatenate with the right input string again split on newlines, indexed and incremented.

Those are left on the pipeline and the implicit Write-Output at completion gives us output as an array of strings, which are printed with newlines between.

Riker
7,9284 gold badges40 silver badges73 bronze badges
answered Mar 16, 2018 at 16:03
\$\endgroup\$
1
\$\begingroup\$

APL (Dyalog Unicode), 22 bytes (Adám's SBCS)

{⊃,/↑ ̈⍵}'[^\n]+'⎕S'&' ̈

Try it online!

answered Mar 16, 2018 at 15:50
\$\endgroup\$
0
1
\$\begingroup\$

Red, 78 bytes

func[a b][b: split b"^/"foreach c split a"^/"[prin c print first b b: next b]]

Try it online!

answered Mar 16, 2018 at 17:29
\$\endgroup\$
1
\$\begingroup\$

Bash, 92 bytes

a=();for b;do c=;while IFS= read -r d;do a[c++]+=$d;done<<<"$b";done;printf '%s\n' "${a[@]}"

Try it online!

Ungolfed:

array=() # Initialize the array
for argument in "${@}"; do # Loop over the arguments list
 index='0' # Reset the index
 while IFS='' read -r 'line'; do # Loop over every line of the current argument
 array[index]+="${line}" # Append the line to its corresponding place
 (( index++ )) # Increment the index
 done <<< "${argument}" # End while loop
done # End for loop
printf '%s\n' "${array[@]}" # Print array's content

Examples:

$ foo $'abc\ndef' $'123\n456'
abc123
def456
$ foo $'qwertyuiop\n asdfghjkl' $'Some other\nTextFiller'
qwertyuiopSome other
 asdfghjklTextFiller
$ foo \
> $' * \n *** \n*****\n *** \n * \n' \
> $' + \n + \n+++++\n + \n + \n'
 * + 
 *** + 
*****+++++
 *** + 
 * + 
# https://gist.github.com/nxnev/dad0576be7eb2996b860c320c01d0ec5
$ foo "$(< input1)" "$(< input2)" "$(< input3)" > output

I also have a shorter one but it fails if the second read statement returns a non-zero value.

Bash, 55 bytes

while IFS= read -r a;IFS= read b<&3;do echo "$a$b";done

Note: <&3 doesn't seem to work on tio.run

This one uses file descriptors (1 and 3) instead of arguments:

$ foo <<< $'qwertyuiop\n asdfghjkl' 3<<< $'Some other\nTextFiller'
qwertyuiopSome other
 asdfghjklTextFiller
answered Mar 16, 2018 at 21:46
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 8 bytes

PθM⌕θ¶→η

Try it online! Link is to verbose version of code. Explanation:

 θ First input
P Print without moving the cursor
 θ First input
 ¶ Literal newline
 ⌕ Find index
 M → Move that many squares right
 η Implicitly print second input

Add 2 bytes to accept multiple inputs:

FA«PιM⌕ι¶→

Try it online! Link is to verbose version of code. Explanation:

 A Input
F « Loop over all entries
 Pι Print current entry
 M⌕ι¶→ Move to next entry

Add 4 bytes to accept unpadded input:

PθM⌈E⪪θ¶Lι→η

Try it online! Link is to verbose version of code. Explanation:

 θ First input
 ¶ Literal newline
 ⪪ Split
 E Map over each string
 ι Current string
 L Length
 ⌈ Maximum
 M → Move that many squares right
answered Mar 17, 2018 at 0:08
\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 79 bytes

a=>(b=a.map(x=>x.split`
`))[i=0].map(y=>b.map(z=>c+=z[i],c="")&&++i&&c).join`
`

Try it online!

Supports arbitrary number of ASCII arts joining together rather than just 2 (as in the 2 previous JS answers).

answered Mar 17, 2018 at 1:57
\$\endgroup\$
1
\$\begingroup\$

Clean, 61 bytes

import StdEnv
$a b=flatlines[u++v\\u<-mklines a&v<-mklines b]

Try it online!

answered Mar 17, 2018 at 4:53
\$\endgroup\$
1
\$\begingroup\$

Swift 4, 119 bytes

func f(s:[String])->String{return s[0].split{0ドル=="\n"}.enumerated().map{0ドル.1+s[1].split{0ドル=="\n"}[0ドル.0]+"\n"}.joined()}

Explanation

func f(s: [String]) -> String {
 return s[0].split{ 0ドル=="\n" } //splitting the first string after every \n
 .enumerated() //create a tuple of offsets and elements
 .map {
 0ドル.1 + //current element
 s[1].split{0ドル == "\n"}[0ドル.0] + //splitting the second string + indexing
 "\n" //new line after every line
 }
 .joined()
}

Try it online!

answered Mar 18, 2018 at 2:24
\$\endgroup\$
1
\$\begingroup\$

Julia 1.0, 34 bytes

^,x=split,"\n"
a\b=join(a^x.*b^x,x)

Try it online!

answered May 3, 2022 at 9:19
\$\endgroup\$
1
\$\begingroup\$

Wolfram Language (Mathematica), 43 bytes (41 chars)

Column[StringJoin/@(#~StringSplit~"
")]&

 is an unprintable character in the private use area which represents Transpose in Mathematica.

This function takes input as a list of any number of strings and returns a Column object, which displays in a Mathematica notebook in the required manner (although it doesn't on TIO). For an additional ten bytes, replacing Column[---] with StringRiffle[---," "] will cause an output in the form of a single string. This code can take input of any number of strings with varied-length lines, as long as each string has the same number of lines.


Explanation:

#~StringSplit~ Split the input (implicitly applied to each string in the list)

" " at each newline.

Then, transpose this list of lists of strings

StringJoin/@ and join together each of the sublists.

Column Finally, convert this list of strings to a Column object.

Try it online!

answered May 3, 2022 at 15:10
\$\endgroup\$
2
  • \$\begingroup\$ Just out of curiosity, how did you come by my challenge? There's been like four very recent submissions to a challenge I posted 4 years ago. \$\endgroup\$ Commented May 3, 2022 at 15:47
  • \$\begingroup\$ It popped up on the recently answered questions (probably from Steffan's Vyxal answer) and so I decided to do it. \$\endgroup\$ Commented May 3, 2022 at 15:49
1
\$\begingroup\$

Japt -R, (削除) 8 (削除ここまで) (削除) 7 (削除ここまで) 5 bytes

·í+V·

Try it

·í+V· :Implcict input of strings U & V
· :Split U on newlines
 í :Interleave with
 V· : V split on newlines
 + : Reduce by concatenation
 :Implicit output, joined by newlines
answered Mar 16, 2018 at 16:55
\$\endgroup\$
1
2

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.