[2016][ruby][11.0] generate next states
diff --git a/2016/ruby/day_11.rb b/2016/ruby/day_11.rb
index b12ee5a..bddda18 100644
--- a/2016/ruby/day_11.rb
+++ b/2016/ruby/day_11.rb
@@ -1,19 +1,45 @@
require 'delegate'
-class State
- attr_reader :floors, :elevator
-
- def initialize(input)
- @floors = input.lines.reverse.map.with_index {|line, index|
+State = Struct.new(:floors, :elevator) do
+ def self.from_s(input)
+ elevator = nil
+ floors = input.lines.reverse.map.with_index {|line, index|
_, e, *items = line.split(/\s+/)
- @elevator = index if e == ?E
+ elevator = index if e == ?E
Floor.new(items.reject {|item| item == ?. })
}
+ new(floors, elevator)
end
def ==(state)
elevator == state.elevator && floors.zip(state.floors).all? {|a,b| a == b }
end
+
+ def candidates
+ [-1, 1].flat_map {|delta|
+ next_floor = elevator + delta
+ next [] unless (0...floors.size).cover?(next_floor)
+
+ current_floor.map {|item| move(item, elevator, next_floor) }
+ }
+ end
+
+ private
+
+ def current_floor
+ floors[elevator]
+ end
+
+ def move(item, from, to)
+ from_floor = floors[from] - [item]
+ to_floor = floors[to] + [item]
+
+ floors = self.floors.clone
+ floors[from] = from_floor
+ floors[to] = to_floor
+
+ self.class.new(floors, to)
+ end
end
class Floor < SimpleDelegator
@@ -43,7 +69,7 @@ F1 E . HM . LM
INPUT
def setup
- @state = State.new(INPUT)
+ @state = State.from_s(INPUT)
end
def test_initialize
@@ -57,7 +83,22 @@ F1 E . HM . LM
end
def test_equality
- state = State.new(INPUT)
+ state = State.from_s(INPUT)
assert_equal @state, state
end
+
+ def test_candidates
+ candidates = @state.candidates
+ assert_equal 2, candidates.size
+
+ candidate = candidates[0]
+ assert_equal 1, candidate.elevator
+ assert_equal %W[ LM ], candidate.floors[0]
+ assert_equal %W[ HG HM ], candidate.floors[1]
+
+ candidate = candidates[1]
+ assert_equal 1, candidate.elevator
+ assert_equal %W[ HM ], candidate.floors[0]
+ assert_equal %W[ HG LM ], candidate.floors[1]
+ end
end