# Bring ASCII art to the 3rd dimension

In this challenge, You have to bring ASCII art (which are usually 2D) to 3D!

# How?

like this,

X X DD
X  D D
X X DD


to...

  X X DD
X X DD D
X X DDDD
X XDDD
X X DD


# Then How do we do that?

Given the ascii art and N, repeat this N times.

• for every character (we will call this A):
• let B be the character which is exactly 1 right and 1 up from A
• if B is a space or is undefined:
• set B to A.

# Specs

• The first input can be a string with newline characters or a list of strings representing the 2D ASCII art.
• You are allowed to use %END% to tag the end of input, but this is not required.
• The second input will be N. It will be a positive integer.
• all the lines of the strings will be the same length.

# Examples

Input: ("###\n###",1)

Output:

 ###
####
###


# Rules

Basic rules apply.

also, If you have questions, be sure to ask in the comments!

• You might want to clarify that "blank" refers to space (U+0020) or nothing. – Leaky Nun Jul 22 '16 at 12:44
• @LeakyNun Is it fixed now? – user54200 Jul 22 '16 at 12:48
• Is extra whitespaces allowed? – Leaky Nun Jul 22 '16 at 12:53
• Yes, Those are allowed. – user54200 Jul 22 '16 at 12:54
• Can I assume that the length of each line will be the same? (Can I pre-pad the input with spaces on the right?) – Leaky Nun Jul 22 '16 at 13:04

## Perl, 81 bytes

75 bytes code + 6 for -i -n0.
Note that the \e characters are ASCII \x1b but \e is used for ease of testing.

Please note that this solution uses ANSI escape sequences and requires a compatible terminal, as well as using the -i commandline argument to pass in the number of 'dimensions' you'd like.

$n=s/^//mg-1;s/ /\e[1C/g;print(s/^/\e[${^I}C/grm."\e[${n}A"),--$^I for($_)x$^I


### Usage:

In a Linux compatible terminal, run PS1= first to ensure your prompt doesn't overwrite the displayed image.

perl -i10 -n0e '$n=s/^//mg-1;s/ /\e[1C/g;print(s/^/\e[${^I}C/grm."\e[${n}A"),--$^I for($_)x$^I' <<< '
ROFL:ROFL:ROFL:ROFL
_^___
L    __/   [] \
LOL===__        \
L      \________]
I   I
--------/
'

ROFL:ROFL:ROFL:ROFL
ROFL:ROFL:ROFL:ROFL
ROFL:ROFL:ROFL:ROFL
ROFL:ROFL:ROFL:ROFL\
ROFL:ROFL:ROFL:ROFL\_]
ROFL:ROFL:ROFL:ROFL\_]
ROFL:ROFL:ROFL:ROFL\_]/
ROFL:ROFL:ROFL:ROFL\_]/
ROFL:ROFL:ROFL:ROFL\_]/
ROFL:ROFL:ROFL:ROFL\_]/
LOL==___^___]_\_\_]/
LOL==__/ \_[]_\_\_]/
LOL===__ \______\_]/
L      \________]/
I---I---/
--------/

perl -i3 -n0e '$n=s/^//mg-1;s/ /\e[1C/g;print(s/^/\e[${^I}C/grm."\e[${n}A"),--$^I for($_)x$^I' <<< 'X X DD
X  D D
X X DD
'
X X DD
X X DD D
X X DDDD
X XDDD
X X DD


## CJam, 25 24 bytes

{{' 1$f+La@+..{sS@er}}*}  An unnamed block that expects a list of strings and the number of repetitions on the stack and leaves a new list of strings instead. Test it here. (Includes a test wrapper that reads the string from STDIN for convenience.) ### Explanation { e# Repeat this block N times... ' e# Push a space character. 1$    e#   Copy the current grid.
f+    e#   Prepend the space to each line of the grid.
La    e#   Push [[]].
@+    e#   Pull up the other copy of the grid and prepend the [].
e#   We've now got two copies of the grid, one shifted right by
e#   a cell and one shifted down by a cell. We now want to replace
e#   spaces in the latter with the corresponding character in the
e#   former.
..{   e#   For each pair of characters in corresponding positions...
s   e#     Turn the character in the down-shifted grid into a string.
S   e#     Push " ".
@   e#     Pull up the character from the right-shifted grid.
er  e#     Replace spaces with that character.
}
}*

• Ten roflcopters! goo.gl/PEK4iB – user54200 Jul 22 '16 at 13:30
• Why doesn't S work for the initial space? Also, is it allowed to use variables (which might have been overwritten) in a function? – Luis Mendo Jul 22 '16 at 16:51
• @LuisMendo S doesn't work, because then f would be mapping over that string instead. Re functions, I believe so, in "normal" languages, there are also many functions submissions that rely globals which aren't tampered with between invocations. – Martin Ender Jul 22 '16 at 16:53
• Thanks. I forgot that a character in CJam is not the same as a one-character string – Luis Mendo Jul 22 '16 at 17:05
• You can save one byte by using Convex as it has a one-char transliterate operator instead of a two-char: convex.tryitonline.net/… (shameless plug) – GamrCorps Jul 22 '16 at 20:03

## APL, 49 bytes

{⎕UCS 32⌈{s+(s=0)×1⊖¯1⌽s←0⍪⍵,0}⍣⍺⊣(32∘≠×⊣)⎕UCS↑⍵}


Input: vector of character vectors. Example:

      2 {⎕UCS 32⌈{s+(s=0)×1⊖¯1⌽s←0⍪⍵,0}⍣⍺⊣(32∘≠×⊣)⎕UCS↑⍵} 'X X DD' ' X  D D' 'X X DD'
X X DD
X X DD D
X X DDDD
X XDDD
X X DD


How it works:

• ↑⍵ turns the argument into a matrix of chars
• ⎕UCS from char to integer
• (32∘≠×⊣) substitute the spaces (32) with zeroes
• ...⍣⍺⊣ apply ⍺ (the left argument) times the function on the left
• s←0⍪⍵,0 border with zeroes on top and on the right the argument
• 1⊖¯1⌽ rotate 1 up and 1 right
• s+(s=0)× sum to the original the shifted version but only on top of the zeroes of the original
• 32⌈ turns back the zeroes into 32s
• ⎕UCS from integer to char

# MATL, 24 bytes

:"ct32>*TTYatFTEqYSy~*+c


Input format is

2
{'X X DD', ' X  D D', 'X X DD'}


So the other example is

1
{'###', '###'}


The output contains extra whitespace, which is allowed by the challenge.

Try it online!

If a 2D char array is acceptable as input (I've asked the OP twice...), the first c can be removed, so 23 bytes:

:"t32>*TTYatFTEqYSy~*+c


Input format in this case is (all strings have equal lengths, which may require right-padding with spaces):

2
['X X DD '; ' X  D D'; 'X X DD ']


Try it online!

### Explanation

:        % Input number n implicitly. Generate [1 2 ... n]
"        % For loop: repeat n times
c      %   Convert to char array. In the first iteration it inputs a cell array of
%   strings implicitly and converts to a 2D char array, right-padding with
%   spaces. In the next iterations it does nothing, as the top of the stack
%   is already a 2D char array
t32>*  %   Convert characters below 32 into 0
TT     %   Push array [1 1]
Ya     %   Pad the 2D char array with one zero in the two directions (up/down,
%   left/right), on both sides
t      %   Duplicate
FTEq   %   Push array [-1 1]
YS     %   Circularly shift the 2D char array one unit up and one unit right
y      %   Push a copy of the non-shifted 2D array
~      %   Logical negate: nonzero entries become 0, zero entries become 1. This
%   will be used as a mask for entries that need to be changed. Since the
%   values at those entries are zero, we can simply add the new values. We do
%   that by multiplying the mask by the shifted array and adding to the
%   non-shifted array
*      %   Multiply element-wise
c      %   Convert the 2D array back to char
% End for
% Implicitly display


## Convex, 23 bytes

Byte count assumes CP-1252 encoding.

{{' 1$f+La@+..{sS@Ë}}*}  An unnamed block that expects a list of strings and the number of repetitions on the stack and leaves a new list of strings instead. Try it online! This is a direct port of my CJam answer to Convex (which is heavily based on CJam). The only difference is that Convex uses Ë instead of er for transliteration, saving one byte. Thanks to GamrCorps for letting me know about it. # Pyth, 54 33 bytes ju+++dhG.bsmh|-d;;.t,Y+dNdtGGeG.*  Test suite. • why do you need two ;? – Ven Jul 22 '16 at 13:55 • @ven ; is not the usual ; in programming languages. – Leaky Nun Jul 22 '16 at 14:19 • ; is a variable. – Leaky Nun Jul 22 '16 at 14:19 • ah pyth overloads ; in lambdas... – Ven Jul 22 '16 at 14:24 • @ven When you get along with Pyth, you would use I, .?, V, F, ;, (explicit statements) very less, and they will be replaced by ?, m, u, F, M, L, R, #, ... – Leaky Nun Jul 22 '16 at 14:26 ## JavaScript (ES6), 128 bytes f=(a,n)=>n?f((a=[,...a].map(s=>[...s|| ])).map((b,i)=>i--&&b.map((c,j)=>a[i][++j]>' '?0:a[i][j]=c))&&a.map(b=>b.join),n-1):a  Accepts and returns an array of strings, prepends an extra row for the output, ensures each row contains at least a space, splits them all up into characters, loops though trying to copy the characters to the row above and column to the right, then recursively calls itself to complete the loop. # Python 2, 116 bytes S=' ' def f(a,d):e=[S*len(a)];exec"a=[''.join(t[t[1]>S]for t in zip(S+x,y+S))for x,y in zip(a+e,e+a)];"*d;return a  I’ll golf this more soon. • Are you sure a lambda isn't shorter? – wizzwizz4 Jul 23 '16 at 8:31 • I need the assignment of e in there. Also, exec is a statement, so it can’t be in a lambda. – Lynn Jul 23 '16 at 10:24 • Ok. Just making sure. – wizzwizz4 Jul 23 '16 at 11:55 # Ruby, 95 bytes ->a,n{n.downto(0){|i|f="<Esc>[1C"$><<a.gsub(/^/,f*i).gsub(" ",f)+(i>0?"<Esc>[#{a.lines.size-1}A":"")}}


Each <Esc> is a literal ESC character (0x1b).

## Usage

Assign the lambda to a variable e.g. func.

art = <<END
X X DD
X  D D
X X DD
END

func[art, 2]
# Prints:
#   X X DD
#  X X DD D
# X X DDDD
#  X XDDD
# X X DD


## Ungolfed

->(art, num) {
num.downto(0) do |i|
forward = "\e[1C"
\$> << art.gsub(/^/, forward * i).gsub(" ", forward) +
(i > 0 ? "\e[#{art.lines.size - 1}A" : "")
end
}


The forward escape sequence, \e[1C, moves the cursor forward (right) 1 space and \e[<n>A moves it up n lines. Basically what this code does is print the "layers" back to front, replacing spaces with the forward sequence to avoid overwriting the other layers with a space.

• You accidentally put a f= before the -> in the golfed version. Remove it for -2 bytes. – wizzwizz4 Jul 23 '16 at 8:30