11
\$\begingroup\$

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!

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

9 Answers 9

18
\$\begingroup\$

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
\$\endgroup\$
8
\$\begingroup\$

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.
  }
}*
\$\endgroup\$
6
  • 5
    \$\begingroup\$ Ten roflcopters! goo.gl/PEK4iB \$\endgroup\$
    – user54200
    Commented Jul 22, 2016 at 13:30
  • \$\begingroup\$ Why doesn't S work for the initial space? Also, is it allowed to use variables (which might have been overwritten) in a function? \$\endgroup\$
    – Luis Mendo
    Commented Jul 22, 2016 at 16:51
  • \$\begingroup\$ @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. \$\endgroup\$ Commented Jul 22, 2016 at 16:53
  • \$\begingroup\$ Thanks. I forgot that a character in CJam is not the same as a one-character string \$\endgroup\$
    – Luis Mendo
    Commented Jul 22, 2016 at 17:05
  • 1
    \$\begingroup\$ 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) \$\endgroup\$
    – GamrCorps
    Commented Jul 22, 2016 at 20:03
4
\$\begingroup\$

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
\$\endgroup\$
4
\$\begingroup\$

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
  +      %   Add element-wise
  c      %   Convert the 2D array back to char
         % End for
         % Implicitly display
\$\endgroup\$
3
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

Pyth, 54 33 bytes

ju+++dhG.bsmh|-d;;.t,Y+dNdtGGeG.*

Test suite.

\$\endgroup\$
5
  • \$\begingroup\$ why do you need two ;? \$\endgroup\$
    – Ven
    Commented Jul 22, 2016 at 13:55
  • \$\begingroup\$ @ven ; is not the usual ; in programming languages. \$\endgroup\$
    – Leaky Nun
    Commented Jul 22, 2016 at 14:19
  • \$\begingroup\$ ; is a variable. \$\endgroup\$
    – Leaky Nun
    Commented Jul 22, 2016 at 14:19
  • \$\begingroup\$ ah pyth overloads ; in lambdas... \$\endgroup\$
    – Ven
    Commented Jul 22, 2016 at 14:24
  • \$\begingroup\$ @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, #, ... \$\endgroup\$
    – Leaky Nun
    Commented Jul 22, 2016 at 14:26
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ Are you sure a lambda isn't shorter? \$\endgroup\$
    – wizzwizz4
    Commented Jul 23, 2016 at 8:31
  • \$\begingroup\$ I need the assignment of e in there. Also, exec is a statement, so it can’t be in a lambda. \$\endgroup\$
    – lynn
    Commented Jul 23, 2016 at 10:24
  • \$\begingroup\$ Ok. Just making sure. \$\endgroup\$
    – wizzwizz4
    Commented Jul 23, 2016 at 11:55
2
\$\begingroup\$

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.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You accidentally put a f= before the -> in the golfed version. Remove it for -2 bytes. \$\endgroup\$
    – wizzwizz4
    Commented Jul 23, 2016 at 8:30

Your Answer

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