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\$
3
  • \$\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, 2016 at 0:01
  • \$\begingroup\$ @randomra you have t connect every legal pair, they won't always be 1 component \$\endgroup\$
    – Downgoat
    Feb 13, 2016 at 0:02
  • \$\begingroup\$ @Downgoat How about some more test cases that cover disconnected components and loops within a single component then? ;) \$\endgroup\$ Feb 13, 2016 at 13:07

3 Answers 3

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\$
3
  • 4
    \$\begingroup\$ Alright, I'll input as a padded rectangle, but only because you asked so nicely. \$\endgroup\$
    – Alex A.
    Feb 13, 2016 at 1:07
  • \$\begingroup\$ Can you use \b instead of (?=o)? \$\endgroup\$
    – Justin
    Feb 13, 2016 at 2:54
  • \$\begingroup\$ @Justin Doesn't appear to work. :/ \$\endgroup\$
    – Doorknob
    Feb 13, 2016 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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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