Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

You don't want to pay money for the expensive architectural program, so you decide to roll your own. You decide to use ASCII to design your buildings. Your program will take in a single string formatted in a specific way, and the program will output the building.

Input

Input consists of a single line of characters. It can be assumed to only contain the letters a-j, the numbers 1-9, and the symbols - and +.

Output Description

For each letter a-j, the program will output a vertical line as follows. We will call this a column.

         .
        ..
       ...
      ****
     *****
    ******
   -------
  --------
 +++++++++
++++++++++
abcdefghij

For instance, the input abcdefgfedefghgfedc would output:

             .
      *     ***
     ***   *****
    ***** *******
   ---------------
  -----------------
 ++++++++++++++++++
+++++++++++++++++++

A letter may be prefixed with a positive integer n, which will add n whitespace characters below the column. We will call this an offset. For instance, using S to notate a whitespace, the input 3b2b3b would output:

+ +
+++
S+S
SSS
SSS

A letter may also be prefixed with a negative integer -m, which will remove the bottom m non-whitespace characters of the column (not replace them with whitespace, remove them entirely). We will call this a slice. For instance, the input -1j-2j-3j-4j-5j-6j-7j-8j would output:

.
..
...
*...
**...
***...
-***...
--***...
+--***..

An offset and a slice can be applied to the same line, but the offset must go first. In other words, the letter may be prefixed with n-m, where n is the size of the offset, and m is the size of the slice. For instance, using S to notate a whitespace, the input '2-4j' would output:

.
.
.
*
*
*
S
S

Lastly, the + operator used between two columns indicates that they should be stacked on top of each other in the same column instead of in seperate columns. For instance, the input `2-4ja' outputs:

.
.
.
*
*
*
S
S+

Whereas the input 2-4j+a outputs:

+
.
.
.
*
*
*
S
S

Here is a sample input:

abiehef+ehfhabc

And the resultant output:

      *
      -
  .   -
  . . +. .
  * * +* *
  * * ****
  ********
  --------
  --------  -
 +++++++++ ++
+++++++++++++

Looks like an old destroyed castle tower of some sort.

Here is another sample input:

6b5b+a6b1-2d+3-4f1-2d+-2c+2-4f+1-2d+-2c2-2d+1-4g+1-2c+b+-2c+-4e2-7j+-4g+d+-2c+-4f2-7j+-5h+b+-2c+a+-3f2-7j+-7i+-4e+b+b+a+-4f2-7i+a+-7h+-4f+b+b+a+-4f2-7j+-7h+-4f+a+-7h+a+-7i+-4f2-7j+-7i+-6h+a+-7i+b+-4e3-7i+a+-7h+-4e+a+-7h+b+1-7h3-7j+1-4f+-7h+b+-4f+a3-7j+2-4f+a+-4f+b3-2d+-2d+3-4g+b3-2d+-2d+-2c

And the resultant output:

      ****** +++
     ******+.*++
     ---++.+ ***
    -+-+++..++**
    -+--+++.+++*
    --++++.+..*
      +++++.+**
+++****.******  -
+++*****.**..  --
 +   ***....+..--
      ...+.....--
    --.........--
   ---......
   --

(It was supposed to be Mario but didn't turn out very good...)

If the specification still isn't clear, I have a non-golfed implementation written in Python 2.7. You can run it and experiment to get a feel for how the specification works. You may also choose to laugh at my programming skills.

This is code-golf, so shortest entry wins. Ask questions in comments if unclear.

share|improve this question
    
Stacking of more than two towers is valid? I see "2c+b+-2c" in one of your examples, but I can't make out if that's how you stacked them. –  AndoDaan Aug 20 at 21:17
1  
@AndoDaan Towers can be infinitely stacked using +. For instance a+a+a+a+a would output five plus signs on top of each other. –  Lilac Aug 20 at 21:26
1  
Isn't this a duplicate of codegolf.stackexchange.com/questions/18967/landscapes? –  Howard Aug 20 at 22:00
    
@Howard Huh, you're right, these are surprisingly similar (the only additions being to be able to cut off the tower and to stack towers). –  Martin Büttner Aug 20 at 22:03
    
​​​​​​​​​​​​​​@Howard Huh. It didn't show up on the similiar questions thingo that pops up when you type in your title. The implementation of the whitespace is a little different though. I'll flag my post as a duplicate and see what the mods think. –  Lilac Aug 20 at 22:11

3 Answers 3

up vote 10 down vote accepted

Ruby, 223 214 bytes

g=$*[0].split(/(?<=[a-j])(?!\+)/).map{|r|r.scan(/(\d*)(-\d+)?([a-j])/).map{|a,b,c|' '*a.to_i+'++--***...'[-b.to_i..c.ord-97]}*''}
puts g.map{|s|s.ljust(g.map(&:size).max).chars.reverse}.transpose.map(&:join).join$/

That was fun. :)

Although it should be quite obvious, I discovered a new way to do these challenges where strings have be constructed from columns: just do them in rows, and transpose the array of characters before joining everything.

g=$*[0].split(/(?<=[a-j])(?!\+)/)               # Split into columns.
       .map{|r|                                 # For each column
            r.scan(/(\d*)(-\d+)?([a-j])/)       # Split into components.
             .map{|a,b,c|                       # For each component
                ' '*a.to_i+                     # Prepend spaces if any.
                '++--***...'[-b.to_i..c.ord-97] # Select the appropriate slice of the tower.
            }*''                                # Join all components together.
        }
puts g.map{|s|                                  # For each column
            s.ljust(g.map(&:size).max)          # Pad with spaces on the right such that. 
                                                # all columns are the same height.
            .chars.reverse                      # Turn into character array and reverse.
      }
      .transpose                                # Mirror in the main diagonal.
      .map(&:join)                              # Join lines.
      .join$/                                   # Join columns.
share|improve this answer
1  
+1 for calling this "fun" –  TheBlastOne Aug 21 at 7:48
    
Was trying out different styles of the final line and came out with: puts (0..z=g.map(&:size).max-1).map{|i|g.map{|y|(v=y[z-i])?v:?\ }*''}. But probably not so fun without the transpose. –  bitpwner Aug 22 at 16:27
    
@bitpwner Thanks, I'll have a look and test this later. –  Martin Büttner Aug 26 at 10:07

Cobra - 473

I don't think Cobra's ever going to win one of these :/

use System.Text.RegularExpressions
class P
    def main
        r=Regex.matches(Console.readLine,r'(?<=^|[a-j])(([^a-j]*[a-j])+?)(?=[^+]|$)')
        z,l=0String[](r.count)
        for m in r.count,for n in'[r[m]]'.split('+'),l[m]+=' '.repeat(int.parse('0[Regex.match(n,r'(?<!-)\d+')]'))+'++--***...'[int.parse('0[Regex.match(n,r'(?<=-)\d+')]'):' abcdefghij'.indexOf(n[-1:])]
        for y in l,if y.length>z,z=y.length
        for x in-z+1:1
            for y in l,Console.write(if(-x<y.length,y[-x],' '))
            print

All nice and commented:

EDIT: Just realized this looks suspiciously similar to the Ruby solution. Great minds think alike?

use System.Text.RegularExpressions
class P
    def main
        r=Regex.matches(Console.readLine,r'(?<=^|[a-j])(([^a-j]*[a-j])+?)(?=[^+]|$)')
        # Split into columns
        z,l=0,String[](r.count)
        # Assign the column-array
        for m in r.count
        # Loop through columns
            for n in'[r[m]]'.split('+')
            # Loop through individual letter instructions
            # - within columns
                l[m]+=
                # Add characters to the last column
                    ' '.repeat(int.parse('0[Regex.match(n,r'(?<!-)\d+')]'))+
                    # Any spaces, plus
                    '++--***...'[:' abcdefghij'.indexOf(n[-1:])]
                    # The default column string
                        [int.parse('0[Regex.match(n,r'(?<=-)\d+')]'):]
                        # Sliced to the right length
        for y in l,if y.length>z,z=y.length
        # Determine the maximum length of any column
        for x in-z+1:1
            for y in l
            # Loop through columns so that they rotate to the left
                Console.write(if(-x<y.length,y[-x],' '))
                # Write the character in the current position
            print
            # Insert newlines
share|improve this answer

Lua - 451

a=arg[1]j='++--***...'I=io.write M=string.match U=string.sub T=table.insert n=''y=0 t={}m=0 for i in a:gmatch('[%-%d]*[a-j]%+?')do b=M(i,'-(%d)')b=b or 0 s=M(U(i,1,1),'%d')s=s or 0 n=n..(' '):rep(s)..U(U(j,1,M(U(i,-2),'[a-j]'):byte()-96),1+b,-1)if U(i,-1,-1)~="+"then T(t,n)m=m<#n and #n or m n=""y=y+1 end end T(t,n)n=''for k,v in pairs(t)do n=#v<m and n..v..(' '):rep(m-#v)or n..v end for i=m,1,-1 do for k=0,m*y-1,m do I(U(n,i+k,i+k))end I'\n'end

Nothing special. It was fun to rename a butt-load of functions for once though. I'll edit the ungolfed code in later.

Try it out here. Sample Output:

SampleOutput

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.