# Outline words with their letters

For the purposes of the current challenge to "outline" a word means to surround it successively with its own letters, starting with the last one, and finally to replace the original word in the center with spaces:

       oooooo
onnnno
on ->  on  no
onnnno
oooooo


Given a list of words, consisting only of lowercase and/or uppercase English letters, outline each word and display all the resulting blocks next to each other horizontally, separated by a column of single space, vertically aligned at the centers of the blocks.

You can write a full program, or a function.

## Input:

A list of words, or if you prefer - a space- or other symbol- delimited string

## Output:

The ASCII representation of the blocks for the outlined words. Leading/trailing whitespaces are permitted.

## Test cases:

Input 1: ["code", "golf"] (or "code golf")
Output 1:

cccccccccccc gggggggggggg
cooooooooooc goooooooooog
coddddddddoc gollllllllog
codeeeeeedoc golfffffflog
code    edoc golf    flog
codeeeeeedoc golfffffflog
coddddddddoc gollllllllog
cooooooooooc goooooooooog
cccccccccccc gggggggggggg

Input 2: ["I", "am", "just", "a", "man"]  (or "I am just a man")
Output 2:

jjjjjjjjjjjj
juuuuuuuuuuj     mmmmmmmmm
aaaaaa jussssssssuj     maaaaaaam
III ammmma justtttttsuj aaa mannnnnam
I I am  ma just    tsuj a a man   nam
III ammmma justtttttsuj aaa mannnnnam
aaaaaa jussssssssuj     maaaaaaam
juuuuuuuuuuj     mmmmmmmmm
jjjjjjjjjjjj


## Winning criteria:

The shortest code in bytes in each language wins. I will greatly appreciate if you comment/explain your code and approach.

• Can we assume there is at least one word? – PurkkaKoodari Nov 11 '18 at 12:32
• @Pietu1998 Yes, there always be at least one word – Galen Ivanov Nov 11 '18 at 14:45
• @Kevin Cruijssen Transpose? – Galen Ivanov Nov 13 '18 at 18:34

# Canvas, 22 20 bytes

ｌ ＊；±２１＊｛；ｌ└＊ｅ⟳｝ ］ｒ⤢


Try it here!

Explanation:

{                 ]    map over the inputs
l *                     array of length spaces - the canvas of the current word
;                    get the word back on top
±                   reverse it
21*                repeat each character twice
{      }        for each character
;l└              push the height of the item below (the canvas)
*             repeat the character that many times vertically
e            and encase the canvas in that char column
⟳           and rotate it clockwise for encasing the next time
∙      push another space as the separator of words
r   center the words
⤢  and transpose the final output (as everything was built vertically)


# Charcoal, 35 bytes

ＦＡ«≔ＬιθＭθ↑Ｆθ«Ｂ⁻×³θ⊗κ⊕⊗⁻θκ§ικ↘»Ｍ⊕⊗θ→


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

ＦＡ«


Loop over the input list.

≔Ｌιθ


Get the length of the current word.

Ｍθ↑


Move to the top left corner of the resulting outline.

Ｆθ«


Loop once for each character.

Ｂ⁻×³θ⊗κ⊕⊗⁻θκ§ικ


Draw a box of the appropriate height, width and character.

↘»


Move to the top left corner of the next box.

Ｍ⊕⊗θ→


Move to the next outline.

# Haskell, 188 183 174 171 167 bytes

-9 -13 bytes thanks to Laikoni.

e=[]:e
c#a=k c<$>k(c<$a!!0)a
k c s=c:s++[c]
f w=foldr(#)[p w]w
p=(' '<$) s w=unlines.map unwords.foldr(zipWith(:))e$until(\a->all((p a>=).p)$f<$>w)(k=<<p.head)<$>f<$>w


Try it online!

• \a->and[p a>=p x|x<-f<$>w] can be \a->all((p a>=).p)$f<\$>w and k c=(++[c]).(c:) can be k c s=c:s++[c]. – Laikoni Nov 12 '18 at 10:54

# Pyth, 34 33 bytes

Jsm+;uCjR*2HG_.iddm\ dQjCm.[lJd;J


Try it online.

Dumps out a whole bunch of extra whitespace, but that's allowed by the challenge.

### Explanation

• mQ does the following for each word d in the input Q:

• m\ d maps the word with x => " ", essentially creating the list [" ", ..., " "] with as many items as the word has letters.
• .idd interleaves the word with itself, repeating the word's letters twice. _ reverses this string. word becomes ddrrooww.
• u starts with G = the array of spaces, and applies the following with each letter in the interleaved string in H:
• *2H repeats the character twice.
• jRG puts each string in G between the pair of characters.
• C swaps rows and columns. When these three steps are done twice with the same character in H, this outlines the lines in G with that character.
• We now have the columns for the outlined word d. +; prepends a space column.
• s flattens the array of columns for each word, and J saves it in the variable J.
• mJ does the following for each column of the output:
• .[lJd; pads both sides of the column with spaces so that the length of the column is equal to the number of columns. This is always sufficient padding to make the columns align vertically.
• C turns the columns to rows and j joins the rows with newlines.

### Alternative solution, 33 bytes

j.tsm.[L\ l+dsQ+;uCjR*2HG_.iddm\


Try it online.

Note that there is a trailing space. Mostly the same algorithm, except only pads columns on the top and then transposes with space fill.

# R, 189 bytes

function(x,S=32,+=rbind,*=cbind)cat(intToUtf8(Reduce(+,Map(function(s,K=utf8ToInt(s),o=S-!K){for(i in rev(K))o=i+i*o*i+i
for(j in(0:(max(nchar(x))-nchar(s)))[-1])o=S*o*S
o+S},x))+10))


Try it online!

A collaboration between digEmAll and myself in chat.

function(x){
S <- 32			# space
+ <- rbind			# alias for rbind
* <- cbind			# alias for cbind
outlineWord <- function(s){	# function to construct the outline for each word
chars <- utf8ToInt(s)		# convert to code points
output <- S - !chars		# replace each char with 32 (space)
for(i in rev(chars))
o <- i + i * o * i + i	# o <- rbind(i,cbind(i,o,i),i)
for(j in(0:(max(nchar(x))-nchar(s)))[-1])
o <- S * o * S		# pad with spaces
o + S}			# return with an additional row of spaces between words
outlines <- Map(outlineWord,x)	# apply outlineWord to each element of x
outlines <- Reduce(+,outlines)# reduce by rbind
outlines <- outlines+10	# add row of newlines
cat(intToUtf8(outlines))	# convert back to strings and print
}

• 187 with an obvious alias – J.Doe Nov 20 '18 at 13:47
• @J.Doe it's community wiki so feel free to edit that in :-) – Giuseppe Nov 20 '18 at 15:46

# APL (Dyalog Classic), 5751 50 bytes

{⍉⊃⍪/,/((⊢-⌈/)≢¨⍵)⌽↑{⍪¨↓0 1↓⍕,∘⍉∘⌽⍣4/⍵,⊂⍉⍪¯1/⍵}¨⍵}


Try it online!

# Stax, 26 25 bytes

¢π‼○MªΘ└ƒ∩┘?◙↕)fY╨nu⌂E┴6X


Run and debug it

# 05AB1E, 46 bytes

εg©;ò<Uyηε¤®∍«®>∍}yð«©ª®Xиª˜».º.∊}¶«».C.B€SζJ»


Explanation:

ε                             # Map y over the (implicit) input-list
g                            #  Take the length of the current item
©                           #  Store it in the register (without popping)
;                          #  Halve it
ò                         #  Ceil and cast to integer at the same time
<                        #  Decrease it by 1
U                       #  Pop and store it in variable X
yη                           #  Take the prefixes of the current string y
ε       }                  #  Map over these prefixes:
¤                         #   Take the last character of the string
®×                       #   Increase it to a size equal to the length from the register
«                      #   Append it to the current prefix
®>                    #   Take the length from the register, and add 1
∍                   #   Shorten the string to that size
y                            #  Push the string y again
ð«                          #  Append a space
©                         #  Store it in the register (without popping)
ª                        #  Append it at the end of the list of modified prefixes
®                       #  Push the string with space from the register again
Xи                     #  Repeat it X amount of times
ª                    #  Append them to the list
˜                   #  Flatten to remove the empty appended list if X was 0
»                  #  Join by newlines
.º.∊              #  Intersect mirror both horizontally and vertically
}             # Close outer map
¶«           # Append a newline after each (for the space delimiters)
»          # Join everything by newlines
.C        # Centralize it horizontally
# (too bad a centralize vertically isn't available..)
.B      # Split on newlines again
€S    # Convert each line to a list of characters
ζ   # Zip, swapping rows/columns (with space filler by default)
J  # Join the loose characters of every line to a string again
» # Join the lines by newlines (and output implicitly)