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\$
5
  • \$\begingroup\$ really nice ascii art \$\endgroup\$
    – Optimizer
    Apr 13, 2015 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\$
    – minseong
    Apr 13, 2015 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, 2015 at 17:46
  • \$\begingroup\$ Still confused; why not give us some examples? \$\endgroup\$
    – minseong
    Apr 13, 2015 at 18:02
  • \$\begingroup\$ @theonlygusti: Basically, it's not a case you should account for \$\endgroup\$
    – Claudiu
    Apr 13, 2015 at 18:41

2 Answers 2

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\$
2
  • \$\begingroup\$ I count 341 chars. \$\endgroup\$
    – mbomb007
    Apr 16, 2015 at 20:14
  • \$\begingroup\$ @mbomb007 don't count indentation whitespace and newlines \$\endgroup\$
    – edc65
    Apr 16, 2015 at 20:16
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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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