fork download
  1. # frozen_string_literal: true
  2.  
  3. class Slide
  4. attr_accessor :dirs
  5.  
  6. def initialize(field, dirs)
  7. @field = field.split.map { |s| s.split('') }
  8. @dirs = optimise(dirs.gsub(/[LR]+(?<m>[LR])|[UD]+(?<m>[UD])/, '\k<m>'))
  9. end
  10.  
  11. def to_s
  12. @field.map(&:join).join($/)
  13. end
  14.  
  15. def incline_all
  16. @dirs.each_char do |c|
  17. case c
  18. when ?L, ?R then incline(c)
  19. else
  20. rotate(:+)
  21. incline({?U => ?L, ?D => ?R}[c])
  22. rotate(:-)
  23. end
  24. end
  25. end
  26.  
  27. private
  28.  
  29. def optimise(dirs)
  30. s = dirs.gsub(/(?<m>.).\k<m>(?=.)|(?<m>(?<n>.).)\k<n>\z/, '\k<m>')
  31. s == dirs ? s : optimise(s)
  32. end
  33.  
  34. def incline(dir)
  35. @field = @field.map do |a|
  36. f = case dir
  37. when ?R then ->c{c == ?.}
  38. when ?L then ->c{c != ?.}
  39. end
  40. a.partition { |c| f[c] }.flatten
  41. end
  42. end
  43.  
  44. def rotate(dir)
  45. ary = @field.transpose
  46. @field = case dir
  47. when :+ then ary.reverse
  48. when :- then ary.map(&:reverse)
  49. end
  50. end
  51. end
  52.  
  53. samples = [[<<~EOT, 'UR'], [<<~EOT, 'LRRLLUDRRLRLRRURRRRLLLRULDUDULDLLRDULURULUDLDLUDDL']]
  54. ...
  55. .a.
  56. ...
  57. EOT
  58. .....
  59. .d.i.
  60. kmegk
  61. ..tu.
  62. EOT
  63.  
  64. samples.each do |field, dirs|
  65. s = Slide.new(field, dirs)
  66. s.incline_all
  67. puts "%s%s optimised => %s\n%s\n\n" % [field, dirs, s.dirs, s]
  68. end
  69.  
Success #stdin #stdout 0.01s 6116KB
stdin
Standard input is empty
stdout
...
.a.
...
UR optimised => UR
..a
...
...

.....
.d.i.
kmegk
..tu.
LRRLLUDRRLRLRRURRRRLLLRULDUDULDLLRDULURULUDLDLUDDL optimised => LDRULDRULD
.....
gk...
km...
dietu