ASCII art 3D StreetView

29

4

Input:

  1. You get a series of integers (fed via stdin or prompt).
  2. Every pair of integers in this series represents a building's WIDTH [valid range: 1..10] and HEIGHT [valid range: 0..10]
  3. Assume input to be well-formed.

Sample input (the second line is for demonstration purposes only):

1 2 1 1 1 0 2 4 1 3 1 2 2 1
W H W H W H W H W H W H W H

Corresponding sample output:

                 ______
               /______ /|
              |       | |__
              |       |/__ /|
     __       |       |   | |__
   /__ /|     |       |   |/__ /|  
  |   | |__   |       |   |   | |______
  |   |/__ /| |       |   |   |/______ /|
  |   |   | |_|       |   |   |       | |
  |_o_|_o_|/__|_o_____|_o_|_o_|_o_____|/
  -------------------------------------  
 -  -  -  -  -  -  -  -  -  -  -  -  - 
-------------------------------------

Rules:

The buildings

  1. A basic building block looks like this (1 W, 1H)
   __
 /__ /| (base cube is borrowed from the one at this question:
|   | |  http://stackoverflow.com/questions/1609702/code-golf-playing-cubes)
|___|/
  1. Our view is (ahum) ~3D so neighbouring buildings may hide parts of others. Buildings are 'logically' rendered from left to right.

  2. The first building is preceded by two spaces to it's left.

  3. You render every building by applying the WIDTH and HEIGHT to the dimensions of the base cube (do have a look at the sample output provided!). For reference: number of characters from the left to the right 'wall' (for a building with W > 1): (W*5)-(W-1).

  4. Buildings with Height > 0 have ONE door (which is depicted by the character o and is located at two characters from the 'left' wall on the 'bottom' row ).

The road:

  1. The road consists of three parts which we'll call 'top', 'middle' and 'bottom'.
  2. The 'top' part and 'bottom' part are identical apart from the fact that the 'top' part is preceded by two spaces.
  3. The middle part is preceded by one space and consists of a repetition of the following pattern:
    '-  '
  4. Length is to be determined by the total width of the combined buildings: the most rightmost part of the road corresponds with the position of the 'right' wall of the 'last' building.

Winners:

This is code-golf! The winner is the qualifying contestant with the shortest solution (by source code count). The source must consist solely of printable ASCII characters. Have fun!

Imaginary bonus points for (random) windows, cars or pedestrians.

Feel free to comment if the specifications are not clear!

ChristopheD

Posted 2012-01-18T16:25:36.537

Reputation: 1 599

@user unknown: there was indeed a small typo in the rules indeed. Should be fixed now, thanks! – ChristopheD – 2012-01-18T16:36:48.407

Trailing whitespace permitted? You seem to have some in the example, so I assume so. – Peter Taylor – 2012-01-18T16:59:06.160

@Peter Taylor: trailing whitespace is allowed. – ChristopheD – 2012-01-18T17:21:08.397

Road part 3, should that be '-  ' (with two spaces)? Edit: Ah, the two spaces don't show :P. You can display multiple spaces by using ASCII 255 (non-breaking space, ALT+255 on numpad), or by copying and pasting from my comment here. Orr... you could instead just say it's a repetition of ' - ' :) – mellamokb – 2012-01-18T18:52:11.677

It looks like the height valid range is actually [0..10]. Also what do you mean by but you must not enforce this in 3)? IMO, any assumption is available to be exploited if it increases your score. So I may write code that only works if the total width is less than 80 if I can squeeze out a lower character count. For example, writing output to a display buffer array with a width of 80, so it will crash on any higher total width. If you want any width supported, then don't give the assumption - you can't have both :P – mellamokb – 2012-01-18T19:00:56.123

@mellamokb: thanks for commenting! (spaces and range fixed). You may write code that only works if the total width is less than 80, that was what I was trying to convey. But you are right, I'll delete part of the assumption. – ChristopheD – 2012-01-18T19:08:57.647

Answers

10

Haskell, 396 characters

w&h=take h((3," /|"++(w-3)#'_'++"o_|"):c[(3,"| |"++(w-1)#s++"|")])++[(2,"|/ "++(w-2)#'_'++"/"),(0,"  "++(w-2)#'_')]++c[(0,w#s)]
p(w,h)=r.z take[sum w+k|k<-[1..]]$([c"-",s:c"-  ","  "++c"-"]++).map r.foldl(z(%))((2+maximum h)#(5#s))$z(&)w h
main=interact$unlines.p.q.map read.words;y%(d,x)=x++drop d y;q(x:y:z)=(4*x:a,2*y:b)where(a,b)=q z
q x=(x,x);(#)=replicate;c=cycle;r=reverse;z=zipWith;s=' '

Example output:

$ runghc Streetview.hs <<< "1 1 1 3 1 2 1 0 2 4 2 2 1 3 3 1"
                     ______                          
                   /______ /|                        
         __       |       | |        __              
       /__ /|     |       | |      /__ /|            
      |   | |__   |       | |_____|   | |            
      |   |/__ /| |       |/______|   | |            
     _|   |   | | |       |       |   | |__________  
   /__|   |   | | |       |       |   |/__________ /|
  |   |   |   | |_|       |       |   |           | |
  |_o_|_o_|_o_|/__|_o_____|_o_____|_o_|_o_________|/
  -------------------------------------------------
 -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
-------------------------------------------------

hammar

Posted 2012-01-18T16:25:36.537

Reputation: 4 011

5+1 Your recent haskell submissions on codegolf.se have triggered an interest in me for learning a bit more about haskell. Short as the solutions may be, they still remain quite 'readable' imho. – ChristopheD – 2012-01-19T22:45:07.880

8

Python, 415 chars

I=eval(raw_input().replace(' ',','))
X=I[::2]
Y=I[1::2]
W=4*sum(X)+6
H=2*max(Y)+2
A=W*H*[' ']
p=W*H-W+2
for w,h in zip(X,Y):i=2*h;j=4*w;q=p-i*W;r=p+j;s=q+j;A[p+1:q+1:-W]=A[p+2:q+2:-W]=i*' ';A[p:q:-W]=A[r:s:-W]=A[r+2-W:s+2-W:-W]=i*'|';A[p+1:r]='_'*(j-1);A[q+2:s]=A[q+3-W:s+1-W]='_'*(j-2);A[q+1]=A[s+1]=A[r+1]='/';A[p+2]='_o'[h>0]; p+=j
A[W-1::W]='\n'*H
D=(W-5)*'-'
print''.join(A)+'  '+D+'\n'+(' - '*W)[:W-4]+'\n'+D

Uses slices to draw all the parts of the building.

$ echo "1 2 1 1 1 0 2 4 1 3 1 5 2 1" | ./streetview.py 
                             __          
                           /__ /|        
                 ______   |   | |        
               /______ /| |   | |        
              |       | |_|   | |        
              |       |/__|   | |        
     __       |       |   |   | |        
   /__ /|     |       |   |   | |        
  |   | |__   |       |   |   | |______  
  |   |/__ /| |       |   |   |/______ /|
  |   |   | |_|       |   |   |       | |
  |_o_|_o_|/__|_o_____|_o_|_o_|_o_____|/ 
  -------------------------------------
 -  -  -  -  -  -  -  -  -  -  -  -  -
-------------------------------------

Keith Randall

Posted 2012-01-18T16:25:36.537

Reputation: 19 865

+1 Very nice. The solution looks pretty golfed already ;-) – ChristopheD – 2012-01-19T22:44:00.643

2There's one lost space at p+=j (@the end of the long line). Not sure if you counted that one ;-) – ChristopheD – 2012-01-19T22:47:05.597