23
\$\begingroup\$

You should write a program or function which receives a block of chars represented as a string and outputs or returns a similar string in which the letters adjacent in the alphabet are connected.

A visual example (in the form of input => output):

b     d               b     d        
                      |\   /|        
                      | \ / |        
             =>       |  X  |        
                      | / \ |        
      e               |/   \e        
c     a               c     a        

Details

  • Input will be a string containing spaces, newlines and exactly one of each of the first N lowercase letters. 1 <= N <= 26
  • The lines of the input will be padded with spaces creating a full rectangular block.
  • Every pair of letters adjacent in the alphabet will be on the same row, column or diagonal line and should be connected with a straight ascii line using \ / | or -. (The line might have a length of 0.)
  • The following types of two-line overlaps should be handled:

    / and \ become X
    | and - become +
    / and / become /
    \ and \ become \
    | and | become |
    - and - become -
    [letter] and [anything] become [letter]
    
  • No other kind of two-line overlap will occur.

  • If more than two lines overlap any pair of them will be guaranteed to be one of the valid overlaps. (e.g. [letter] / | triplet will never occur)
  • Apart from changing spaces into \ / | - X and + input and output should be identical.
  • Trailing newline is optional but have to be the same for input and output.
  • This is code-golf so the shortest entry wins.

Examples

Input:

b     d        


     h   gi    

      e  f     
c     a        

Output:

b     d        
|\   /|        
| \ / |        
|  X h+--gi    
| / \ |  |     
|/   \e--f     
c     a        

Input:

     dk    j   

 b    l        

 c   fg        

     a    m    

   i      h    
     e         

Output:

     dk----j   
    /||   /    
 b / |l  /     
 |X  | \/      
 c \ fg/\      
    \|/\ \     
     a  \ m    
    /|   \     
   i-+----h    
     e         

Input:

   eti  sqjh k  p  u  cfm vb owgzyx rnd la  

Output:

   eti--sqjh-k--p--u--cfm-vb-owgzyx-rnd-la  

Input:

a

Output:

a
\$\endgroup\$
  • \$\begingroup\$ really nice ascii art \$\endgroup\$ – Optimizer Apr 13 '15 at 16:22
  • 2
    \$\begingroup\$ What if both a X and + overlap should be in the same spot? Or is that not a case we should account for? \$\endgroup\$ – theonlygusti Apr 13 '15 at 17:18
  • \$\begingroup\$ @theonlygusti "If more than two lines overlap any pair of them will be one of the valid overlaps" As e.g. / and - are invalid overlaps X and + (/ \ - and |) can't occur at the same position. \$\endgroup\$ – randomra Apr 13 '15 at 17:46
  • \$\begingroup\$ Still confused; why not give us some examples? \$\endgroup\$ – theonlygusti Apr 13 '15 at 18:02
  • \$\begingroup\$ @theonlygusti: Basically, it's not a case you should account for \$\endgroup\$ – Claudiu Apr 13 '15 at 18:41
3
\$\begingroup\$

Perl, 219

Some improvements may be still possible.

#!perl -p0
/
/;$x="@-";
sub g{map"(?=$_)(.@_)+[".chr(1+ord).chr(~-ord)."]",a..z}
sub f{for$p(g"{$x}"){s/$p/$&&((_."\177"x~-$x)x y!
!!)/se;$_=lc;s![\0\\]!@_!g}$x++}
f"/";y!\17!/!;f"|";f"\\";y/\17/X/;for$p(g){s/$p/$&=~y! |!-+!r/e}

Try me.

\$\endgroup\$
6
\$\begingroup\$

JavaScript (ES6) 246 266 280 285 307

Quite bulky ...

A function with string param and returning the modified string. A trailing newline is optional unless the input is just 1 row (I need a newline to find the row len)

Just to make someone happy

F=b=>b.match(/\w/g).sort().map(l=>(q=b.indexOf(l),~p)?[o=b.indexOf('\n'),~o,o+2,1].map((d,i)=>{k=(q-p)/d|0;if(k&&k*d+p==q)for(m='/|\\-'[i];(p+=k>0?d:-d)-q;c==m|c>'`'&c<'{'?0:b[p]=c>' '?c<'/'|c>'z'?'+':'X':m)c=b[p]}):p=q,p=-1,b=[...b])&&b.join('')

More readable

F=b=>
  b.match(/\w/g).sort().map(l=>
    (q=b.indexOf(l),~p)?
    [o=b.indexOf('\n'),~o,o+2,1].map((d,i)=>{
      k=(q-p)/d|0;
      if(k&&k*d+p==q)
        for(m='/|\\-'[i];
              (p+=k>0?d:-d)-q;
              c==m|c>'`'&c<'{'?0:b[p]=c>' '?c<'/'|c>'z'?'+':'X':m)
            c=b[p]
    })
    :p=q
  ,p=-1,b=[...b])
  &&b.join('')

Test In Firefox/FireBug console

console.log(F('\
b     d\n\
       \n\
       \n\
       \n\
       \n\
      e\n\
c     a\n'))

console.log(F('\
     dk    j\n\
            \n\
 b    l     \n\
            \n\
 c   fg     \n\
            \n\
     a    m \n\
            \n\
   i      h \n\
     e      \n'))

console.log(F('\
b     d    \n\
           \n\
           \n\
     h   gi\n\
           \n\
      e  f \n\
c     a    \n'))

Output

b     d
|\   /|
| \ / |
|  X  |
| / \ |
|/   \e
c     a

     dk----j
    /||   / 
 b / |l  /  
 |X  | \/   
 c \ fg/\   
    \|/\ \  
     a  \ m 
    /|   \  
   i-+----h 
     e      

b     d    
|\   /|    
| \ / |    
|  X h+--gi
| / \ |  | 
|/   \e--f 
c     a    
\$\endgroup\$
  • \$\begingroup\$ I count 341 chars. \$\endgroup\$ – mbomb007 Apr 16 '15 at 20:14
  • \$\begingroup\$ @mbomb007 don't count indentation whitespace and newlines \$\endgroup\$ – edc65 Apr 16 '15 at 20:16

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.