# frozen_string_literal: true
class Slide
attr_accessor :dirs
def initialize(field, dirs)
@field = field.split.map { |s| s.split('') }
@dirs = optimise(dirs.gsub(/[LR]+(?<m>[LR])|[UD]+(?<m>[UD])/, '\k<m>'))
end
def to_s
@field.map(&:join).join($/)
end
def incline_all
@dirs.each_char do |c|
case c
when ?L, ?R then incline(c)
else
rotate(:+)
incline({?U => ?L, ?D => ?R}[c])
rotate(:-)
end
end
end
private
def optimise(dirs)
s = dirs.gsub(/(?<m>.).\k<m>(?=.)|(?<m>(?<n>.).)\k<n>\z/, '\k<m>')
s == dirs ? s : optimise(s)
end
def incline(dir)
@field = @field.map do |a|
f = case dir
when ?R then ->c{c == ?.}
when ?L then ->c{c != ?.}
end
a.partition { |c| f[c] }.flatten
end
end
def rotate(dir)
ary = @field.transpose
@field = case dir
when :+ then ary.reverse
when :- then ary.map(&:reverse)
end
end
end
samples = [[<<~EOT, 'UR'], [<<~EOT, 'LRRLLUDRRLRLRRURRRRLLLRULDUDULDLLRDULURULUDLDLUDDL']]
...
.a.
...
EOT
.....
.d.i.
kmegk
..tu.
EOT
samples.each do |field, dirs|
s = Slide.new(field, dirs)
s.incline_all
puts "%s%s optimised => %s\n%s\n\n" % [field, dirs, s.dirs, s]
end
IyBmcm96ZW5fc3RyaW5nX2xpdGVyYWw6IHRydWUKCmNsYXNzIFNsaWRlCiAgYXR0cl9hY2Nlc3NvciA6ZGlycwogIAogIGRlZiBpbml0aWFsaXplKGZpZWxkLCBkaXJzKQogICAgQGZpZWxkID0gZmllbGQuc3BsaXQubWFwIHsgfHN8IHMuc3BsaXQoJycpIH0KICAgIEBkaXJzID0gb3B0aW1pc2UoZGlycy5nc3ViKC9bTFJdKyg/PG0+W0xSXSl8W1VEXSsoPzxtPltVRF0pLywgJ1xrPG0+JykpCiAgZW5kCiAgCiAgZGVmIHRvX3MKICAgIEBmaWVsZC5tYXAoJjpqb2luKS5qb2luKCQvKQogIGVuZAogIAogIGRlZiBpbmNsaW5lX2FsbAogICAgQGRpcnMuZWFjaF9jaGFyIGRvIHxjfAogICAgICBjYXNlIGMKICAgICAgd2hlbiA/TCwgP1IgdGhlbiBpbmNsaW5lKGMpCiAgICAgIGVsc2UKICAgICAgICByb3RhdGUoOispCiAgICAgICAgaW5jbGluZSh7P1UgPT4gP0wsID9EID0+ID9SfVtjXSkKICAgICAgICByb3RhdGUoOi0pCiAgICAgIGVuZAogICAgZW5kCiAgZW5kCiAgCiAgcHJpdmF0ZQogIAogIGRlZiBvcHRpbWlzZShkaXJzKQogICAgcyA9IGRpcnMuZ3N1YigvKD88bT4uKS5cazxtPig/PS4pfCg/PG0+KD88bj4uKS4pXGs8bj5cei8sICdcazxtPicpCiAgICBzID09IGRpcnMgPyBzIDogb3B0aW1pc2UocykKICBlbmQKICAKICBkZWYgaW5jbGluZShkaXIpCiAgICBAZmllbGQgPSBAZmllbGQubWFwIGRvIHxhfAogICAgICBmID0gY2FzZSBkaXIKICAgICAgICAgIHdoZW4gP1IgdGhlbiAtPmN7YyA9PSA/Ln0KICAgICAgICAgIHdoZW4gP0wgdGhlbiAtPmN7YyAhPSA/Ln0KICAgICAgICAgIGVuZAogICAgICBhLnBhcnRpdGlvbiB7IHxjfCBmW2NdIH0uZmxhdHRlbgogICAgZW5kCiAgZW5kCiAgCiAgZGVmIHJvdGF0ZShkaXIpCiAgICBhcnkgPSBAZmllbGQudHJhbnNwb3NlCiAgICBAZmllbGQgPSBjYXNlIGRpcgogICAgICAgICAgICAgd2hlbiA6KyB0aGVuIGFyeS5yZXZlcnNlCiAgICAgICAgICAgICB3aGVuIDotIHRoZW4gYXJ5Lm1hcCgmOnJldmVyc2UpCiAgICAgICAgICAgICBlbmQKICBlbmQKZW5kCgpzYW1wbGVzID0gW1s8PH5FT1QsICdVUiddLCBbPDx+RU9ULCAnTFJSTExVRFJSTFJMUlJVUlJSUkxMTFJVTERVRFVMRExMUkRVTFVSVUxVRExETFVEREwnXV0KICAuLi4KICAuYS4KICAuLi4KRU9UCiAgLi4uLi4KICAuZC5pLgogIGttZWdrCiAgLi50dS4KRU9UCgpzYW1wbGVzLmVhY2ggZG8gfGZpZWxkLCBkaXJzfAogIHMgPSBTbGlkZS5uZXcoZmllbGQsIGRpcnMpCiAgcy5pbmNsaW5lX2FsbAogIHB1dHMgIiVzJXMgb3B0aW1pc2VkID0+ICVzXG4lc1xuXG4iICUgW2ZpZWxkLCBkaXJzLCBzLmRpcnMsIHNdCmVuZAo=