# Lay out the Carpet

Inspired by this SO question.

## Challenge:

Input:

• A string $$\s\$$
• A character $$\c\$$

Output:

Create a diamond-square ASCII art of the string in all four directions, with the first character of the string in the center and going outwards. Which is inside a square ASCII-art carpet, with the character as filler. This may sound pretty vague, so here an example:

Input: $$\s\$$ = string, $$\c\$$ = .
Output:

..........g..........
........g.n.g........
......g.n.i.n.g......
....g.n.i.r.i.n.g....
..g.n.i.r.t.r.i.n.g..
g.n.i.r.t.s.t.r.i.n.g
..g.n.i.r.t.r.i.n.g..
....g.n.i.r.i.n.g....
......g.n.i.n.g......
........g.n.g........
..........g..........


## Challenge rules:

• Input-string may also be a list of characters
• Output may also be a list of string-lines or matrix of characters
• Input-string and character are guaranteed to be non-empty
• The string is guaranteed to not contain the character
• Both string and character will only be printable ASCII (unicode range [32,126], space ' ' to and including tilde '~')

## General rules:

• This is , so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
• Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
• Default Loopholes are forbidden.

## Test cases:

Input: $$\s\$$ = 11111, $$\c=\$$ = 0
Output:

00000000100000000
00000010101000000
00001010101010000
00101010101010100
10101010101010101
00101010101010100
00001010101010000
00000010101000000
00000000100000000


Input: $$\s\$$ = 12345ABCDEF, $$\c\$$ = #
Output:

####################F####################
##################F#E#F##################
################F#E#D#E#F################
##############F#E#D#C#D#E#F##############
############F#E#D#C#B#C#D#E#F############
##########F#E#D#C#B#A#B#C#D#E#F##########
########F#E#D#C#B#A#5#A#B#C#D#E#F########
######F#E#D#C#B#A#5#4#5#A#B#C#D#E#F######
####F#E#D#C#B#A#5#4#3#4#5#A#B#C#D#E#F####
##F#E#D#C#B#A#5#4#3#2#3#4#5#A#B#C#D#E#F##
F#E#D#C#B#A#5#4#3#2#1#2#3#4#5#A#B#C#D#E#F
##F#E#D#C#B#A#5#4#3#2#3#4#5#A#B#C#D#E#F##
####F#E#D#C#B#A#5#4#3#4#5#A#B#C#D#E#F####
######F#E#D#C#B#A#5#4#5#A#B#C#D#E#F######
########F#E#D#C#B#A#5#A#B#C#D#E#F########
##########F#E#D#C#B#A#B#C#D#E#F##########
############F#E#D#C#B#C#D#E#F############
##############F#E#D#C#D#E#F##############
################F#E#D#E#F################
##################F#E#F##################
####################F####################


Input: $$\s\$$ = @+-|-o-|-O, $$\c\$$ = :
Output:

::::::::::::::::::O::::::::::::::::::
::::::::::::::::O:-:O::::::::::::::::
::::::::::::::O:-:|:-:O::::::::::::::
::::::::::::O:-:|:-:|:-:O::::::::::::
::::::::::O:-:|:-:o:-:|:-:O::::::::::
::::::::O:-:|:-:o:-:o:-:|:-:O::::::::
::::::O:-:|:-:o:-:|:-:o:-:|:-:O::::::
::::O:-:|:-:o:-:|:-:|:-:o:-:|:-:O::::
::O:-:|:-:o:-:|:-:+:-:|:-:o:-:|:-:O::
O:-:|:-:o:-:|:-:+:@:+:-:|:-:o:-:|:-:O
::O:-:|:-:o:-:|:-:+:-:|:-:o:-:|:-:O::
::::O:-:|:-:o:-:|:-:|:-:o:-:|:-:O::::
::::::O:-:|:-:o:-:|:-:o:-:|:-:O::::::
::::::::O:-:|:-:o:-:o:-:|:-:O::::::::
::::::::::O:-:|:-:o:-:|:-:O::::::::::
::::::::::::O:-:|:-:|:-:O::::::::::::
::::::::::::::O:-:|:-:O::::::::::::::
::::::::::::::::O:-:O::::::::::::::::
::::::::::::::::::O::::::::::::::::::


Input: $$\s\$$ = AB, $$\c\$$ = c
Output:

ccBcc
BcAcB
ccBcc


Input: $$\s\$$ = ~, $$\c\$$ = X
Output:

~


Input: $$\s\$$ = /\^/\, $$\c\$$ = X
Output:

XXXXXXXX\XXXXXXXX
XXXXXX\X/X\XXXXXX
XXXX\X/X^X/X\XXXX
XX\X/X^X\X^X/X\XX
\X/X^X\X/X\X^X/X\
XX\X/X^X\X^X/X\XX
XXXX\X/X^X/X\XXXX
XXXXXX\X/X\XXXXXX
XXXXXXXX\XXXXXXXX

• Can the string contain spaces? – Emigna Mar 26 '19 at 9:16
• @Emigna Yes, all printable ASCII (unicode range [32,126]) are valid input-characters. – Kevin Cruijssen Mar 26 '19 at 9:21
• This becomes wonderful to debug if you use characters that visually look like a single character, e.g. ()()(). – Filip Haglund Mar 26 '19 at 10:09
• What should happen if $s$ is empty? – Solomon Ucko Mar 26 '19 at 19:09
• @SolomonUcko From the rules section: "Input-string and character are guaranteed to be non-empty" :) – Kevin Cruijssen Mar 26 '19 at 19:27

# Canvas, 8 bytes

Ｒ±［］／┼┼＊


Try it here!

7 bytes but mirrors a bunch of chars.

# R, 11895 92 bytes

function(a,d,n=length(a),I=c(n:1,1:n)[-n])for(i in I-1)write(c(a,d)[pmin(I+i,n+1)],1,n*2,,d)


Try it online!

Thanks to:

• Giuseppe for fixing an error and a golf
• Aaron Hayman for 22 bytes worth of golf
• I guess I need to drop my aversion to for loops in R, at least for golfing. – Aaron Hayman Mar 26 '19 at 15:29
• @Giuseppe, thanks, I shouldn't be so lazy about inclusion of extra test cases! – Kirill L. Mar 26 '19 at 15:46
• This for 98 looks closer to your solution than mine Try it online! – Aaron Hayman Mar 28 '19 at 13:10
• can take off another two with a bit of rearrangement: Try it online! – Aaron Hayman Mar 28 '19 at 16:02
• @AaronHayman or else this 92 byter combining the pmin logic with the rearrangement :-) – Giuseppe Mar 28 '19 at 16:42

# J, 59 56 bytes

,{~[:((0-2*#)}.\[:,0,:"0({:>:t)*t=:]+/<:)[:(|.@}.,])#\@]


Try it online!

Too long solution for J ... (entirely my fault)

• Here’s 39 – FrownyFrog Mar 27 '19 at 14:09
• @FrownyFrog Thanks, I think you should post it as your own solution – Galen Ivanov Mar 27 '19 at 16:23

# R, an ugly 118 bytes version

By letting the input be a vector of single characters, and outputting a matrix instead of printing nice ascii art.

function(s,C,l=length(s),L=4*l-3,k=2*l-1,y=abs(rep(1:k,L)-l)+abs(rep(1:L,e=k)-k)/2+1)matrix(ifelse(y%%1|y>l,C,s[y]),k)


Try it online!

# R, 161 157 bytes

saved 4 bytes by using ifelse instead of conditionally modifying y

function(S,C,l=nchar(S),L=4*l-3,k=2*l-1,y=abs(rep(1:L,k)-k)/2+abs(rep(1:k,e=L)-l)+1)cat(rbind(matrix(ifelse(y%%1|y>l,C,el(strsplit(S,''))[y]),L),'
'),sep='')


Try it online!

## ungolfed and commented

function(S,C){
s=el(strsplit(S,''))
l=nchar(S)
L=4*l-3
k=2*l-1
y=abs(rep(1:L,k)-k)/2+abs(rep(1:k,e=L)-l)+1 # distance from centre
y[!!y%%1]=l+1  # set non integers to one more than length of string
y[y>l]=l+1     # set number beyond length of string to one more than length of string
M = rbind(matrix(c(s,C)[y],L),'\n') # build matrix and add line returns
cat(M,sep='') # print the matrix as a string
}


hmmm, seems like the longest answer so far!

• Oh dear, should have looked at the question better – Aaron Hayman Mar 26 '19 at 13:18
• @KevinCruijssen I have fixed it now – Aaron Hayman Mar 26 '19 at 13:47
• for +15 bytes, you can make your ugly answer ascii-art: Try it online! – Giuseppe Mar 26 '19 at 16:58

# Python 2, 979690 84 bytes

def f(s,c):r=range(len(s));return[c.join(c*i+s[:i:-1]+s[i:]+c*i)for i in r[:0:-1]+r]


Try it online!

# Ruby, 9584 75 bytes

->a,c{(1...2*z=a.size).map{|i|s=a[j=(z-i).abs,z]*c+c*2*j;s.reverse.chop+s}}


Try it online!

Takes input string as an array of chars. Returns an array of strings.

# 05AB1E, 15 11 bytes

.sûsζøsýí€û


Try it online! or as a Test Suite

Explanation

.s            # push suffixes of input
û           # palendromize this list
sζ         # transpose using the second input as filler
ø        # transpose back
sý      # merge each on the second input
í     # reverse each row
€û   # palendromize each row

• @KevinCruijssen: Yeah. Fortunately it didn't cost any bytes to fix it. I still feel as if there should be a better way of doing this though, so I'll keep looking. – Emigna Mar 26 '19 at 9:49
• "Output may also be a list of string-lines or matrix of characters", so you can move the » to the footer. :) – Kevin Cruijssen Mar 26 '19 at 10:37
• @KevinCruijssen Ah right. I glanced over that part. Thanks :) – Emigna Mar 26 '19 at 12:01

# J, 35 34 33 bytes

,{~1j1(}:@#"1{:(<*-)1-|+/|)i:@-&#


Try it online!

Right to left:
-&# Length of $$\c\$$ minus the length of $$\s\$$
i: Range from negative n to n
1-|+/| Absolute value, outer sum with absolute value, subtract from 1
{: (<*-) Compare the matrix with the end of the range (the -&#), 0 for less than or equal, 1 otherwise. Also subtract the matrix from the end of range. Multiply together. The double subtraction saves a byte and gives something like this

 0  0 _1  0  0
0 _1 _2 _1  0
_1 _2 _3 _2 _1
0 _1 _2 _1  0
0  0 _1  0  0


Negative indices start from -1 like in python. The only thing left is to insert the columns of zeroes.

1j1( #"1 for each row, repeat each element 1 time and pad with one 0
  }:@  then drop the last one (zero)
,{~concat $$\c\$$ and $$\s\$$ and index into that

Many thanks to Galen Ivanov for the algorithm.

• Would you mind adding an explanation? I'm not that familiar with J. – Kevin Cruijssen Mar 29 '19 at 14:02

# K (ngn/k), 38 bytes

{1_',/'y,''2{+x,1_|x}/(#x)'1_,/+y,'|x}


Try it online!

{ } function with arguments x (the string s) and y (the character c)

|x reverse x

y,' prepend y to each

+ transpose

,/ concat

1_ drop first char

at this point we have a string of length(x) instances of y followed by the characters from x

#x length of x

(#x)' sliding window of that many consecutive chars

2{ }/ do twice

+x,1_|x join x with the reversed x without its first element, and transpose

y,'' prepend y to each each

,/' concat each

1_' drop one from each

# Japt, 15 bytes

Returns an array of lines

Ôå+ ®¬qV êÃûV ê


Try it

Ôå+ ®¬qV êÃûV ê     :Implicit input of strings U=s & V=c
Ô                   :Reverse U
å+                 :Prefixes
®               :Map
¬              :  Split
qV            :  Join with V
ê          :  Palindromise
Ã         :End map
ûV       :Centre pad each string with V, to the length of the longest
ê     :Palindromise


# Charcoal, 15 bytes

ＵＢηＥθ✂θκ‖Ｏ↑←ＵＥ¹


Try it online! Link is to verbose version of code. Originally submitted as a comment on the now deleted sandbox post. Explanation:

ＵＢη


Set the background to the second input c.

Ｅθ✂θκ


Map over the first input s to generate all suffixes and implicitly print them on separate lines.

‖Ｏ↑←


Reflect horizontally and vertically.

ＵＥ¹


# APL (Dyalog Classic), 32 31 bytes

(⍉1↓¯1↓⊖⍪1↓⊢)⍣2∘↑(≢⊣),/,¨,2⍴¨⊢¨


Try it online!

# Wolfram Language (Mathematica), 121 bytes

Join[q=Table[(v=Table[#2,2(l-k)])<>Riffle[Join[(h=Reverse)[n=(g=Take)[#,-k]],g[n,-k+1]],#2]<>v,{k,l=Length@#}],Rest@h@q]&


Try it online!

# Japt, 16 bytes

Note: I'll golf it :)

Ôå+ ®¬qVÃùV mê ê


Try it online!

• It's fairly similar to the other Japt answer, but in a different order, isn't it? I don't know Japt, but I see similar characters in both answers. ;) – Kevin Cruijssen Mar 26 '19 at 11:56
• @KevinCruijssen Yeah, both are almost the same, for now – Luis felipe De jesus Munoz Mar 26 '19 at 12:09
• @KevinCruijssen, Luis developed this independently from my solution. – Shaggy Mar 26 '19 at 14:31

# PowerShell, 120 bytes

param($s,$c)($s,(($l=$s.length-1)..0+1..$l|%{($x=$c*(2*$_))+($s[($_,($l..$_+($_+1)..$l))[$_-ne$l]]-join$c)+$x}))[$l-gt0]


Try it online!

Some days, having index ranges instead of slices really hurts. Today is one of those days. Due to conjoined ranges messing up when dealing with single elements (e.g. returning 0..0+1..0), special-casing is used to avoid it altogether (at the cost of many bytes).

# Japt, 15 bytes

Ôå+ ê ®ê ¬qV
ûV


Try it

# Jelly, 11 bytes

jÐƤṚzṚŒḄZŒḄ


Try it online!

Left argument: $$\s\$$.
Right argument: $$\c\$$ (as a single character, not as a string).
Output: List of Jelly strings (appears as a list of lists of 1-char Python strings, replace ŒṘ with Y to see the \n-joined output).

# PowerShell, 82 83 bytes

+2 bytes thanks Veskah: the single character case bug fixed

-1 byte: The rule Input-string may also be a list of characters used

$c,$s=$args ($s|%{(-join$s|% s*g$i)+$c*$i++})[($r=$i..0+1..$i)]|%{"$_"[$r]-join$c}


Try it online!

Less golfed:

$c,$s=$args$southEast = $s|%{ (-join$s|% substring $i) +$c*$i++ }$range=$i..0+1..$i
$southEast[$range]|%{
"$_"[$range]-join$c }  • Looks like this breaks for the single character case. There's just an empty line in the TIO link for ~ – Veskah Mar 26 '19 at 17:21 • Indeed. Thanks! – mazzy Mar 26 '19 at 19:54 # Pip, 24 20 bytes QPRV:_JbMa@>RV,#aZDb  Use the -l flag to get human-readable output. Try it online! ### Explanation QPRV:_JbMa@>RV,#aZDb a,b are cmdline args (implicit) a 1st cmdline arg (the string) # Length , Range RV Reverse a@> Take slices of a starting at those indices ZDb Zip the list of slices together, filling out missing values in the matrix with b (the character) M To each row, map this function: _Jb Join on b RV: Reverse (making top row the bottom and vice versa) QP Quad-palindromize: reflect downward and rightward, with overlap  For example, with inputs of abcd and .: RV,#a [3 2 1 0] a@> ["d" "cd" "bcd" "abcd"] ZDb [['d 'c 'b 'a] ['. 'd 'c 'b] ['. '. 'd 'c] ['. '. '. 'd]] _JbM ["d.c.b.a" "..d.c.b" "....d.c" "......d"] RV: ["......d" "....d.c" "..d.c.b" "d.c.b.a"] QP ["......d......" "....d.c.d...." "..d.c.b.c.d.." "d.c.b.a.b.c.d" "..d.c.b.c.d.." "....d.c.d...." "......d......"]  # Attache, 57 bytes ${q:=#x-1Bounce!Bounce@Join&y@PadLeft&y&#x=>x[q::(q::0)]}


Try it online! Output is a list of lines.

## Explanation

?? parameters: x, y
${ ?? q is length of x - 1 q:=#x-1 ?? Reflect, collapsing middle: Bounce! ?? Function: ?? Reflect, Bounce@ ?? Joined by y, Join&y@ ?? padded to the length of x with y PadLeft&y&#x ?? Mapped over => ?? The elements of x at x[ ?? decreasing range from q to q::( ?? each element in the range from q to 0 q::0 ) ] }  # Perl 6, 79 bytes ->\c{{map {join c,g$_ X||c},g .[^*X+(^$_,)]}o*.comb} my&g={.[$_-1...0...$_-1]}  Try it online! Anonymous codeblock that takes input curried (like f(char)(string)) and returns a list of lines. I think a different approach would be shorter. ### Explanation: my&g={.[$_-1...0...$_-1]} # Helper function to palindromise a list ->\c{ } # Code block that takes a char { }o*.comb # And returns a function .[^*X+(^$_,)]  # Get all prefixes with end padding
# e.g. "str" => [["r",Nil,Nil]
["t","r",Nil]
["s","t","r"]]
g   # Palindromise the lsit
map {                },    # Map each element to
$_ X||c # Replace all Nils with the character g # Palindromise it join c, # And join by the character  # Perl 5 with -lF, -M5.010, 71 bytes $"=<>;$A=abs,$_="@F[$A..$#F]".$"x($A*2),/./,say reverse.$' for-$#F..\$#F


Try it online!

# C# (Visual C# Interactive Compiler), 249 bytes

s=>c=>{var r=s.Select((x,_)=>{int k=s.Length;var m=s.Substring(_,k-_).Aggregate("",(a,b)=>a+c+b);return new string(m.Skip(2).Reverse().Concat(m.Skip(1)).ToArray()).PadLeft(2*k-3+m.Length,c).PadRight(4*k-3,c);});return r.Skip(1).Reverse().Concat(r);}


Try it online!

This must be improvable...

• 213 – dana Mar 31 '19 at 12:10

# JavaScript (Node.js), 143 bytes

(s,c)=>{q=Math.abs;m=(l=s.length*4-3)-1;for(i=j=0;j<l/2;(i=(++i)%l)?0:++j){p=s[q(i-m/2)/2+q(j-m/4)];process.stdout.write((i?"":"\n")+(p?
p:c))}}


Try it online!

A bit more thinkering would lead to calculating in terms of a one-dimensional array, and less bytes.

# Kotlin, 250 bytes

Note: Kotlin tio currently fails to return a new class so this code gets an null pointer exception. This also occurs for codes I previously posted that worked at that time. I assume it will eventually get fixed, but couldn't find a support contact to report the issue to. It can also be run here.

{s:String,c:Char->val h=s.length*2-1
val w=h*2-1
val m=Array(h){Array(w){c}}
for(i in s.indices)for(r in 0..h-1){val o=(i-Math.abs(h/2-r))*2
if(o>=0){m[r][w/2+o]=s[i].toChar()
m[r][w/2-o]=s[i].toChar()}}
m.map{it.joinToString("")}.joinToString("\n")}


Try it online!

• You can contact @Dennis in The Ninteenth Byte chat. He's the moderator for TIO. Also, I allow returning a list of strings instead of actually printing, so I think (not sure) you can remove the .joinToString("\n") from the byte-count (and do that in the footer outside the function). – Kevin Cruijssen Mar 29 '19 at 22:59

# Gaia, 19 bytes

:ṫl¤┅v;@&Z¦<¦v¦ṫ¦ṫṣ


Try it online!

Explanation to follow.

# JavaScript (Node.js), 101 bytes

s=>c=>[l=s.length-1,...Array(l*2)].map((x,i,a,m=Math.abs)=>a.map((y,j)=>s[m(l-i)+m(l-j)]||c).join(c))


Try it online!

# TSQL query, 191 bytes

In MS-SQL Server Management Studio press Ctrl-T before running this query, this will change the output to text.

This script is building up the output from left to right in one long "string", calculating the value to put in each position. The output is limited to 4096 characters.

Golfed:

SELECT
string_agg(iif(h>k/2,@y,substring(@,h+1,1))+iif(-~n%k=0,'
',@y),'')FROM(SELECT
abs(k/2-n%k)+abs(k/2-n/k)h,*FROM(SELECT
number n,len(@)*2-1k,*FROM spt_values)c)d
WHERE n<k*k and'P'=type


Ungolfed:

USE master
DECLARE
@y char='.',
@ varchar(20) = 'abcd'

SELECT
string_agg(iif(h>k/2,@y,substring(@,h+1,1))+iif(-~n%k=0,'
',@y),'')
FROM
(
SELECT
abs(k/2-n%k)+abs(k/2-n/k)h,*
FROM
(
SELECT
number n,
len(@)*2-1k,*
FROM spt_values
)c
)d
WHERE n<k*k and'P'=type


I had to make some changes to format the output in the online version.

Try it online

# Java (JDK), 213199 198 bytes

a->b->{int i=0,l=a.length()-1;String s=a,r[]=new String[l-~l],p;for(;i<=l;s=s.substring(1))r[l+i]=r[l-i]=new StringBuffer(p=b.join(b,s.split(""))+b.repeat(2*i++)).reverse()+p.substring(1);return r;}


Try it online!

-14 bytes thanks to @KevinCruijssen
-1 byte thanks to @ceilingcat

### Ungolfed

a->
b-> {
int i = 0, l = a.length() - 1;
String s = a, r[]=new String[a.length()*2-1],p;
for (; i<=l; s=s.substring(1))
r[l+i]
= r[l-i++]
=   new StringBuffer(
p =   String.join(b,s.split(""))
+ b.repeat(2*i)
).reverse()
+ p.substring(1);
return r;
}

• Nice answer, you can golf it by 14 bytes below 200 however. :) – Kevin Cruijssen Apr 3 '19 at 6:37
• @KevinCruijssen Well spotted, thanks! – Sara J Apr 3 '19 at 10:09
• @ceilingcat Nice thinking, thanks! – Sara J Sep 20 '19 at 1:03

# Wolfram Language (Mathematica), 68 67 bytes

Table[#[[1+Abs@y+Abs@x]]/._@__->#2,{y,l=1-Tr[1^#],-l},{x,l,-l,.5}]&


Try it online!

Takes a list of characters and the filler character, and returns a matrix of characters.

Table[                            ,{y,l=1-Tr[1^#],-l},{x,l,-l,.5}]& (* make a (2*len-1 x 4*len-3) table centered at (0,0) *)
#[[             ]]                                                (*  where the value at each point is the string indexed at *)
1+Abs@y+Abs@x                                                  (*   (1 + |y-coordinate| + |x-coordinate|/2) *)
/._@__:>#2                                      (*  if that indexing fails, use the filler character instead *)


list[[index]] is equivalent to Part[list, index]; if the index is not valid - if it's not an integer or is out of range - that expression remains unevaluated.
The shortest pattern which matches Part[...], but not a single character, is _@__, which matches any expression with one or more arguments.