13
\$\begingroup\$

Given a series of os representing dots, connect them vertically or horizontally

Examples

Input:

o   o

o

Output:

o---o
|
|
o

Input:

o   o    o

    o

Output:

o---o----o
    |
    o

Spec

  • If you want the input padded with spaces to form a rectangle, please specify this in your answer

  • There will only be o, spaces, and newlines in the input

  • There will always be a pair of dots to connect
  • No two os will be directly adjacent
  • Dots should be connected with | and -, for vertical and horizontal connections respectively
  • No dot connections will overlap
\$\endgroup\$
  • \$\begingroup\$ Do you have to connect every legal pair or just connect the dots into 1 component? Can the dots always be connected into 1 component? "There will always be at least two dots to connect" would make more sense if I understand it right. A couple test cases could clear these up too. \$\endgroup\$ – randomra Feb 13 '16 at 0:01
  • \$\begingroup\$ @randomra you have t connect every legal pair, they won't always be 1 component \$\endgroup\$ – Downgoat Feb 13 '16 at 0:02
  • \$\begingroup\$ @Downgoat How about some more test cases that cover disconnected components and loops within a single component then? ;) \$\endgroup\$ – Martin Ender Feb 13 '16 at 13:07
2
\$\begingroup\$

Japt, 33 29 bytes

Uy eV="o +o"_rS'|} y eV,_rS'-

Test it online!

How it works

Uy         // Transpose rows with columns in the input.
eV="o +o"  // Set V to the regex-string "o +o", and recursively replace each match Z with:
_rS'|}     //  Z with spaces replaced with "|"s.
y          // Transpose again.
eV,        // Recursively replace matches Z of V with:
_rS'-      //  Z with spaces replaced with "-"s.
\$\endgroup\$
2
\$\begingroup\$

Ruby, 137 133 bytes

->s{eval"s.split($/).map(&:chars)#{".map{|x|x.join.gsub(/o +(?=o)/){|x|x.tr' ',?|}.chars}.transpose"*2}.map(&:join)*$/".sub'?|','?-'}

This is absolutely horrible. Still trying to golf.

Input as a padded rectangle, please.

Newline for "readability":

eval"s.split($/).map(&:chars)#{".map{|x|x.join.gsub(/o +(?=o)/){|x|x.tr' ',?|}
.chars}.transpose"*2}.map(&:join)*$/".sub'?|','?-'
\$\endgroup\$
  • 4
    \$\begingroup\$ Alright, I'll input as a padded rectangle, but only because you asked so nicely. \$\endgroup\$ – Alex A. Feb 13 '16 at 1:07
  • \$\begingroup\$ Can you use \b instead of (?=o)? \$\endgroup\$ – Justin Feb 13 '16 at 2:54
  • \$\begingroup\$ @Justin Doesn't appear to work. :/ \$\endgroup\$ – Doorknob Feb 13 '16 at 4:06
2
\$\begingroup\$

Retina, 80 bytes

T` `-`o.+o
Tm` `|`(?<=(?(1)!)^(?<-1>.)*o\D*¶(.)*) (?=(.)*¶\D*o(?<-2>.)*$(?(2)!))

Input needs to be padded.

Try it online!

Explanation

The first stage is pretty simple, it just turns all spaces into hyphens which are found between two os in the same line.

The second stage covers the |s. This is a bit trickier and requires balancing groups. The lookbehind

(?<=(?(1)!)^(?<-1>.)*o\D*¶(.)*)

checks that there's an o earlier in the same column. Remember that lookbehinds should be read from right to left. (.)* stores the horizontal position of match, \D*¶ checks skips to any character in the preceding lines, o matches literally. Then (?(1)!)^(?<-1>.)* ensures that the horizontal position of that o is the same.

The lookahead

(?=(.)*¶\D*o(?<-2>.)*$(?(2)!))

Does exactly the same thing in the opposite direction.

\$\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.