Drawing in Slashes

23

Write a program that takes in a rectangular block of text made up of X's and .'s, such as this rough A:

......
..XX..
.X..X.
.XXXX.
.X..X.
.X..X.

Output a representation of this grid rotated 45 degrees counterclockwise by drawing a slash — forward or backward depending on context — everywhere an X borders a . or the side of the grid (with spaces filling in the rest):

 /\/\
/ /\ \
\/ /  \
/\/ /\ \
\  /  \/
 \ \
  \ \
   \/

The number of trailing and leading spaces (and newlines) doesn't matter as long as the shape of the X's in the input is maintained by the slashes. It's ok to trim extra rows or columns of .'s.

For I/O you may use any combination of stdin/stdout/files/command line parameters. For example your script might take in a file name of the X. pattern and rewrite the file with the slash pattern. Or your script might take in the X. pattern from stdin line by line (pressing d when done) and output the result to stdout.

The input may be arbitrarily large, but you may assume it is always well formatted.

No characters besides / \ and newlines should be in any output.

Scoring

The shortest code in bytes wins. Use https://mothereff.in/byte-counter as a byte counter if you use non-ASCII characters.

Bonus: Minus 50 bytes if you can change (replace, not remove) one character in your program so it outputs the slash grid rotated 45 degrees clockwise, e.g.:

   /\/\
  / /\ \
 /  \ \/
/ /\ \/\
\/  \  /
    / /
   / /
   \/

Input Samples

XXXXXXXXX
X.......X
X.XXXXX.X
X.X...X.X
X.X.X.X.X
X.X...X.X
X.XXXXX.X
X.......X
XXXXXXXXX

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...X
X...X...............X...............X...........X...................X...X
X...X...XXXXXXXXX...X...XXXXX...XXXXXXXXX...XXXXX...XXXXX...XXXXX...X...X
X...............X.......X...X...........X...........X...X...X.......X...X
XXXXXXXXX...X...XXXXXXXXX...XXXXXXXXX...XXXXX...X...X...X...XXXXXXXXX...X
X.......X...X...............X...........X...X...X...X...X...........X...X
X...X...XXXXXXXXXXXXX...X...X...XXXXXXXXX...XXXXX...X...XXXXXXXXX...X...X
X...X...............X...X...X.......X...........X...........X.......X...X
X...XXXXXXXXXXXXX...XXXXX...XXXXX...X...XXXXX...XXXXXXXXX...X...XXXXX...X
X...........X.......X...X.......X...X.......X...........X...X...........X
X...XXXXX...XXXXX...X...XXXXX...X...XXXXXXXXX...X...X...X...XXXXXXXXXXXXX
X.......X.......X...X...X.......X.......X.......X...X...X.......X.......X
XXXXXXXXXXXXX...X...X...X...XXXXXXXXX...X...XXXXX...X...XXXXX...XXXXX...X
X...........X...X...........X.......X...X.......X...X.......X...........X
X...XXXXX...X...XXXXXXXXX...XXXXX...X...XXXXX...XXXXX...XXXXXXXXXXXXX...X
X...X.......X...........X...........X.......X...X...X...............X...X
X...X...XXXXXXXXX...X...XXXXX...XXXXXXXXX...X...X...XXXXXXXXXXXXX...X...X
X...X...........X...X...X...X...X...........X...............X...X.......X
X...XXXXXXXXX...X...X...X...XXXXX...XXXXXXXXX...XXXXXXXXX...X...XXXXXXXXX
X...X.......X...X...X...........X...........X...X.......X...............X
X...X...XXXXX...XXXXX...XXXXX...XXXXXXXXX...XXXXX...X...XXXXXXXXX...X...X
X...X...................X...........X...............X...............X...X
X...XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

(maze source)

Related Questions:
Draw the Hilbert curve using slashes
Align a horizontally-aligned, right-angled ASCII shape along a diagonal

Calvin's Hobbies

Posted 2014-09-06T06:24:41.257

Reputation: 84 000

Is replacing the single character with a whitespace character (or a whitespace to a symbol) acceptable? – Reinstate Monica - ζ-- – 2014-09-06T16:39:19.627

@hexafraction Sure – Calvin's Hobbies – 2014-09-06T16:40:56.443

What we need is someone to answer this in itflabtijtslwi. Then we'd have "Drawing in Slashes in Slashes."

– Justin – 2014-09-06T23:43:04.850

Answers

10

Python 2 - 236, 228, 226, 221, 250, 248 246 - 50 = 196

s=input().split()
s=zip(*s[::-1])
X=len(s[0])+2
d=('.',)
B=[d*X]
s=B+[d+tuple(l)+d for l in s]+B
Y=len(s)
for x in range(X,-Y,-1):print' '*abs(x)+''.join(' \\'[s[y-1][x+y-1]!=s[y-1][x+y]]+' /'[s[y-1][x+y]!=s[y][x+y]]for y in range(1,Y)if 0<x+y<X)

I added the optional bonus feature that switches the direction from clockwise to counterclockwise. Basically, the second line simply rotates the input by 90 degrees. To switch between both options, replace s=zip(...) by something like S=zip(...) (i.e. assign to a variable that won't be used again).

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

                 /\           /\/\ 
                 \ \          \/\ \ 
               /\ \ \         /\ \/  
               \ \/  \     /\ \/   /\ 
             /\ \  /\ \    \ \/\  / /  
            / /  \ \ \/     \/\/ / /    
            \/    \ \           / /      
            /\/\/\ \/          / /        
            \/\/\/             \ \    /\/\ 
        /\/\    /\              \ \  / /\/  
        \/\ \  / /               \/ /  \/\   
        /\/  \ \/                  / /\  /    
        \  /\ \                    \/ / / /\/\ 
         \ \ \/                      / /  \/\ \ 
   /\     \ \                        \/   /\ \/  
   \ \     \/                          /\ \/   /\ 
 /\ \ \  /\                            \ \/\  / /  
/ /  \ \/ /                             \/\/ / / /\ 
\/    \  /                                  /  \/ /
/\/\/\ \/                                  / /\  /
\/\/\/                                     \/ / /
    /\                                       / /
   / /                                       \/
   \/

Falko

Posted 2014-09-06T06:24:41.257

Reputation: 5 307

You could save 5bytes by sandwiching s with B by s=B+s+B. – BeetDemGuise – 2014-09-07T00:06:42.037

1@BeetDemGuise: Thanks! That's so much easier! :) – Falko – 2014-09-07T07:04:53.757

7

MATLAB - 286 - 50 = 236

Minified:

S=input('');x=rot90(reshape(input('','s'),S),1);S=size(x);D=sum(S);[r,c]=ind2sub(S,find(x==88));A=zeros(D);f=@(o,p)sub2ind([D D],r+c+o-1,c-r+S(1)+p);A(f(1,1))=1;t=f(0,0);A(t)=A(t)+1;A(f(1,0))=3;t=f(0,1);A(t)=A(t)+3;fprintf('%s',char([(1-mod(A,2))*32+(A==1)*47+(A==3)*92,ones(D,1)*13]'))

Expanded:

S = input('');
x = rot90( reshape( input('','s'), S ), 1 );
S = size( x );
D = sum( S );
[r,c] = ind2sub( S, find( x==88 ) );
A = zeros( D );
f = @(o,p) sub2ind( [D D], r+c+o-1, c-r+S(1)+p );

A(f(1,1)) = 1;
t = f(0,0); A(t) = A(t)+1;
A(f(1,0)) = 3;
t = f(0,1); A(t) = A(t)+3;

fprintf( '%s', char( [(1-mod( A, 2 ))*32 + (A==1)*47 + (A==3)*92, ones( D, 1 )*13]' ) )

The code can be further reduced by 6 characters (to tie the current lead) by eliminating the cast to type char, but this results in a warning from MATLAB, and I wasn't sure if that was allowed.

It can be reduced by an additional 13 characters if the input is required to have a "marked up" format such as ['X..';'.X.';'..X'], but I didn't figure this was allowed either. Currently the script just accepts two numbers (row and column dimensions) and then reads in a single string of grid characters.

Bonus

By changing the 1 in the call x = rot90( ..., 1 ); to a 0, the transformation changes from a CCW 45° rotation to a CW 45° rotation. In fact, all possible 45° + n·90° rotations are possible by stepping this parameter from 0 to 3.

Sample Outputs:

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

                     /\    
                    / /    
                   / / /\  
                   \/ /  \ 
                   /\ \/\ \
                   \ \  / /
               /\   \ \/ / 
              / /    \/\/  
             / /           
             \/            
             /\    /\      
             \ \  / /      
              \ \/ /       
        /\/\   \/\/        
       / /\/               
      / / /\               
      \ \/ /               
       \  /                
        \ \                
  /\/\   \ \               
 / /\/    \/               
/ / /\                     
\ \/ /                     
 \  /                      
  \ \                      
   \ \                     
    \/                     

    /\                     
   /  \                    
  / /\ \                   
 /  \ \/                   
/ /\ \/\                   
\/  \/\/                   
          /\               
         /  \              
        / /\ \             
       /  \ \/             
      / /\ \/\             
      \/  \/\/             

               /\/\        
              / /\ \       
             / /  \ \      
             \/    \/      
             /\            
             \ \           
              \ \    /\/\  
               \/   / /\ \ 
                   / /  \ \
                   \/ /\ \/
                   /\ \ \  
                   \ \/ /  
                    \  /   
                     \/    

COTO

Posted 2014-09-06T06:24:41.257

Reputation: 3 701

3

Perl - 409

while(<>){$a[$.]=[/./g]}$l=$#a<($g=@{$a[1]})?$#a:$g;$r=$#a+$g-1;for$d(1..$r){for$e(1..$l){if(($b=$a[$c=($d>$g?$d-$g:0)+$e][$n=-($d-$c+1)])&&$n<0){$h[$d][$e]=$b;}}$h[$d]=[(0)x(($l-{@$h[$d]})/2),@{$h[$d]}];}sub z{"\0"x((reverse(1..$g),(2..$r-$g+1))[int($q++/2)-1]).join'',map{$_ eq'X'?($q%2?'/\\':'\/'):"\0\0"}@_}@i="\0"x2x$l;for$f(@h){$i[$#i]=(z@$f)^$i[$#i];$i[$#i+1]=z@$f}for$j(@i){print$j=~s/[\0s]/ /gr."\n"}

Reads from stdin and prints to stdout.

Example outputs:

XXX
X..
XXX
..X
XXX

     /\
    / / 
   / / /\
   \ \/  \
    \  /\ \
     \/ / /
       / /
       \/

XXXXXXXXX
X........
X.XXXXXXX
X.X.....X
X.X..X..X
X.XXXX..X
X...X...X
XXXXXXXXX
           /\
          / / 
         / / /\
        / / /  \
       / / / /\ \
      / / / /  \ \
     / / / /    \ \
    / / / / /\   \ \
   / / / /  \ \  / /
   \ \ \ \  / / / /
    \ \ \ \/  \/ /
     \ \ \  /\  /
      \ \ \/ / /
       \ \  / /
        \ \/ /
         \  /
          \/

faubi

Posted 2014-09-06T06:24:41.257

Reputation: 2 599