Skip to main content
added 99 characters in body
Source Link
Cristian Lupascu
  • 8.7k
  • 2
  • 26
  • 52

The program can be run in Ruby 2.1.5+. Here's a version which includes unit testsTry it online: http://pastebin.com/a8KTatL1http://ideone.com/kIKELi (I added a #to_a call on the first line, because ideone.com uses Ruby 1.9.3, which does not support #size for Enumerables. In Ruby 2.1.5+ the code runs OK.)

The program can be run in Ruby 2.1.5+. Here's a version which includes unit tests: http://pastebin.com/a8KTatL1

Try it online: http://ideone.com/kIKELi (I added a #to_a call on the first line, because ideone.com uses Ruby 1.9.3, which does not support #size for Enumerables. In Ruby 2.1.5+ the code runs OK.)

Source Link
Cristian Lupascu
  • 8.7k
  • 2
  • 26
  • 52

Ruby 295

F=->i{l=i.lines g={} l.size.times{|y|i.size.times{|x|l[y][x]==?+&&g[[y,x]]=[[y,x]]}} c=->a,b{w=g[b]+g[a];w.map{|x|g[x]=w}} k=g.keys k.product(k).map{|n,o| r,p=n s,q=o ((r==s&&p<q&&l[r][p...q]=~/^\+-[|-]*$/)||(p==q&&r<s&&l[r...s].map{|l|l[p]||c}.join=~/^\+\|[|-]*$/))&&c[n,o]} g.values.uniq.size} 

The program can be run in Ruby 2.1.5+. Here's a version which includes unit tests: http://pastebin.com/a8KTatL1

The approach is the following:

  • make a list of all the + signs in the input and consider each of them a distinct shape
  • find horizontal and vertical lines that link two + signs and combine their shapes into one
  • in the end, the number of distinct shapes matches the result

Here's a more readable version:

def ascii_topology_count(input) lines = input.lines max_length = lines.map(&:size).max # hash in which the keys are corners ("+"s), represented by their [y, x] coords # and the values are arrays of corners, representing all corners in that group corner_groups = {} lines.size.times { |y| max_length.times { |x| if lines[y][x] == ?+ corner_groups[[y, x]] = [[y, x]] end } } # function that combines the groups of two different corners # into only one group combine_groups =-> c1, c2 { g1 = corner_groups[c1] g2 = corner_groups[c2] g2 += g1 corner_groups[c1] = g2 g2.map{|x| corner_groups[x] = g2} } corner_groups.keys.product(corner_groups.keys).map{|c1, c2| y1,x1=c1 y2,x2=c2 if y1 == y2 && x1 < x2 # test horizontal edge t = lines[y1][x1...x2] if t =~ /^\+-[|-]*$/ # p "#{c1}, #{c2}, [H] #{t}" combine_groups[c1, c2] end end if x1 == x2 && y1 < y2 # test vertical edge t=lines[y1...y2].map{|l|l[x1]||' '}.join if t =~ /^\+\|[|-]*$/ # p "#{c1}, #{c2}, [V] #{t}" combine_groups[c1, c2] end end } corner_groups.values.uniq.count end