http://nabetani.sakura.ne.jp/hena/ord3ynode/
When A Graph is given a continuous instruction of "turn right/go forward/turn left/go back", it is a problem to output a column of passing nodes.
Ruby
module YshapedRoadTour
Graph = {"A"=>"DCB", "B"=>"CEA", "C"=>"FBA",
"D"=>"EFA", "E"=>"DBF", "F"=>"ECD"}
def self.solve(input)
input = input.each_char
result = ""
go = ->(s, e) {
result << e
idx = Graph[e].index(s)
case input.next
when "b"
go.(e, s)
when "r"
i = (idx - 1) % 3
when "l"
i = (idx + 1) % 3
end
go.(e, Graph[e][i])
}
go.("B", "A")
rescue StopIteration
result
end
end
if __FILE__ == $0
require 'minitest/autorun'
describe 'YshapedRoadTour' do
[
["b", "AB"],
["l", "AD"],
["r", "AC"],
["bbb", "ABAB"],
["rrr", "ACBA"],
["blll", "ABCAB"],
["llll", "ADEBA"],
["rbrl", "ACADE"],
["brrrr", "ABEDAB"],
["llrrr", "ADEFDE"],
["lrlll", "ADFEDF"],
["lrrrr", "ADFCAD"],
["rllll", "ACFDAC"],
["blrrrr", "ABCFEBC"],
["brllll", "ABEFCBE"],
["bbbrrlrl", "ABABEDFCB"],
["rbllrrrr", "ACABCFEBC"],
["lbrlrrblr", "ADABCFEFCA"],
["rlbrrrrbl", "ACFCADFCFD"],
["bllrlrbrrb", "ABCADEFEBCB"],
["rllrllllbb", "ACFDEBADEDE"],
["blblrlrrlbr", "ABCBEDFCABAC"],
["lrlrrrrrbrb", "ADFEBCFEBEDE"],
["rblllrlrrlrr", "ACABCADEFDABE"],
["rbrrlrblrllb", "ACADFEBEFDACA"],
["lrrrlrllrrllr", "ADFCABEFCADEBC"],
["rrlblllrrlrrb", "ACBEBADEFDABEB"],
["brbllrrbbrlrll", "ABEBADFCFCABEFC"],
["rrrbbrlbrlblrb", "ACBABACFCABADFD"],
["lllllllllllblrr", "ADEBADEBADEBEFDE"],
["llllllrllrlbrrr", "ADEBADEFCBADABED"]
].each do |input, expect|
it input do
assert_equal YshapedRoadTour.solve(input), expect
end
end
end
end
It's difficult to express a right turn or a left turn. Here, the graph is represented by Hash, but if it is {"A "=>" DCB "}
, it means that it is D, C, B clockwise around node A.
Input is converted to Enumerator with each_char
and extracted character by character with next
. When there is nothing to retrieve, an exception StopIteration
will occur, so I try to catch it with rescue
and return the result.
go. (S, e)
means going from s
to e
.
I'm using recursion here, but I think loops are better. But I somehow like recursion (laughs).
Is it like this with a loop? After all this is better (laughs).
module YshapedRoadTour
Graph = {"A"=>"DCB", "B"=>"CEA", "C"=>"FBA",
"D"=>"EFA", "E"=>"DBF", "F"=>"ECD"}
def self.solve(input)
input = input.each_char
result = ""
s, e = "B", "A"
loop do
result << e
idx = Graph[e].index(s)
case input.next
when "b"
s, e = e, s
when "r"
i = (idx - 1) % 3
s, e = e, Graph[e][i]
when "l"
i = (idx + 1) % 3
s, e = e, Graph[e][i]
end
end
result
end
end
Note that loop do ~ end
catches the exception StopIteration, so Enumerator # next can be written straightforwardly.
Recommended Posts