23
\$\begingroup\$

Input:

1
      X                                
      X                                
      X                                
      X      XX    XXXXXX     X X X    
      X      XX    XXXXXX     X X X    
XXX   X      XX    XXXXXX     X X X    
XXX   X      XX    XXXXXX     X X X    

Output:

      X.                               
      X..                              
      X...                             
      X....  XX.   XXXXXX.    X.X.X.   
      X..... XX..  XXXXXX..   X.X.X..  
XXX.  X......XX... XXXXXX...  X.X.X... 
XXX.. X......XX....XXXXXX.... X.X.X....

Input:

2
         XX
         XX
         XX
         XX
         XX
     XX  XX
     XX  XX
     XX  XX
     XX  XX

Output:

        .XX
       ..XX
      ...XX
     ....XX
    .....XX
   ..XX..XX
  ...XX..XX
 ....XX..XX
.....XX..XX

Specification:

  • You must take as input
    1. A flag signifying whether the light is coming from the top left or top right. This can be 1 or 2, -1 or 1, 0 or 65536, or whatever is convenient for you, as long as both flags are integers.
    2. Rows composed of either X or , all of the same length in characters (i.e. padded with )
      • All Xs will either be on the last row or have an X under them (meaning no floating buildings)
  • You must output the rows (buildings) with shadows added. This is done with the following procedure:
    • If the light is coming from the top left, draw a right triangle of .s with the same height and width as the height of the building, starting from one space past its right edge and going rightwards.
    • Otherwise, if it's from the top right, do the same thing but start from one space past its left edge and pointing left.
    • Remember, do not alter Xs by changing them to .s; leave them as they are.
    • There will always be "room" for your shadows, i.e. if there's a 3-space tall building at the end there will be at least 3 spaces of padding after it.
  • This is , so the shortest code in bytes will win!
\$\endgroup\$
  • 1
    \$\begingroup\$ Can I use {} and {-1*} as flag values? \$\endgroup\$ – John Dvorak Apr 20 '14 at 7:28
  • \$\begingroup\$ @Jan Yes, yes you can. You could even use potato and while(1){}. As quoted in the question, "whatever is convenient." \$\endgroup\$ – Doorknob Apr 20 '14 at 11:48
  • 2
    \$\begingroup\$ :( I was going to solve this in (.NET-flavoured) regex, but I think I found a bug in Regex.Replace which I can't work around... do I have two problems now? \$\endgroup\$ – Martin Ender Apr 20 '14 at 12:18
  • 3
    \$\begingroup\$ @Doorknob Someone is going to abuse this rule to just have their entire code in the input. \$\endgroup\$ – ɐɔıʇǝɥʇuʎs Apr 20 '14 at 14:04
  • 2
    \$\begingroup\$ @Synthetica That is one of the "standard loopholes." \$\endgroup\$ – Doorknob Apr 20 '14 at 14:06
6
\$\begingroup\$

GolfScript, 67 characters

n%(~:S\zip\%.0=\{.' '3$);+{{\(@[\].~<=}%+}:M~'X'/'.'*@@M}%S%zip\;n*

1/-1 for shadows going right/left. Run the example online:

      X.                               
      X..                              
      X...                             
      X....  XX.   XXXXXX.    X.X.X.   
      X..... XX..  XXXXXX..   X.X.X..  
XXX.  X......XX... XXXXXX...  X.X.X... 
XXX.. X......XX....XXXXXX.... X.X.X....
\$\endgroup\$
11
\$\begingroup\$

Perl - 85

BEGIN{$d=-<>}$d?s/X /X./g:s/ X/.X/g;s/ /substr($p,$+[0]+$d,1)eq'.'?'.':$&/ge;$p=$_;

EDIT: I totally forgot about the -p flag this needs to be run with. Added 2 to char count.
The flag specified at the first line is 0 for shadows going left and 2 for shadows going right.

\$\endgroup\$
4
\$\begingroup\$

Python 3 - 233

Well, that turned out longer than expected...

1 for shadows going right, -1 for shadows going left.

d,x=int(input()),[1]
while x[-1]:x+=[input()]
x,o,l,h=list(zip(*x[1:-1]))[::d],[],0,len(x)-1
for i in x:o+=[''.join(i[:len(i)-l])+''.join(i[len(i)-l:]).replace(' ','.')];l=max(l-1,i.count('X'))
for i in zip(*o[::d]):print(''.join(i))

EDIT: Didn't see the either side padding in the rules. Ehehe. ^^'

\$\endgroup\$
3
\$\begingroup\$

JavaScript - 14

eval(prompt())

The flag on the first line is for(p='';l=prompt();)console.log(p=l.replace(/ /g,function(a,b){return p[b+1]=='.'||p[b]=='.'||l[b+1]=='X'?'.':a})); for shadows facing the left or for(p='';l=prompt();)console.log(p=l.replace(/ /g,function(a,b){return p[b-1]=='.'||p[b]=='.'||l[b-1]=='X'?'.':a})); for shadows to the right.

This might abuse the "whatever is convenient for you" rule for the flag :P


Edit: without abuse (127):

c=prompt();for(p='';l=prompt();)console.log(p=l.replace(/ /g,function(a,b){return p[b+c]=='.'||p[b]=='.'||l[b+c]=='X'?'.':a}));

The flag for this is 1 or -1

\$\endgroup\$
  • \$\begingroup\$ Fine, I fixed the rules. :-P \$\endgroup\$ – Doorknob Apr 20 '14 at 21:45
  • \$\begingroup\$ Aaww, that's no fun :-( This does make "both flags are integers" conflict with your comment "You could even use potato...", unless potato is an integer. :-P \$\endgroup\$ – Zaq Apr 20 '14 at 21:51
  • \$\begingroup\$ c=+prompt() or else b+c will concatenate as a string. \$\endgroup\$ – nderscore Apr 21 '14 at 2:05
  • \$\begingroup\$ Optimized a few things and got this down to 119: for(c=p=+(P=prompt)(d='.');l=P();)console.log(p=l.replace(/ /g,function(a,b){return p[b]==d|p[b+=c]==d|l[b]=='X'?d:a})) (demo) \$\endgroup\$ – nderscore Apr 21 '14 at 2:24
  • \$\begingroup\$ Save another byte on converting c to a number by subtracting instead. b-c or b-=c in my code above. (demo) \$\endgroup\$ – nderscore Apr 21 '14 at 2:40
1
\$\begingroup\$

Python 2.7 - 229

p,s,M,J,L=input(),__import__('sys').stdin.readlines(),map,''.join,len
n,s,r,f=L(s),M(str.strip,M(J,zip(*s[::-1]))),0,[]
for l in s[::p]:f,r=f+[(l+'.'*(r-L(l))+' '*n)[:n]],max(r-1,L(l))
print'\n'.join(M(J,zip(*f[::p])[::-1]))

Ungolfed Version

def shadow(st, pos):
    _len = len(st)
    st = map(str.strip, map(''.join,zip(*st[::-1])))
    prev = 0
    res = []
    for line in st[::[1,-1][pos-1]]:
        res +=[(line+'.'*(prev-len(line)) + ' '*_len)[:_len]]
        prev = max(prev - 1, len(line))
    return '\n'.join(map(''.join,zip(*res[::[1,-1][pos-1]])[::-1]))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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